예제 #1
0
파일: r_numint.py 프로젝트: pyscf/pyscf
def _col_lda_vxc_mat(mol,
                     ao,
                     weight,
                     rho,
                     vxc,
                     mask,
                     shls_slice,
                     ao_loc,
                     hermi,
                     on_LL=True):
    '''Vxc matrix of collinear LDA'''
    # NOTE vxc in u/d representation
    aoa, aob = ao
    wv = weight * vxc
    if hermi:
        wv *= .5
    if on_LL:
        wva, wvb = wv
    else:  # for SS block
        # v_rho = (vxc_a + vxc_b) * .5
        # v_mz  = (vxc_a - vxc_b) * .5
        # For small components, M = \beta\Sigma leads to
        # (v_rho - sigma_z*v_mz) = [vxc_b, 0    ]
        #                          [0    , vxc_a]
        wvb, wva = wv
    mat = _dot_ao_ao(mol, aoa, _scale_ao(aoa, wva[0]), mask, shls_slice,
                     ao_loc)
    mat += _dot_ao_ao(mol, aob, _scale_ao(aob, wvb[0]), mask, shls_slice,
                      ao_loc)
    return mat
예제 #2
0
파일: r_numint.py 프로젝트: pyscf/pyscf
def _col_gga_vxc_mat(mol,
                     ao,
                     weight,
                     rho,
                     vxc,
                     mask,
                     shls_slice,
                     ao_loc,
                     hermi,
                     on_LL=True):
    '''Vxc matrix of collinear GGA'''
    # NOTE vxc in u/d representation
    aoa, aob = ao
    wv = weight * vxc
    if hermi:
        wv[:, 0] *= .5
    if on_LL:
        wva, wvb = wv
    else:  # for SS block
        wvb, wva = wv
    aow = None
    aow = _scale_ao(aoa[:4], wva[:4], out=aow)
    mat = _dot_ao_ao(mol, aoa[0], aow, mask, shls_slice, ao_loc)
    aow = _scale_ao(aob[:4], wvb[:4], out=aow)
    mat += _dot_ao_ao(mol, aob[0], aow, mask, shls_slice, ao_loc)
    if hermi != 1:
        aow = _scale_ao(aoa[1:4], wva[1:4].conj(), out=aow)
        mat += _dot_ao_ao(mol, aow, aoa[0], mask, shls_slice, ao_loc)
        aow = _scale_ao(aob[1:4], wvb[1:4].conj(), out=aow)
        mat += _dot_ao_ao(mol, aow, aob[0], mask, shls_slice, ao_loc)
    return mat
예제 #3
0
파일: numint2c.py 프로젝트: pyscf/pyscf
def _mcol_lda_vxc_mat(mol, ao, weight, rho, vxc, mask, shls_slice, ao_loc, hermi):
    '''Vxc matrix of multi-collinear LDA'''
    wv = weight * vxc
    if hermi:
        wv *= .5  # * .5 because of v+v.conj().T in r_vxc
    wr, wmx, wmy, wmz = wv

    # einsum('g,g,xgi,xgj->ij', vxc, weight, ao, ao)
    # + einsum('xy,g,g,xgi,ygj->ij', sx, vxc, weight, ao, ao)
    # + einsum('xy,g,g,xgi,ygj->ij', sy, vxc, weight, ao, ao)
    # + einsum('xy,g,g,xgi,ygj->ij', sz, vxc, weight, ao, ao)
    aow = None
    aow = _scale_ao(ao, wmx[0], out=aow)  # Mx
    tmpx = _dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    aow = _scale_ao(ao, wmy[0], out=aow)  # My
    tmpy = _dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    if hermi:
        # conj(mx+my*1j) == mx-my*1j, tmpx and tmpy should be real
        matba = (tmpx + tmpx.T) + (tmpy + tmpy.T) * 1j
        matab = np.zeros_like(matba)
    else:
        # conj(mx+my*1j) != mx-my*1j, tmpx and tmpy should be complex
        matba = tmpx + tmpy * 1j
        matab = tmpx - tmpy * 1j
    tmpx = tmpy = None
    aow = _scale_ao(ao, wr[0]+wmz[0], out=aow)  # Mz
    mataa = _dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    aow = _scale_ao(ao, wr[0]-wmz[0], out=aow)  # Mz
    matbb = _dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    mat = np.block([[mataa, matab], [matba, matbb]])
    return mat
예제 #4
0
파일: numint.py 프로젝트: ushnishray/pyscf
        def dot(ao1, ao2):
            ao1_re = numpy.asarray(ao1.real, order='C')
            ao1_im = numpy.asarray(ao1.imag, order='C')
            ao2_re = numpy.asarray(ao2.real, order='C')
            ao2_im = numpy.asarray(ao2.imag, order='C')

            mat_re  = _dot_ao_ao(cell, ao1_re, ao2_re, nao, ngrids, non0tab)
            mat_re += _dot_ao_ao(cell, ao1_im, ao2_im, nao, ngrids, non0tab)
            mat_im  = _dot_ao_ao(cell, ao1_re, ao2_im, nao, ngrids, non0tab)
            mat_im -= _dot_ao_ao(cell, ao1_im, ao2_re, nao, ngrids, non0tab)
            return mat_re + 1j*mat_im
예제 #5
0
파일: numint.py 프로젝트: gmwang18/pyscf
        def dot(ao1, ao2):
            ao1_re = numpy.asarray(ao1.real, order='C')
            ao1_im = numpy.asarray(ao1.imag, order='C')
            ao2_re = numpy.asarray(ao2.real, order='C')
            ao2_im = numpy.asarray(ao2.imag, order='C')

            mat_re = _dot_ao_ao(cell, ao1_re, ao2_re, nao, ngrids, non0tab)
            mat_re += _dot_ao_ao(cell, ao1_im, ao2_im, nao, ngrids, non0tab)
            mat_im = _dot_ao_ao(cell, ao1_re, ao2_im, nao, ngrids, non0tab)
            mat_im -= _dot_ao_ao(cell, ao1_im, ao2_re, nao, ngrids, non0tab)
            return mat_re + 1j * mat_im
예제 #6
0
파일: rks.py 프로젝트: chrinide/pyscf
def _d1d2_dot_(vmat, mol, ao1, ao2, mask, ao_loc, dR1_on_bra=True):
    shls_slice = (0, mol.nbas)
    if dR1_on_bra:  # (d/dR1 bra) * (d/dR2 ket)
        for d1 in range(3):
            for d2 in range(3):
                vmat[d1,d2] += numint._dot_ao_ao(mol, ao1[d1], ao2[d2], mask,
                                                 shls_slice, ao_loc)
    else:  # (d/dR2 bra) * (d/dR1 ket)
        for d1 in range(3):
            for d2 in range(3):
                vmat[d1,d2] += numint._dot_ao_ao(mol, ao1[d2], ao2[d1], mask,
                                                 shls_slice, ao_loc)
예제 #7
0
파일: rks.py 프로젝트: zwgsyntax/pyscf
def _d1d2_dot_(vmat, mol, ao1, ao2, mask, ao_loc, dR1_on_bra=True):
    shls_slice = (0, mol.nbas)
    if dR1_on_bra:  # (d/dR1 bra) * (d/dR2 ket)
        for d1 in range(3):
            for d2 in range(3):
                vmat[d1, d2] += numint._dot_ao_ao(mol, ao1[d1], ao2[d2], mask,
                                                  shls_slice, ao_loc)
    else:  # (d/dR2 bra) * (d/dR1 ket)
        for d1 in range(3):
            for d2 in range(3):
                vmat[d1, d2] += numint._dot_ao_ao(mol, ao1[d2], ao2[d1], mask,
                                                  shls_slice, ao_loc)
예제 #8
0
파일: rks.py 프로젝트: pulkin/pyscf
def _gga_sum_(vmat, mol, ao, giao, wv, mask, shls_slice, ao_loc):
    aow = numpy.einsum('pi,p->pi', giao[XX], wv[1])
    aow += numpy.einsum('pi,p->pi', giao[YX], wv[2])
    aow += numpy.einsum('pi,p->pi', giao[ZX], wv[3])
    vmat[0] += numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
    aow = numpy.einsum('pi,p->pi', giao[XY], wv[1])
    aow += numpy.einsum('pi,p->pi', giao[YY], wv[2])
    aow += numpy.einsum('pi,p->pi', giao[ZY], wv[3])
    vmat[1] += numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
    aow = numpy.einsum('pi,p->pi', giao[XZ], wv[1])
    aow += numpy.einsum('pi,p->pi', giao[YZ], wv[2])
    aow += numpy.einsum('pi,p->pi', giao[ZZ], wv[3])
    vmat[2] += numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
예제 #9
0
파일: rks.py 프로젝트: chrinide/pyscf
def _gga_sum_(vmat, mol, ao, giao, wv, mask, shls_slice, ao_loc):
    aow = numpy.einsum('pi,p->pi', giao[XX], wv[1])
    aow+= numpy.einsum('pi,p->pi', giao[YX], wv[2])
    aow+= numpy.einsum('pi,p->pi', giao[ZX], wv[3])
    vmat[0] += numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
    aow = numpy.einsum('pi,p->pi', giao[XY], wv[1])
    aow+= numpy.einsum('pi,p->pi', giao[YY], wv[2])
    aow+= numpy.einsum('pi,p->pi', giao[ZY], wv[3])
    vmat[1] += numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
    aow = numpy.einsum('pi,p->pi', giao[XZ], wv[1])
    aow+= numpy.einsum('pi,p->pi', giao[YZ], wv[2])
    aow+= numpy.einsum('pi,p->pi', giao[ZZ], wv[3])
    vmat[2] += numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
예제 #10
0
파일: r_numint.py 프로젝트: pyscf/pyscf
def _ncol_lda_vxc_mat(mol,
                      ao,
                      weight,
                      rho_tm,
                      vxc,
                      mask,
                      shls_slice,
                      ao_loc,
                      hermi,
                      on_LL=True):
    '''Vxc matrix of non-collinear LDA'''
    # NOTE vxc in u/d representation
    aoa, aob = ao
    r, mx, my, mz = rho_tm
    vxc = xc_deriv.ud2ts(vxc)
    vr, vs = vxc[:, 0]
    s = lib.norm(rho_tm[1:4], axis=0)

    wv = weight * vr
    with numpy.errstate(divide='ignore', invalid='ignore'):
        ws = vs * weight / s
    ws[s < 1e-20] = 0
    if not on_LL:
        # flip the sign for small components because
        # M = \beta\Sigma = [sigma,  0    ]
        #                   [0    , -sigma]
        ws *= -1

    # * .5 because of v+v.conj().T in r_vxc
    if hermi:
        wv *= .5
        ws *= .5

    # einsum('g,g,xgi,xgj->ij', vr, weight, ao, ao)
    # + einsum('xy,g,g,xgi,ygj->ij', sx, vs*m[0]/s, weight, ao, ao)
    # + einsum('xy,g,g,xgi,ygj->ij', sy, vs*m[1]/s, weight, ao, ao)
    # + einsum('xy,g,g,xgi,ygj->ij', sz, vs*m[2]/s, weight, ao, ao)
    aow = None
    aow = _scale_ao(aoa, ws * (mx + my * 1j), out=aow)
    mat = _dot_ao_ao(mol, aob, aow, mask, shls_slice, ao_loc)
    if hermi:
        mat = mat + mat.conj().T
    else:
        aow = _scale_ao(aob, ws * (mx - my * 1j), out=aow)  # Mx
        mat += _dot_ao_ao(mol, aoa, aow, mask, shls_slice, ao_loc)
    aow = _scale_ao(aoa, wv + ws * mz, out=aow)  # Mz
    mat += _dot_ao_ao(mol, aoa, aow, mask, shls_slice, ao_loc)
    aow = _scale_ao(aob, wv - ws * mz, out=aow)  # Mz
    mat += _dot_ao_ao(mol, aob, aow, mask, shls_slice, ao_loc)
    return mat
예제 #11
0
        def mgga_sum_(vmat, ao, wv, mask):
            aow = numint._scale_ao(ao[:4], wv[:4])
            tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
            aow = numint._scale_ao(ao[1], wv[5], aow)
            tmp += numint._dot_ao_ao(mol, ao[1], aow, mask, shls_slice, ao_loc)
            aow = numint._scale_ao(ao[2], wv[5], aow)
            tmp += numint._dot_ao_ao(mol, ao[2], aow, mask, shls_slice, ao_loc)
            aow = numint._scale_ao(ao[3], wv[5], aow)
            tmp += numint._dot_ao_ao(mol, ao[3], aow, mask, shls_slice, ao_loc)
            vmat[0] += tmp + tmp.T

            rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv[:4], mask, ao_loc)
            rks_grad._tau_grad_dot_(vmat[1:], mol, ao, wv[5] * 2, mask, ao_loc,
                                    True)
예제 #12
0
파일: r_numint.py 프로젝트: pyscf/pyscf
def _mcol_mgga_vxc_mat(mol,
                       ao,
                       weight,
                       rho,
                       vxc,
                       mask,
                       shls_slice,
                       ao_loc,
                       hermi,
                       on_LL=True):
    '''Vxc matrix of multi-collinear MGGA'''
    # NOTE vxc in t/m representation
    aoa, aob = ao
    wv = weight * vxc
    tau_idx = 4
    wv[:, tau_idx] *= .5  # *.5 for 1/2 in tau
    if hermi:
        wv[:, 0] *= .5
        wv[:, tau_idx] *= .5
    if not on_LL:
        # flip the sign for small components because
        # M = \beta\Sigma = [sigma,  0    ]
        #                   [0    , -sigma]
        wv[1:4] *= -1
    wr, wmx, wmy, wmz = wv

    aow = None
    aow = _scale_ao(aoa[:4], wmx[:4] + wmy[:4] * 1j, out=aow)
    mat = _dot_ao_ao(mol, aob[0], aow, mask, shls_slice, ao_loc)
    mat += _tau_dot(mol, aob, aoa, wmx[tau_idx] + wmy[tau_idx] * 1j, mask,
                    shls_slice, ao_loc)
    if hermi:
        assert vxc.dtype == numpy.double
        mat = mat + mat.conj().T
    else:
        aow = _scale_ao(aob[:4], wmx[:4] - wmy[:4] * 1j, out=aow)
        mat += _dot_ao_ao(mol, aoa[0], aow, mask, shls_slice, ao_loc)
        mat += _tau_dot(mol, aoa, aob, wmx[tau_idx] - wmy[tau_idx] * 1j, mask,
                        shls_slice, ao_loc)

        aow = _scale_ao(aob[1:4], (wmx[1:4] + wmy[1:4] * 1j).conj(), out=aow)
        mat += _dot_ao_ao(mol, aow, aoa[0], mask, shls_slice, ao_loc)
        aow = _scale_ao(aoa[1:4], (wmx[1:4] - wmy[1:4] * 1j).conj(), out=aow)
        mat += _dot_ao_ao(mol, aow, aob[0], mask, shls_slice, ao_loc)
        aow = _scale_ao(aoa[1:4], (wr[1:4] + wmz[1:4]).conj(), out=aow)  # Mz
        mat += _dot_ao_ao(mol, aow, aoa[0], mask, shls_slice, ao_loc)
        aow = _scale_ao(aob[1:4], (wr[1:4] - wmz[1:4]).conj(), out=aow)  # Mz
        mat += _dot_ao_ao(mol, aow, aob[0], mask, shls_slice, ao_loc)

    aow = _scale_ao(aoa, wr[:4] + wmz[:4], out=aow)  # Mz
    mat += _dot_ao_ao(mol, aoa[0], aow, mask, shls_slice, ao_loc)
    mat += _tau_dot(mol, aoa, aoa, wr[tau_idx] + wmz[tau_idx], mask,
                    shls_slice, ao_loc)
    aow = _scale_ao(aob, wr[:4] - wmz[:4], out=aow)  # Mz
    mat += _dot_ao_ao(mol, aob[0], aow, mask, shls_slice, ao_loc)
    mat += _tau_dot(mol, aob, aob, wr[tau_idx] - wmz[tau_idx], mask,
                    shls_slice, ao_loc)
    return mat
예제 #13
0
    def get_veff_nuc_epc(self, mol, dm, dm_last=None, vhf_last=None, hermi=1):
        '''Add EPC contribution to nuclear veff'''
        nao = mol.nao_nr()
        shls_slice = (0, mol.nbas)
        ao_loc = mol.ao_loc_nr()
        nnuc = 0
        excsum = 0
        vmat = numpy.zeros((nao, nao))

        grids = self.mf_elec.grids
        ni = self.mf_elec._numint

        aow = None
        for ao, mask, weight, coords in ni.block_loop(mol, grids, nao):
            aow = numpy.ndarray(ao.shape, order='F', buffer=aow)
            ao_elec = eval_ao(self.mol.elec, coords)
            if self.dm_elec.ndim > 2:
                rho_elec = eval_rho(self.mol.elec, ao_elec, self.dm_elec[0] + self.dm_elec[1])
            else:
                rho_elec = eval_rho(self.mol.elec, ao_elec, self.dm_elec)
            ao_nuc = eval_ao(mol, coords)
            rho_nuc = eval_rho(mol, ao_nuc, dm)
            exc, vxc = eval_xc_nuc(self.epc, rho_elec, rho_nuc)
            den = rho_nuc * weight
            nnuc += den.sum()
            excsum += numpy.dot(den, exc)
            # times 0.5 because vmat + vmat.T
            aow = _scale_ao(ao_nuc, 0.5 * weight * vxc, out=aow)
            vmat += _dot_ao_ao(mol, ao_nuc, aow, mask, shls_slice, ao_loc)
        logger.debug(self, 'The number of nuclei: %.5f', nnuc)
        vmat += vmat.conj().T
        # attach E_ep to vmat to retrieve later
        vmat = lib.tag_array(vmat, exc=excsum, ecoul=0, vj=0, vk=0)
        return vmat
예제 #14
0
    def get_veff_elec_epc(self, mol, dm, dm_last=None, vhf_last=None, hermi=1):
        '''Add EPC contribution to electronic veff'''
        nao = mol.nao_nr()
        shls_slice = (0, mol.nbas)
        ao_loc = mol.ao_loc_nr()
        vmat = numpy.zeros((nao, nao))

        grids = self.mf_elec.grids
        ni = self.mf_elec._numint

        aow = None
        for i in range(self.mol.nuc_num):
            ia = self.mol.nuc[i].atom_index
            if self.mol.atom_symbol(ia) == 'H':
                for ao, mask, weight, coords in ni.block_loop(mol, grids, nao):
                    aow = numpy.ndarray(ao.shape, order='F', buffer=aow)
                    ao_elec = eval_ao(mol, coords)
                    if dm.ndim > 2:
                        rho_elec = eval_rho(mol, ao_elec, dm[0] + dm[1])
                    else:
                        rho_elec = eval_rho(mol, ao_elec, dm)
                    ao_nuc = eval_ao(self.mol.nuc[i], coords)
                    rho_nuc = eval_rho(self.mol.nuc[i], ao_nuc, self.dm_nuc[i])
                    vxc_i = eval_xc_elec(self.epc, rho_elec, rho_nuc)
                    # times 0.5 because vmat + vmat.T
                    aow = _scale_ao(ao_elec, 0.5 * weight * vxc_i, out=aow)
                    vmat += _dot_ao_ao(mol, ao_elec, aow, mask, shls_slice, ao_loc)
        vmat += vmat.conj().T
        if dm.ndim > 2:
            veff = dft.uks.get_veff(self.mf_elec, mol, dm, dm_last, vhf_last, hermi)
        else:
            veff = dft.rks.get_veff(self.mf_elec, mol, dm, dm_last, vhf_last, hermi)
        vxc = lib.tag_array(veff + vmat, ecoul=veff.ecoul, exc=veff.exc, vj=veff.vj, vk=veff.vk)
        return vxc
예제 #15
0
파일: tdrks.py 프로젝트: zwang123/pyscf
 def gga_sum_(vmat, ao, wv, mask):
     aow = numpy.einsum('pi,p->pi', ao[0], wv[0])
     aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
     tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice,
                             ao_loc)
     vmat[0] += tmp + tmp.T
     rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)
예제 #16
0
파일: r_numint.py 프로젝트: wmizukami/pyscf
def _vxc2x2_to_mat(mol, ao, weight, rho, vrho, non0tab, shls_slice, ao_loc):
    aoa, aob = ao
    r, m = rho
    vr, vm = vrho.T
    aow = numpy.empty_like(aoa)
    #    aow = numpy.einsum('pi,p->pi', aoa, weight*vr, out=aow)
    #    mat = _dot_ao_ao(mol, aoa, aow, non0tab, shls_slice, ao_loc)
    #    aow = numpy.einsum('pi,p->pi', aob, weight*vr, out=aow)
    #    mat+= _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
    #
    #    s = lib.norm(m, axis=0)
    #    ws = vm * weight / (s+1e-300)
    #    aow = numpy.einsum('pi,p->pi', aoa, ws*m[0], out=aow)  # Mx
    #    tmp = _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
    #    mat+= tmp + tmp.T.conj()
    #    aow = numpy.einsum('pi,p->pi', aoa, ws*m[1], out=aow)  # My
    #    tmp = _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
    #    mat+= (tmp - tmp.T.conj()) * 1j
    #    aow = numpy.einsum('pi,p->pi', aoa, ws*m[2], out=aow)  # Mz
    #    mat+= _dot_ao_ao(mol, aoa, aow, non0tab, shls_slice, ao_loc)
    #    aow = numpy.einsum('pi,p->pi', aob, ws*m[2], out=aow)
    #    mat-= _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)

    s = lib.norm(m, axis=0)
    idx = s < 1e-20
    with numpy.errstate(divide='ignore', invalid='ignore'):
        ws = vm * weight / s
    ws[idx] = 0

    aow = numpy.einsum('pi,p->pi', aoa, ws * m[0], out=aow)  # Mx
    tmp = _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
    mat = tmp + tmp.T.conj()
    aow = numpy.einsum('pi,p->pi', aoa, ws * m[1], out=aow)  # My
    tmp = _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
    mat += (tmp - tmp.T.conj()) * 1j
    aow = numpy.einsum('pi,p->pi', aoa, weight * vr, out=aow)
    aow += numpy.einsum('pi,p->pi', aoa, ws * m[2])  # Mz
    mat += _dot_ao_ao(mol, aoa, aow, non0tab, shls_slice, ao_loc)
    aow = numpy.einsum('pi,p->pi', aob, weight * vr, out=aow)
    aow -= numpy.einsum('pi,p->pi', aob, ws * m[2])  # Mz
    mat += _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
    return mat
예제 #17
0
파일: r_numint.py 프로젝트: pyscf/pyscf
def _mcol_lda_vxc_mat(mol,
                      ao,
                      weight,
                      rho,
                      vxc,
                      mask,
                      shls_slice,
                      ao_loc,
                      hermi,
                      on_LL=True):
    '''Vxc matrix of multi-collinear LDA'''
    # NOTE vxc in t/m representation
    aoa, aob = ao
    wv = weight * vxc
    if hermi:
        wv *= .5  # * .5 because of v+v.conj().T in r_vxc
    if not on_LL:
        # flip the sign for small components because
        # M = \beta\Sigma = [sigma,  0    ]
        #                   [0    , -sigma]
        wv[1:4] *= -1
    wr, wmx, wmy, wmz = wv

    # einsum('g,g,xgi,xgj->ij', vxc, weight, ao, ao)
    # + einsum('xy,g,g,xgi,ygj->ij', sx, vxc, weight, ao, ao)
    # + einsum('xy,g,g,xgi,ygj->ij', sy, vxc, weight, ao, ao)
    # + einsum('xy,g,g,xgi,ygj->ij', sz, vxc, weight, ao, ao)
    aow = None
    aow = _scale_ao(aoa, wmx[0] + wmy[0] * 1j, out=aow)
    mat = _dot_ao_ao(mol, aob, aow, mask, shls_slice, ao_loc)
    if hermi:
        assert vxc.dtype == numpy.double
        mat = mat + mat.conj().T
    else:
        aow = _scale_ao(aob, wmx[0] - wmy[0] * 1j, out=aow)
        mat += _dot_ao_ao(mol, aoa, aow, mask, shls_slice, ao_loc)
    aow = _scale_ao(aoa, wr[0] + wmz[0], out=aow)  # Mz
    mat += _dot_ao_ao(mol, aoa, aow, mask, shls_slice, ao_loc)
    aow = _scale_ao(aob, wr[0] - wmz[0], out=aow)  # Mz
    mat += _dot_ao_ao(mol, aob, aow, mask, shls_slice, ao_loc)
    return mat
예제 #18
0
파일: uks.py 프로젝트: chrinide/pyscf
def _cross3x3_(out, mol, ao1, ao2, mask, shls_slice, ao_loc):
    out[0] += numint._dot_ao_ao(mol, ao1[1], ao2[2], mask, shls_slice, ao_loc)
    out[0] -= numint._dot_ao_ao(mol, ao1[2], ao2[1], mask, shls_slice, ao_loc)
    out[1] += numint._dot_ao_ao(mol, ao1[2], ao2[0], mask, shls_slice, ao_loc)
    out[1] -= numint._dot_ao_ao(mol, ao1[0], ao2[2], mask, shls_slice, ao_loc)
    out[2] += numint._dot_ao_ao(mol, ao1[0], ao2[1], mask, shls_slice, ao_loc)
    out[2] -= numint._dot_ao_ao(mol, ao1[1], ao2[0], mask, shls_slice, ao_loc)
    return out
예제 #19
0
파일: uks.py 프로젝트: wmizukami/pyscf
def _cross3x3_(out, mol, ao1, ao2, mask, shls_slice, ao_loc):
    out[0] += numint._dot_ao_ao(mol, ao1[1], ao2[2], mask, shls_slice, ao_loc)
    out[0] -= numint._dot_ao_ao(mol, ao1[2], ao2[1], mask, shls_slice, ao_loc)
    out[1] += numint._dot_ao_ao(mol, ao1[2], ao2[0], mask, shls_slice, ao_loc)
    out[1] -= numint._dot_ao_ao(mol, ao1[0], ao2[2], mask, shls_slice, ao_loc)
    out[2] += numint._dot_ao_ao(mol, ao1[0], ao2[1], mask, shls_slice, ao_loc)
    out[2] -= numint._dot_ao_ao(mol, ao1[1], ao2[0], mask, shls_slice, ao_loc)
    return out
예제 #20
0
파일: r_numint.py 프로젝트: chrinide/pyscf
def _vxc2x2_to_mat(mol, ao, weight, rho, vrho, non0tab, shls_slice, ao_loc):
    aoa, aob = ao
    r, m = rho
    vr, vm = vrho.T
    aow = numpy.empty_like(aoa)
#    aow = numpy.einsum('pi,p->pi', aoa, weight*vr, out=aow)
#    mat = _dot_ao_ao(mol, aoa, aow, non0tab, shls_slice, ao_loc)
#    aow = numpy.einsum('pi,p->pi', aob, weight*vr, out=aow)
#    mat+= _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
#
#    s = lib.norm(m, axis=0)
#    ws = vm * weight / (s+1e-300)
#    aow = numpy.einsum('pi,p->pi', aoa, ws*m[0], out=aow)  # Mx
#    tmp = _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
#    mat+= tmp + tmp.T.conj()
#    aow = numpy.einsum('pi,p->pi', aoa, ws*m[1], out=aow)  # My
#    tmp = _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
#    mat+= (tmp - tmp.T.conj()) * 1j
#    aow = numpy.einsum('pi,p->pi', aoa, ws*m[2], out=aow)  # Mz
#    mat+= _dot_ao_ao(mol, aoa, aow, non0tab, shls_slice, ao_loc)
#    aow = numpy.einsum('pi,p->pi', aob, ws*m[2], out=aow)
#    mat-= _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)

    s = lib.norm(m, axis=0)
    ws = vm * weight / (s+1e-300)
    aow = numpy.einsum('pi,p->pi', aoa, ws*m[0], out=aow)  # Mx
    tmp = _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
    mat = tmp + tmp.T.conj()
    aow = numpy.einsum('pi,p->pi', aoa, ws*m[1], out=aow)  # My
    tmp = _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
    mat+= (tmp - tmp.T.conj()) * 1j
    aow = numpy.einsum('pi,p->pi', aoa, weight*vr, out=aow)
    aow+= numpy.einsum('pi,p->pi', aoa, ws*m[2])  # Mz
    mat+= _dot_ao_ao(mol, aoa, aow, non0tab, shls_slice, ao_loc)
    aow = numpy.einsum('pi,p->pi', aob, weight*vr, out=aow)
    aow-= numpy.einsum('pi,p->pi', aob, ws*m[2])  # Mz
    mat+= _dot_ao_ao(mol, aob, aow, non0tab, shls_slice, ao_loc)
    return mat
예제 #21
0
파일: numint2c.py 프로젝트: pyscf/pyscf
def _ncol_lda_vxc_mat(mol, ao, weight, rho, vxc, mask, shls_slice, ao_loc, hermi):
    '''Vxc matrix of non-collinear LDA'''
    # NOTE vxc in u/d representation
    r, mx, my, mz = rho
    vxc = xc_deriv.ud2ts(vxc)
    vr, vs = vxc[:,0]
    s = lib.norm(rho[1:4], axis=0)

    wv = weight * vr
    with np.errstate(divide='ignore',invalid='ignore'):
        ws = vs * weight / s
    ws[s < 1e-20] = 0

    # * .5 because of v+v.conj().T in r_vxc
    if hermi:
        wv *= .5
        ws *= .5
    aow = None
    aow = _scale_ao(ao, ws*mx, out=aow)  # Mx
    tmpx = _dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    aow = _scale_ao(ao, ws*my, out=aow)  # My
    tmpy = _dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    if hermi:
        # conj(mx+my*1j) == mx-my*1j, tmpx and tmpy should be real
        matba = (tmpx + tmpx.T) + (tmpy + tmpy.T) * 1j
        matab = np.zeros_like(matba)
    else:
        # conj(mx+my*1j) != mx-my*1j, tmpx and tmpy should be complex
        matba = tmpx + tmpy * 1j
        matab = tmpx - tmpy * 1j
    tmpx = tmpy = None
    aow = _scale_ao(ao, wv+ws*mz, out=aow)  # Mz
    mataa = _dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    aow = _scale_ao(ao, wv-ws*mz, out=aow)  # Mz
    matbb = _dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    mat = np.block([[mataa, matab], [matba, matbb]])
    return mat
예제 #22
0
파일: rks.py 프로젝트: chrinide/pyscf
def _d1_dot_(vmat, mol, ao1, ao2, mask, ao_loc, dR1_on_bra=True):
    shls_slice = (0, mol.nbas)
    if dR1_on_bra:
        vmat[0] += numint._dot_ao_ao(mol, ao1[0], ao2, mask, shls_slice, ao_loc)
        vmat[1] += numint._dot_ao_ao(mol, ao1[1], ao2, mask, shls_slice, ao_loc)
        vmat[2] += numint._dot_ao_ao(mol, ao1[2], ao2, mask, shls_slice, ao_loc)
    else:
        vmat[0] += numint._dot_ao_ao(mol, ao1, ao2[0], mask, shls_slice, ao_loc)
        vmat[1] += numint._dot_ao_ao(mol, ao1, ao2[1], mask, shls_slice, ao_loc)
        vmat[2] += numint._dot_ao_ao(mol, ao1, ao2[2], mask, shls_slice, ao_loc)
예제 #23
0
def _d1_dot_(vmat, mol, ao1, ao2, mask, ao_loc, dR1_on_bra=True):
    shls_slice = (0, mol.nbas)
    if dR1_on_bra:
        vmat[0] += numint._dot_ao_ao(mol, ao1[0], ao2, mask, shls_slice, ao_loc)
        vmat[1] += numint._dot_ao_ao(mol, ao1[1], ao2, mask, shls_slice, ao_loc)
        vmat[2] += numint._dot_ao_ao(mol, ao1[2], ao2, mask, shls_slice, ao_loc)
    else:
        vmat[0] += numint._dot_ao_ao(mol, ao1, ao2[0], mask, shls_slice, ao_loc)
        vmat[1] += numint._dot_ao_ao(mol, ao1, ao2[1], mask, shls_slice, ao_loc)
        vmat[2] += numint._dot_ao_ao(mol, ao1, ao2[2], mask, shls_slice, ao_loc)
예제 #24
0
def _dot_ao_mo(mol,
               ao,
               mo,
               non0tab=None,
               shls_slice=None,
               ao_loc=None,
               hermi=0):
    if hermi:
        #print ("_dot_ao_mo punting to numint._dot_ao_ao")
        return numint._dot_ao_ao(mol,
                                 ao,
                                 mo,
                                 non0tab=non0tab,
                                 shls_slice=shls_slice,
                                 ao_loc=ao_loc,
                                 hermi=hermi)
    ngrids, nao = ao.shape
    nmo = mo.shape[-1]

    if nao < SWITCH_SIZE:
        #print ("_dot_ao_mo punting to lib.dot")
        return lib.dot(ao.T.conj(), mo)

    #print ("_dot_ao_mo doing my own thing")

    if not ao.flags.f_contiguous:
        ao = lib.transpose(ao)
    if not mo.flags.f_contiguous:
        mo = lib.transpose(mo)
    if ao.dtype == mo.dtype == np.double:
        fn = libpdft.VOTdot_ao_mo
    else:
        raise NotImplementedError("Complex-orbital PDFT")

    if non0tab is None or shls_slice is None or ao_loc is None:
        pnon0tab = pshls_slice = pao_loc = lib.c_null_ptr()
    else:
        pnon0tab = non0tab.ctypes.data_as(ctypes.c_void_p)
        pshls_slice = (ctypes.c_int * 2)(*shls_slice)
        pao_loc = ao_loc.ctypes.data_as(ctypes.c_void_p)

    vv = np.empty((nao, nmo), dtype=ao.dtype)
    fn(vv.ctypes.data_as(ctypes.c_void_p), ao.ctypes.data_as(ctypes.c_void_p),
       mo.ctypes.data_as(ctypes.c_void_p),
       ctypes.c_int(nao), ctypes.c_int(nmo), ctypes.c_int(ngrids),
       ctypes.c_int(mol.nbas), pnon0tab, pshls_slice, pao_loc)
    return vv
예제 #25
0
파일: numint2c.py 프로젝트: pyscf/pyscf
def _mcol_mgga_vxc_mat(mol, ao, weight, rho, vxc, mask, shls_slice, ao_loc, hermi):
    '''Vxc matrix of multi-collinear MGGA'''
    wv = weight * vxc
    tau_idx = 4
    wv[:,tau_idx] *= .5  # *.5 for 1/2 in tau
    if hermi:
        wv[:,0] *= .5  # * .5 because of v+v.conj().T in r_vxc
        wv[:,tau_idx] *= .5
    wr, wmx, wmy, wmz = wv

    aow = None
    aow = _scale_ao(ao[:4], wr[:4]+wmz[:4], out=aow)  # Mz
    mataa = _dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
    mataa += _tau_dot(mol, ao, ao, wr[tau_idx]+wmz[tau_idx], mask, shls_slice, ao_loc)
    aow = _scale_ao(ao[:4], wr[:4]-wmz[:4], out=aow)  # Mz
    matbb = _dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
    matbb += _tau_dot(mol, ao, ao, wr[tau_idx]-wmz[tau_idx], mask, shls_slice, ao_loc)

    aow = _scale_ao(ao[:4], wmx[:4], out=aow)  # Mx
    tmpx = _dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
    tmpx += _tau_dot(mol, ao, ao, wmx[tau_idx], mask, shls_slice, ao_loc)
    aow = _scale_ao(ao[:4], wmy[:4], out=aow)  # My
    tmpy = _dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
    tmpy += _tau_dot(mol, ao, ao, wmy[tau_idx], mask, shls_slice, ao_loc)
    if hermi:
        assert vxc.dtype == np.double
        # conj(mx+my*1j) == mx-my*1j, tmpx and tmpy should be real
        matba = (tmpx + tmpx.T) + (tmpy + tmpy.T) * 1j
        matab = np.zeros_like(matba)
    else:
        # conj(mx+my*1j) != mx-my*1j, tmpx and tmpy should be complex
        aow = _scale_ao(ao[1:4], wmx[1:4].conj(), out=aow)  # Mx
        tmpx += _dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)
        aow = _scale_ao(ao[1:4], wmy[1:4].conj(), out=aow)  # My
        tmpy += _dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)
        matba = tmpx + tmpy * 1j
        matab = tmpx - tmpy * 1j
        aow = _scale_ao(ao[1:4], (wr[1:4]+wmz[1:4]).conj(), out=aow)  # Mz
        mataa += _dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)
        aow = _scale_ao(ao[1:4], (wr[1:4]-wmz[1:4]).conj(), out=aow)  # Mz
        matbb += _dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)

    mat = np.block([[mataa, matab], [matba, matbb]])
    return mat
예제 #26
0
파일: rks.py 프로젝트: chrinide/pyscf
def get_vxc_giao(ni, mol, grids, xc_code, dms, max_memory=2000, verbose=None):
    xctype = ni._xc_type(xc_code)
    make_rho, nset, nao = ni._gen_rho_evaluator(mol, dms, hermi=1)
    ngrids = len(grids.weights)
    BLKSIZE = numint.BLKSIZE
    blksize = min(int(max_memory/12*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    vmat = numpy.zeros((3,nao,nao))
    if xctype == 'LDA':
        buf = numpy.empty((4,blksize,nao))
        ao_deriv = 0
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize, buf=buf):
            rho = make_rho(0, ao, mask, 'LDA')
            vxc = ni.eval_xc(xc_code, rho, 0, deriv=1)[1]
            vrho = vxc[0]
            aow = numpy.einsum('pi,p->pi', ao, weight*vrho)
            giao = mol.eval_gto('GTOval_ig', coords, comp=3,
                                non0tab=mask, out=buf[1:])
            vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], mask, shls_slice, ao_loc)
            vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], mask, shls_slice, ao_loc)
            vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], mask, shls_slice, ao_loc)
            rho = vxc = vrho = aow = None
    elif xctype == 'GGA':
        buf = numpy.empty((10,blksize,nao))
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize, buf=buf):
            rho = make_rho(0, ao, mask, 'GGA')
            vxc = ni.eval_xc(xc_code, rho, 0, deriv=1)[1]
            vrho, vsigma = vxc[:2]
            wv = numpy.empty_like(rho)
            wv[0]  = weight * vrho
            wv[1:] = rho[1:] * (weight * vsigma * 2)

            aow = numpy.einsum('npi,np->pi', ao[:4], wv)
            giao = mol.eval_gto('GTOval_ig', coords, 3, non0tab=mask, out=buf[4:])
            vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], mask, shls_slice, ao_loc)
            vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], mask, shls_slice, ao_loc)
            vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], mask, shls_slice, ao_loc)

            giao = mol.eval_gto('GTOval_ipig', coords, 9, non0tab=mask, out=buf[1:])
            _gga_sum_(vmat, mol, ao, giao, wv, mask, shls_slice, ao_loc)
            rho = vxc = vrho = vsigma = wv = aow = None
    elif xctype == 'MGGA':
        raise NotImplementedError('meta-GGA')

    return vmat - vmat.transpose(0,2,1)
예제 #27
0
def get_vxc_giao(ni, mol, grids, xc_code, dms, max_memory=2000, verbose=None):
    xctype = ni._xc_type(xc_code)
    make_rho, nset, nao = ni._gen_rho_evaluator(mol, dms, hermi=1)
    ngrids = len(grids.weights)
    BLKSIZE = numint.BLKSIZE
    blksize = min(int(max_memory/12*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    vmat = numpy.zeros((3,nao,nao))
    if xctype == 'LDA':
        buf = numpy.empty((4,blksize,nao))
        ao_deriv = 0
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize, buf=buf):
            rho = make_rho(0, ao, mask, 'LDA')
            vxc = ni.eval_xc(xc_code, rho, 0, deriv=1)[1]
            vrho = vxc[0]
            aow = numpy.einsum('pi,p->pi', ao, weight*vrho)
            giao = mol.eval_gto('GTOval_ig', coords, comp=3,
                                non0tab=mask, out=buf[1:])
            vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], mask, shls_slice, ao_loc)
            vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], mask, shls_slice, ao_loc)
            vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], mask, shls_slice, ao_loc)
            rho = vxc = vrho = aow = None
    elif xctype == 'GGA':
        buf = numpy.empty((10,blksize,nao))
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize, buf=buf):
            rho = make_rho(0, ao, mask, 'GGA')
            vxc = ni.eval_xc(xc_code, rho, 0, deriv=1)[1]
            vrho, vsigma = vxc[:2]
            wv = numpy.empty_like(rho)
            wv[0]  = weight * vrho
            wv[1:] = rho[1:] * (weight * vsigma * 2)

            aow = numpy.einsum('npi,np->pi', ao[:4], wv)
            giao = mol.eval_gto('GTOval_ig', coords, 3, non0tab=mask, out=buf[4:])
            vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], mask, shls_slice, ao_loc)
            vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], mask, shls_slice, ao_loc)
            vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], mask, shls_slice, ao_loc)

            giao = mol.eval_gto('GTOval_ipig', coords, 9, non0tab=mask, out=buf[1:])
            _gga_sum_(vmat, mol, ao, giao, wv, mask, shls_slice, ao_loc)
            rho = vxc = vrho = vsigma = wv = aow = None
    elif xctype == 'MGGA':
        raise NotImplementedError('meta-GGA')

    return vmat - vmat.transpose(0,2,1)
예제 #28
0
파일: rks_grad.py 프로젝트: pulkin/pyscf
def _gga_grad_sum(mol, ao, wv, mask, shls_slice, ao_loc):
    ngrid, nao = ao[0].shape
    vmat = numpy.empty((3, nao, nao))
    aow = numpy.einsum('npi,np->pi', ao[:4], wv)
    vmat[0] = numint._dot_ao_ao(mol, ao[1], aow, mask, shls_slice, ao_loc)
    vmat[1] = numint._dot_ao_ao(mol, ao[2], aow, mask, shls_slice, ao_loc)
    vmat[2] = numint._dot_ao_ao(mol, ao[3], aow, mask, shls_slice, ao_loc)

    # XX, XY, XZ = 4, 5, 6
    # YX, YY, YZ = 5, 7, 8
    # ZX, ZY, ZZ = 6, 8, 9
    aow = numpy.einsum('pi,p->pi', ao[4], wv[1])
    aow += numpy.einsum('pi,p->pi', ao[5], wv[2])
    aow += numpy.einsum('pi,p->pi', ao[6], wv[3])
    vmat[0] += numint._dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)
    aow = numpy.einsum('pi,p->pi', ao[5], wv[1])
    aow += numpy.einsum('pi,p->pi', ao[7], wv[2])
    aow += numpy.einsum('pi,p->pi', ao[8], wv[3])
    vmat[1] += numint._dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)
    aow = numpy.einsum('pi,p->pi', ao[6], wv[1])
    aow += numpy.einsum('pi,p->pi', ao[8], wv[2])
    aow += numpy.einsum('pi,p->pi', ao[9], wv[3])
    vmat[2] += numint._dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)
    return vmat
예제 #29
0
파일: rks_grad.py 프로젝트: berquist/pyscf
def _gga_grad_sum(mol, ao, wv, mask):
    ngrid, nao = ao[0].shape
    vmat = numpy.empty((3,nao,nao))
    aow = numpy.einsum('npi,np->pi', ao[:4], wv)
    vmat[0] = numint._dot_ao_ao(mol, ao[1], aow, nao, ngrid, mask)
    vmat[1] = numint._dot_ao_ao(mol, ao[2], aow, nao, ngrid, mask)
    vmat[2] = numint._dot_ao_ao(mol, ao[3], aow, nao, ngrid, mask)

    # XX, XY, XZ = 4, 5, 6
    # YX, YY, YZ = 5, 7, 8
    # ZX, ZY, ZZ = 6, 8, 9
    aow = numpy.einsum('pi,p->pi', ao[4], wv[1])
    aow+= numpy.einsum('pi,p->pi', ao[5], wv[2])
    aow+= numpy.einsum('pi,p->pi', ao[6], wv[3])
    vmat[0] += numint._dot_ao_ao(mol, aow, ao[0], nao, ngrid, mask)
    aow = numpy.einsum('pi,p->pi', ao[5], wv[1])
    aow+= numpy.einsum('pi,p->pi', ao[7], wv[2])
    aow+= numpy.einsum('pi,p->pi', ao[8], wv[3])
    vmat[1] += numint._dot_ao_ao(mol, aow, ao[0], nao, ngrid, mask)
    aow = numpy.einsum('pi,p->pi', ao[6], wv[1])
    aow+= numpy.einsum('pi,p->pi', ao[8], wv[2])
    aow+= numpy.einsum('pi,p->pi', ao[9], wv[3])
    vmat[2] += numint._dot_ao_ao(mol, aow, ao[0], nao, ngrid, mask)
    return vmat
예제 #30
0
파일: tduks.py 프로젝트: tmash/pyscf
def _contract_xc_kernel(td_grad,
                        xc_code,
                        dmvo,
                        dmoo=None,
                        with_vxc=True,
                        with_kxc=True,
                        max_memory=2000):
    mol = td_grad.mol
    mf = td_grad.base._scf
    grids = mf.grids

    ni = mf._numint
    xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao = mo_coeff[0].shape[0]
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = [
        (dmvo[0] + dmvo[0].T) * .5,  # because K_{ia,jb} == K_{ia,jb}
        (dmvo[1] + dmvo[1].T) * .5
    ]

    f1vo = numpy.zeros((2, 4, nao, nao))
    deriv = 2
    if dmoo is not None:
        f1oo = numpy.zeros((2, 4, nao, nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((2, 4, nao, nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((2, 4, nao, nao))
        deriv = 3
    else:
        k1ao = None

    if xctype == 'LDA':
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao[0], mo_coeff[0], mo_occ[0], mask,
                                'LDA'),
                   ni.eval_rho2(mol, ao[0], mo_coeff[1], mo_occ[1], mask,
                                'LDA'))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            u_u, u_d, d_d = fxc[0].T * weight
            rho1a = ni.eval_rho(mol, ao[0], dmvo[0], mask, 'LDA')
            rho1b = ni.eval_rho(mol, ao[0], dmvo[1], mask, 'LDA')
            aow = (numpy.einsum('pi,p,p->pi', ao[0], u_u, rho1a) +
                   numpy.einsum('pi,p,p->pi', ao[0], u_d, rho1b),
                   numpy.einsum('pi,p,p->pi', ao[0], u_d, rho1a) +
                   numpy.einsum('pi,p,p->pi', ao[0], d_d, rho1b))
            for k in range(4):
                f1vo[0, k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask,
                                                shls_slice, ao_loc)
                f1vo[1, k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask,
                                                shls_slice, ao_loc)
            if dmoo is not None:
                rho2a = ni.eval_rho(mol, ao[0], dmoo[0], mask, 'LDA')
                rho2b = ni.eval_rho(mol, ao[0], dmoo[1], mask, 'LDA')
                aow = (numpy.einsum('pi,p,p->pi', ao[0], u_u, rho2a) +
                       numpy.einsum('pi,p,p->pi', ao[0], u_d, rho2b),
                       numpy.einsum('pi,p,p->pi', ao[0], u_d, rho2a) +
                       numpy.einsum('pi,p,p->pi', ao[0], d_d, rho2b))
                for k in range(4):
                    f1oo[0, k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask,
                                                    shls_slice, ao_loc)
                    f1oo[1, k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask,
                                                    shls_slice, ao_loc)
            if with_vxc:
                vrho = vxc[0].T * weight
                aow = (numpy.einsum('pi,p->pi', ao[0], vrho[0]),
                       numpy.einsum('pi,p->pi', ao[0], vrho[1]))
                for k in range(4):
                    v1ao[0, k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask,
                                                    shls_slice, ao_loc)
                    v1ao[1, k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask,
                                                    shls_slice, ao_loc)
            if with_kxc:
                u_u_u, u_u_d, u_d_d, d_d_d = kxc[0].T * weight
                aow = (
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_u_u, rho1a, rho1a) +
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_u_d, rho1a, rho1b) *
                    2 +
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_d_d, rho1b, rho1b),
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_u_d, rho1a, rho1a) +
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_d_d, rho1a, rho1b) *
                    2 +
                    numpy.einsum('pi,p,p,p->pi', ao[0], d_d_d, rho1b, rho1b))
                for k in range(4):
                    k1ao[0, k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask,
                                                    shls_slice, ao_loc)
                    k1ao[1, k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask,
                                                    shls_slice, ao_loc)
            vxc = fxc = kxc = aow = rho = rho1 = rho2 = None

    elif xctype == 'GGA':

        def gga_sum_(vmat, ao, wv, mask):
            aow = numpy.einsum('pi,p->pi', ao[0], wv[0])
            aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
            tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
            vmat[0] += tmp + tmp.T
            rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)

        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao, mo_coeff[0], mo_occ[0], mask, 'GGA'),
                   ni.eval_rho2(mol, ao, mo_coeff[1], mo_occ[1], mask, 'GGA'))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            rho1 = (ni.eval_rho(mol, ao, dmvo[0], mask, 'GGA'),
                    ni.eval_rho(mol, ao, dmvo[1], mask, 'GGA'))
            wv = numint._uks_gga_wv1(rho, rho1, vxc, fxc, weight)
            gga_sum_(f1vo[0], ao, wv[0], mask)
            gga_sum_(f1vo[1], ao, wv[1], mask)

            if dmoo is not None:
                rho2 = (ni.eval_rho(mol, ao, dmoo[0], mask, 'GGA'),
                        ni.eval_rho(mol, ao, dmoo[1], mask, 'GGA'))
                wv = numint._uks_gga_wv1(rho, rho2, vxc, fxc, weight)
                gga_sum_(f1oo[0], ao, wv[0], mask)
                gga_sum_(f1oo[1], ao, wv[1], mask)
            if with_vxc:
                wv = numint._uks_gga_wv0(rho, vxc, weight)
                gga_sum_(v1ao[0], ao, wv[0], mask)
                gga_sum_(v1ao[1], ao, wv[1], mask)
            if with_kxc:
                wv = numint._uks_gga_wv2(rho, rho1, fxc, kxc, weight)
                gga_sum_(k1ao[0], ao, wv[0], mask)
                gga_sum_(k1ao[1], ao, wv[1], mask)
            vxc = fxc = kxc = rho = rho1 = None

    else:
        raise NotImplementedError('meta-GGA')

    f1vo[:, 1:] *= -1
    if f1oo is not None: f1oo[:, 1:] *= -1
    if v1ao is not None: v1ao[:, 1:] *= -1
    if k1ao is not None: k1ao[:, 1:] *= -1
    return f1vo, f1oo, v1ao, k1ao
예제 #31
0
파일: rks_grad.py 프로젝트: pulkin/pyscf
def _contract_xc_kernel(td_grad,
                        xc_code,
                        xai,
                        oovv=None,
                        with_vxc=True,
                        with_kxc=True,
                        singlet=True,
                        max_memory=2000):
    mol = td_grad.mol
    mf = td_grad._scf
    grids = mf.grids

    ni = mf._numint
    xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_energy = mf.mo_energy
    mo_occ = mf.mo_occ
    nao, nmo = mo_coeff.shape
    nocc = (mo_occ > 0).sum()
    orbv = mo_coeff[:, nocc:]
    orbo = mo_coeff[:, :nocc]
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = (xai + xai.T) * .5  # because K_{ai,bj} == K_{ai,bj}

    f1vo = numpy.zeros((4, nao, nao))
    deriv = 2
    if oovv is not None:
        f1oo = numpy.zeros((4, nao, nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((4, nao, nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((4, nao, nao))
        deriv = 3
    else:
        k1ao = None

    if xctype == 'LDA':
        ao_deriv = 1
        if singlet:
            for ao, mask, weight, coords \
                    in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
                rho = ni.eval_rho2(mol, ao[0], mo_coeff, mo_occ, mask, 'LDA')
                vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 0, deriv=deriv)[1:]

                wfxc = fxc[0] * weight * 2  # *2 for alpha+beta
                rho1 = ni.eval_rho(mol, ao[0], dmvo, mask, 'LDA')
                aow = numpy.einsum('pi,p->pi', ao[0], wfxc * rho1)
                for k in range(4):
                    f1vo[k] += numint._dot_ao_ao(mol, ao[k], aow, mask,
                                                 shls_slice, ao_loc)
                if oovv is not None:
                    rho2 = ni.eval_rho(mol, ao[0], oovv, mask, 'LDA')
                    aow = numpy.einsum('pi,p->pi', ao[0], wfxc * rho2)
                    for k in range(4):
                        f1oo[k] += numint._dot_ao_ao(mol, ao[k], aow, mask,
                                                     shls_slice, ao_loc)
                if with_vxc:
                    aow = numpy.einsum('pi,p->pi', ao[0], vxc[0] * weight)
                    for k in range(4):
                        v1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, mask,
                                                     shls_slice, ao_loc)
                if with_kxc:
                    aow = numpy.einsum('pi,p->pi', ao[0],
                                       kxc[0] * weight * rho1**2)
                    for k in range(4):
                        k1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, mask,
                                                     shls_slice, ao_loc)
                vxc = fxc = kxc = aow = rho = rho1 = rho2 = None
            if with_kxc:  # for (rho1*2)^2, *2 for alpha+beta in singlet
                k1ao *= 4

        else:
            raise NotImplementedError('LDA triplet')

    elif xctype == 'GGA':
        if singlet:

            def gga_sum_(vmat, ao, wv, mask):
                aow = numpy.einsum('pi,p->pi', ao[0], wv[0] * .5)
                aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
                tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice,
                                        ao_loc)
                vmat[0] += tmp + tmp.T
                vmat[1:] += rks_grad._gga_grad_sum(mol, ao, wv, mask,
                                                   shls_slice, ao_loc)

            ao_deriv = 2
            for ao, mask, weight, coords \
                    in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
                rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, mask, 'GGA')
                vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 0, deriv=deriv)[1:]

                vrho, vgamma = vxc[:2]
                frr, frg, fgg = fxc[:3]

                rho1 = ni.eval_rho(mol, ao, dmvo, mask,
                                   'GGA') * 2  # *2 for alpha + beta
                sigma1 = numpy.einsum('xi,xi->i', rho[1:], rho1[1:])
                wv = numpy.empty_like((rho))
                wv[0] = frr * rho1[0]
                wv[0] += frg * sigma1 * 2
                wv[1:] = (fgg * sigma1 * 4 + frg * rho1[0] * 2) * rho[1:]
                wv[1:] += vgamma * rho1[1:] * 2
                wv *= weight
                gga_sum_(f1vo, ao, wv, mask)

                if oovv is not None:
                    rho2 = ni.eval_rho(mol, ao, oovv, mask, 'GGA') * 2
                    sigma2 = numpy.einsum('xi,xi->i', rho[1:], rho2[1:])
                    wv[0] = frr * rho2[0]
                    wv[0] += frg * sigma2 * 2
                    wv[1:] = (fgg * sigma2 * 4 + frg * rho2[0] * 2) * rho[1:]
                    wv[1:] += vgamma * rho2[1:] * 2
                    wv *= weight
                    gga_sum_(f1oo, ao, wv, mask)
                if with_vxc:
                    wv[0] = vrho
                    wv[1:] = 2 * vgamma * rho[1:]
                    wv *= weight
                    gga_sum_(v1ao, ao, wv, mask)
                if with_kxc:
                    frrr, frrg, frgg, fggg = kxc
                    r1r1 = rho1[0]**2
                    s1s1 = sigma1**2
                    r1s1 = rho1[0] * sigma1
                    sigma2 = numpy.einsum('xi,xi->i', rho1[1:], rho1[1:])
                    wv[0] = frrr * r1r1
                    wv[0] += 4 * frrg * r1s1
                    wv[0] += 4 * frgg * s1s1
                    wv[0] += 2 * frg * sigma2
                    wv[1:] = 2 * frrg * r1r1 * rho[1:]
                    wv[1:] += 8 * frgg * r1s1 * rho[1:]
                    wv[1:] += 4 * frg * rho1[0] * rho1[1:]
                    wv[1:] += 4 * fgg * sigma2 * rho[1:]
                    wv[1:] += 8 * fgg * sigma1 * rho1[1:]
                    wv[1:] += 8 * fggg * s1s1 * rho[1:]
                    wv *= weight
                    gga_sum_(k1ao, ao, wv, mask)
                vxc = fxc = kxc = rho = rho1 = rho2 = sigma1 = sigma2 = None

        else:
            raise NotImplementedError('GGA triplet')

    else:
        raise NotImplementedError('meta-GGA')

    f1vo[1:] *= -1
    if f1oo is not None: f1oo[1:] *= -1
    if v1ao is not None: v1ao[1:] *= -1
    if k1ao is not None: k1ao[1:] *= -1
    return f1vo, f1oo, v1ao, k1ao
예제 #32
0
파일: rks_nmr.py 프로젝트: v1j4y/pyscf
def get_vxc_giao(ni, mol, grids, xc_code, dms, max_memory=2000, verbose=None):
    if isinstance(max_memory, (list, tuple, numpy.ndarray)):
        import warnings
        xc_code = '%s, %s' % (xc_code, dms)
        dms, max_memory = max_memory, 2000
        with warnings.catch_warnings():
            warnings.simplefilter("once")
            warnings.warn('API updates: the 5th argument c_id is decoreated '
                          'and will be removed in future release.\n')

    xctype = ni._xc_type(xc_code)
    make_rho, nset, nao = ni._gen_rho_evaluator(mol, dms, hermi=1)
    ngrids = len(grids.weights)
    BLKSIZE = numint.BLKSIZE
    blksize = min(int(max_memory/12*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids)

    vmat = numpy.zeros((3,nao,nao))
    if xctype == 'LDA':
        buf = numpy.empty((4,blksize,nao))
        ao_deriv = 0
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 ni.non0tab, blksize=blksize, buf=buf):
            rho = make_rho(0, ao, mask, 'LDA')
            vxc = ni.eval_xc(xc_code, rho, 0, deriv=1)[1]
            vrho = vxc[0]
            aow = numpy.einsum('pi,p->pi', ao, weight*vrho)
            giao = mol.eval_gto('GTOval_ig_sph', coords, comp=3,
                                non0tab=mask, out=buf[1:])
            vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], nao, weight.size, mask)
            vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], nao, weight.size, mask)
            vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], nao, weight.size, mask)
            rho = vxc = vrho = aow = None
    elif xctype == 'GGA':
        buf = numpy.empty((10,blksize,nao))
        XX, XY, XZ = 0, 1, 2
        YX, YY, YZ = 3, 4, 5
        ZX, ZY, ZZ = 6, 7, 8
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 ni.non0tab, blksize=blksize, buf=buf):
            rho = make_rho(0, ao, mask, 'GGA')
            vxc = ni.eval_xc(xc_code, rho, 0, deriv=1)[1]
            vrho, vsigma = vxc[:2]
            wv = numpy.empty_like(rho)
            wv[0]  = weight * vrho
            wv[1:] = rho[1:] * (weight * vsigma * 2)

            aow = numpy.einsum('npi,np->pi', ao[:4], wv)
            giao = mol.eval_gto('GTOval_ig_sph', coords, 3,
                                non0tab=mask, out=buf[4:])
            vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], nao, weight.size, mask)
            vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], nao, weight.size, mask)
            vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], nao, weight.size, mask)

            giao = mol.eval_gto('GTOval_ipig_sph', coords, 9,
                                non0tab=mask, out=buf[1:])
            aow = numpy.einsum('pi,p->pi', giao[XX], wv[1])
            aow+= numpy.einsum('pi,p->pi', giao[YX], wv[2])
            aow+= numpy.einsum('pi,p->pi', giao[ZX], wv[3])
            vmat[0] += numint._dot_ao_ao(mol, ao[0], aow, nao, weight.size, mask)
            aow = numpy.einsum('pi,p->pi', giao[XY], wv[1])
            aow+= numpy.einsum('pi,p->pi', giao[YY], wv[2])
            aow+= numpy.einsum('pi,p->pi', giao[ZY], wv[3])
            vmat[1] += numint._dot_ao_ao(mol, ao[0], aow, nao, weight.size, mask)
            aow = numpy.einsum('pi,p->pi', giao[XZ], wv[1])
            aow+= numpy.einsum('pi,p->pi', giao[YZ], wv[2])
            aow+= numpy.einsum('pi,p->pi', giao[ZZ], wv[3])
            vmat[2] += numint._dot_ao_ao(mol, ao[0], aow, nao, weight.size, mask)
            rho = vxc = vrho = vsigma = wv = aow = None
    else:
        raise NotImplementedError('meta-GGA')

    return vmat - vmat.transpose(0,2,1)
예제 #33
0
파일: rks.py 프로젝트: zwgsyntax/pyscf
def _get_vxc_diag(hessobj, mo_coeff, mo_occ, max_memory):
    mol = hessobj.mol
    mf = hessobj.base
    if hessobj.grids is not None:
        grids = hessobj.grids
    else:
        grids = mf.grids
    if grids.coords is None:
        grids.build(with_non0tab=True)

    nao, nmo = mo_coeff.shape
    ni = mf._numint
    xctype = ni._xc_type(mf.xc)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    vmat = numpy.zeros((6, nao, nao))
    if xctype == 'LDA':
        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = ni.eval_rho2(mol, ao[0], mo_coeff, mo_occ, mask, 'LDA')
            vxc = ni.eval_xc(mf.xc, rho, 0, deriv=1)[1]
            vrho = vxc[0]
            aow = numpy.einsum('pi,p->pi', ao[0], weight * vrho)
            for i in range(6):
                vmat[i] += numint._dot_ao_ao(mol, ao[i + 4], aow, mask,
                                             shls_slice, ao_loc)
            aow = None

    elif xctype == 'GGA':

        def contract_(mat, ao, aoidx, wv, mask):
            aow = numpy.einsum('pi,p->pi', ao[aoidx[0]], wv[1])
            aow += numpy.einsum('pi,p->pi', ao[aoidx[1]], wv[2])
            aow += numpy.einsum('pi,p->pi', ao[aoidx[2]], wv[3])
            mat += numint._dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)

        ao_deriv = 3
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = ni.eval_rho2(mol, ao[:4], mo_coeff, mo_occ, mask, 'GGA')
            vxc = ni.eval_xc(mf.xc, rho, 0, deriv=1)[1]

            wv = numint._rks_gga_wv0(rho, vxc, weight)
            # *2 because v.T is not applied. Only v is computed in the next _dot_ao_ao
            wv[0] *= 2
            aow = numpy.einsum('npi,np->pi', ao[:4], wv)
            for i in range(6):
                vmat[i] += numint._dot_ao_ao(mol, ao[i + 4], aow, mask,
                                             shls_slice, ao_loc)

            contract_(vmat[0], ao, [XXX, XXY, XXZ], wv, mask)
            contract_(vmat[1], ao, [XXY, XYY, XYZ], wv, mask)
            contract_(vmat[2], ao, [XXZ, XYZ, XZZ], wv, mask)
            contract_(vmat[3], ao, [XYY, YYY, YYZ], wv, mask)
            contract_(vmat[4], ao, [XYZ, YYZ, YZZ], wv, mask)
            contract_(vmat[5], ao, [XZZ, YZZ, ZZZ], wv, mask)
            rho = vxc = wv = aow = None

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

    vmat = vmat[[0, 1, 2, 1, 3, 4, 2, 4, 5]]
    return vmat.reshape(3, 3, nao, nao)
예제 #34
0
파일: uks.py 프로젝트: chrinide/pyscf
 def contract_(mat, ao, aoidx, wv, mask):
     aow = numpy.einsum('pi,p->pi', ao[aoidx[0]], wv[1])
     aow+= numpy.einsum('pi,p->pi', ao[aoidx[1]], wv[2])
     aow+= numpy.einsum('pi,p->pi', ao[aoidx[2]], wv[3])
     mat += numint._dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)
예제 #35
0
파일: ddcosmo.py 프로젝트: tmash/pyscf
def make_psi_vmat(pcmobj, dm, r_vdw, ui, grids, ylm_1sph, cached_pol, L_X, L):
    mol = pcmobj.mol
    natm = mol.natm
    lmax = pcmobj.lmax
    nlm = (lmax+1)**2

    i1 = 0
    scaled_weights = numpy.empty(grids.weights.size)
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        eta_nj = 0
        p1 = 0
        for l in range(lmax+1):
            fac = 4*numpy.pi/(l*2+1)
            p0, p1 = p1, p1 + (l*2+1)
            eta_nj += fac * numpy.einsum('mn,m->n', fak_pol[l], L_X[ia,p0:p1])
        scaled_weights[i0:i1] = eta_nj * grids.weights[i0:i1]

    if not (isinstance(dm, numpy.ndarray) and dm.ndim == 2):
        dm = dm[0] + dm[1]
    ni = numint.NumInt()
    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    make_rho, nset, nao = ni._gen_rho_evaluator(mol, dm)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()
    den = numpy.empty(grids.weights.size)
    vmat = numpy.zeros((nao,nao))
    p1 = 0
    aow = None
    for ao, mask, weight, coords \
            in ni.block_loop(mol, grids, nao, 0, max_memory):
        p0, p1 = p1, p1 + weight.size
        den[p0:p1] = weight * make_rho(0, ao, mask, 'LDA')
        aow = numpy.ndarray(ao.shape, order='F', buffer=aow)
        aow = numpy.einsum('pi,p->pi', ao, scaled_weights[p0:p1], out=aow)
        vmat -= numint._dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    ao = aow = scaled_weights = None

    nelec_leak = 0
    psi = numpy.empty((natm,nlm))
    i1 = 0
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        nelec_leak += den[i0:i1][leak_idx].sum()
        p1 = 0
        for l in range(lmax+1):
            fac = 4*numpy.pi/(l*2+1)
            p0, p1 = p1, p1 + (l*2+1)
            psi[ia,p0:p1] = -fac * numpy.einsum('n,mn->m', den[i0:i1], fak_pol[l])
# Contribution of nuclear charge to the total density
# The factor numpy.sqrt(4*numpy.pi) is due to the product of 4*pi * Y_0^0
        psi[ia,0] += numpy.sqrt(4*numpy.pi)/r_vdw[ia] * mol.atom_charge(ia)
    logger.debug(pcmobj, 'electron leak %f', nelec_leak)

    # <Psi, L^{-1}g> -> Psi = SL the adjoint equation to LX = g
    L_S = numpy.linalg.solve(L.T.reshape(natm*nlm,-1), psi.ravel()).reshape(natm,-1)
    coords_1sph, weights_1sph = make_grids_one_sphere(pcmobj.lebedev_order)
    # JCP, 141, 184108, Eq (39)
    xi_jn = numpy.einsum('n,jn,xn,jx->jn', weights_1sph, ui, ylm_1sph, L_S)
    extern_point_idx = ui > 0
    cav_coords = (mol.atom_coords().reshape(natm,1,3)
                  + numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))
    cav_coords = cav_coords[extern_point_idx]
    xi_jn = xi_jn[extern_point_idx]

    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    blksize = int(max(max_memory*1e6/8/nao**2, 400))

    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas,
                                         mol._env, 'int3c2e')
    vmat_tril = 0
    for i0, i1 in lib.prange(0, xi_jn.size, blksize):
        fakemol = gto.fakemol_for_charges(cav_coords[i0:i1])
        v_nj = df.incore.aux_e2(mol, fakemol, intor='int3c2e', aosym='s2ij',
                                cintopt=cintopt)
        vmat_tril += numpy.einsum('xn,n->x', v_nj, xi_jn[i0:i1])
    vmat += lib.unpack_tril(vmat_tril)
    return psi, vmat, L_S
예제 #36
0
파일: tdrks.py 프로젝트: zwang123/pyscf
def _contract_xc_kernel(td_grad,
                        xc_code,
                        dmvo,
                        dmoo=None,
                        with_vxc=True,
                        with_kxc=True,
                        singlet=True,
                        max_memory=2000):
    mol = td_grad.mol
    mf = td_grad.base._scf
    grids = mf.grids

    ni = mf._numint
    xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao, nmo = mo_coeff.shape
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = (dmvo + dmvo.T) * .5  # because K_{ia,jb} == K_{ia,jb}

    f1vo = numpy.zeros((4, nao, nao))  # 0th-order, d/dx, d/dy, d/dz
    deriv = 2
    if dmoo is not None:
        f1oo = numpy.zeros((4, nao, nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((4, nao, nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((4, nao, nao))
        deriv = 3
    else:
        k1ao = None

    if xctype == 'LDA':
        ao_deriv = 1
        if singlet:
            for ao, mask, weight, coords \
                    in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
                rho = ni.eval_rho2(mol, ao[0], mo_coeff, mo_occ, mask, 'LDA')
                vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 0, deriv=deriv)[1:]

                wfxc = fxc[0] * weight * 2  # *2 for alpha+beta
                rho1 = ni.eval_rho(mol, ao[0], dmvo, mask, 'LDA')
                aow = numpy.einsum('pi,p,p->pi', ao[0], wfxc, rho1)
                for k in range(4):
                    f1vo[k] += numint._dot_ao_ao(mol, ao[k], aow, mask,
                                                 shls_slice, ao_loc)
                if dmoo is not None:
                    rho2 = ni.eval_rho(mol, ao[0], dmoo, mask, 'LDA')
                    aow = numpy.einsum('pi,p,p->pi', ao[0], wfxc, rho2)
                    for k in range(4):
                        f1oo[k] += numint._dot_ao_ao(mol, ao[k], aow, mask,
                                                     shls_slice, ao_loc)
                if with_vxc:
                    aow = numpy.einsum('pi,p,p->pi', ao[0], vxc[0], weight)
                    for k in range(4):
                        v1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, mask,
                                                     shls_slice, ao_loc)
                if with_kxc:
                    aow = numpy.einsum('pi,p,p,p->pi', ao[0], kxc[0], weight,
                                       rho1**2)
                    for k in range(4):
                        k1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, mask,
                                                     shls_slice, ao_loc)
                vxc = fxc = kxc = aow = rho = rho1 = rho2 = None
            if with_kxc:  # for (rho1*2)^2, *2 for alpha+beta in singlet
                k1ao *= 4

        else:
            raise NotImplementedError('LDA triplet')

    elif xctype == 'GGA':
        if singlet:

            def gga_sum_(vmat, ao, wv, mask):
                aow = numpy.einsum('pi,p->pi', ao[0], wv[0])
                aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
                tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice,
                                        ao_loc)
                vmat[0] += tmp + tmp.T
                rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)

            ao_deriv = 2
            for ao, mask, weight, coords \
                    in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
                rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, mask, 'GGA')
                vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 0, deriv=deriv)[1:]

                rho1 = ni.eval_rho(mol, ao, dmvo, mask,
                                   'GGA') * 2  # *2 for alpha + beta
                wv = numint._rks_gga_wv1(rho, rho1, vxc, fxc, weight)
                gga_sum_(f1vo, ao, wv, mask)

                if dmoo is not None:
                    rho2 = ni.eval_rho(mol, ao, dmoo, mask, 'GGA') * 2
                    wv = numint._rks_gga_wv1(rho, rho2, vxc, fxc, weight)
                    gga_sum_(f1oo, ao, wv, mask)
                if with_vxc:
                    wv = numint._rks_gga_wv0(rho, vxc, weight)
                    gga_sum_(v1ao, ao, wv, mask)
                if with_kxc:
                    wv = numint._rks_gga_wv2(rho, rho1, fxc, kxc, weight)
                    gga_sum_(k1ao, ao, wv, mask)
                vxc = fxc = kxc = rho = rho1 = None

        else:
            raise NotImplementedError('GGA triplet')

    else:
        raise NotImplementedError('meta-GGA')

    f1vo[1:] *= -1
    if f1oo is not None: f1oo[1:] *= -1
    if v1ao is not None: v1ao[1:] *= -1
    if k1ao is not None: k1ao[1:] *= -1
    return f1vo, f1oo, v1ao, k1ao
예제 #37
0
파일: uks.py 프로젝트: sunqm/pyscf-test
def _get_vxc_diag(hessobj, mo_coeff, mo_occ, max_memory):
    mol = hessobj.mol
    mf = hessobj.base
    if hessobj.grids is not None:
        grids = hessobj.grids
    else:
        grids = mf.grids
    if grids.coords is None:
        grids.build(with_non0tab=True)

    nao, nmo = mo_coeff[0].shape
    ni = mf._numint
    xctype = ni._xc_type(mf.xc)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    vmata = numpy.zeros((6,nao,nao))
    vmatb = numpy.zeros((6,nao,nao))
    if xctype == 'LDA':
        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rhoa = ni.eval_rho2(mol, ao[0], mo_coeff[0], mo_occ[0], mask, 'LDA')
            rhob = ni.eval_rho2(mol, ao[0], mo_coeff[1], mo_occ[1], mask, 'LDA')
            vxc = ni.eval_xc(mf.xc, (rhoa,rhob), 1, deriv=1)[1]
            vrho = vxc[0]
            aowa = numpy.einsum('pi,p->pi', ao[0], weight*vrho[:,0])
            aowb = numpy.einsum('pi,p->pi', ao[0], weight*vrho[:,1])
            for i in range(6):
                vmata[i] += numint._dot_ao_ao(mol, ao[i+4], aowa, mask, shls_slice, ao_loc)
                vmatb[i] += numint._dot_ao_ao(mol, ao[i+4], aowb, mask, shls_slice, ao_loc)
            aowa = aowb = None

    elif xctype == 'GGA':
        def contract_(mat, ao, aoidx, wv, mask):
            aow = numpy.einsum('pi,p->pi', ao[aoidx[0]], wv[1])
            aow+= numpy.einsum('pi,p->pi', ao[aoidx[1]], wv[2])
            aow+= numpy.einsum('pi,p->pi', ao[aoidx[2]], wv[3])
            mat += numint._dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)

        ao_deriv = 3
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rhoa = ni.eval_rho2(mol, ao[:4], mo_coeff[0], mo_occ[0], mask, 'GGA')
            rhob = ni.eval_rho2(mol, ao[:4], mo_coeff[1], mo_occ[1], mask, 'GGA')
            vxc = ni.eval_xc(mf.xc, (rhoa,rhob), 1, deriv=1)[1]

            wva, wvb = numint._uks_gga_wv0((rhoa,rhob), vxc, weight)
            # *2 because v.T is not applied.
            wva[0] *= 2
            wvb[0] *= 2
            aowa = numpy.einsum('npi,np->pi', ao[:4], wva)
            aowb = numpy.einsum('npi,np->pi', ao[:4], wvb)
            for i in range(6):
                vmata[i] += numint._dot_ao_ao(mol, ao[i+4], aowa, mask, shls_slice, ao_loc)
                vmatb[i] += numint._dot_ao_ao(mol, ao[i+4], aowb, mask, shls_slice, ao_loc)
            contract_(vmata[0], ao, [XXX,XXY,XXZ], wva, mask)
            contract_(vmata[1], ao, [XXY,XYY,XYZ], wva, mask)
            contract_(vmata[2], ao, [XXZ,XYZ,XZZ], wva, mask)
            contract_(vmata[3], ao, [XYY,YYY,YYZ], wva, mask)
            contract_(vmata[4], ao, [XYZ,YYZ,YZZ], wva, mask)
            contract_(vmata[5], ao, [XZZ,YZZ,ZZZ], wva, mask)
            contract_(vmatb[0], ao, [XXX,XXY,XXZ], wvb, mask)
            contract_(vmatb[1], ao, [XXY,XYY,XYZ], wvb, mask)
            contract_(vmatb[2], ao, [XXZ,XYZ,XZZ], wvb, mask)
            contract_(vmatb[3], ao, [XYY,YYY,YYZ], wvb, mask)
            contract_(vmatb[4], ao, [XYZ,YYZ,YZZ], wvb, mask)
            contract_(vmatb[5], ao, [XZZ,YZZ,ZZZ], wvb, mask)
            vxc = aowa = aowb = None

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

    vmata = vmata[[0,1,2, 1,3,4, 2,4,5]].reshape(3,3,nao,nao)
    vmatb = vmatb[[0,1,2, 1,3,4, 2,4,5]].reshape(3,3,nao,nao)
    return vmata, vmatb
예제 #38
0
파일: rks_grad.py 프로젝트: berquist/pyscf
def get_vxc(ni, mol, grids, xc_code, dms, relativity=0, hermi=1,
            max_memory=2000, verbose=None):
    if isinstance(relativity, (list, tuple, numpy.ndarray)):
        import warnings
        xc_code = '%s, %s' % (xc_code, dms)
        dms = relativity
        with warnings.catch_warnings():
            warnings.simplefilter("once")
            warnings.warn('API updates: the 5th argument c_id is decoreated '
                          'and will be removed in future release.\n')
    natocc = []
    natorb = []
    if isinstance(dms, numpy.ndarray) and dms.ndim == 2:
        e, c = scipy.linalg.eigh(dms)
        natocc.append(e)
        natorb.append(c)
        nao = dms.shape[0]
    else:
        for dm in dms:
            e, c = scipy.linalg.eigh(dm)
            natocc.append(e)
            natorb.append(c)
        nao = dms[0].shape[0]

    xctype = ni._xc_type(xc_code)
    make_rho, nset, nao = ni._gen_rho_evaluator(mol, dms, hermi)

    nset = len(natocc)
    vmat = numpy.zeros((nset,3,nao,nao))
    if xctype == 'LDA':
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory, ni.non0tab):
            for idm in range(nset):
                rho = make_rho(idm, ao[0], mask, 'LDA')
                vxc = ni.eval_xc(xc_code, rho, 0, relativity, 1, verbose)[1]
                vrho = vxc[0]
                aow = numpy.einsum('pi,p->pi', ao[0], weight*vrho)
                vmat[idm,0] += numint._dot_ao_ao(mol, ao[1], aow, nao, weight.size, mask)
                vmat[idm,1] += numint._dot_ao_ao(mol, ao[2], aow, nao, weight.size, mask)
                vmat[idm,2] += numint._dot_ao_ao(mol, ao[3], aow, nao, weight.size, mask)
                rho = vxc = vrho = aow = None
    elif xctype == 'GGA':
        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory, ni.non0tab):
            for idm in range(nset):
                rho = make_rho(idm, ao, mask, 'GGA')
                vxc = ni.eval_xc(xc_code, rho, 0, relativity, 1, verbose)[1]
                vrho, vsigma = vxc[:2]
                wv = numpy.empty_like(rho)
                wv[0]  = weight * vrho
                wv[1:] = rho[1:] * (weight * vsigma * 2)
                vmat[idm] += _gga_grad_sum(mol, ao, wv, mask)
    else:
        raise NotImplementedError('meta-GGA')

    if nset == 1:
        vmat = vmat.reshape(3,nao,nao)
    # - sign because nabla_X = -nabla_x
    return -vmat
예제 #39
0
파일: tduks.py 프로젝트: chrinide/pyscf
def _contract_xc_kernel(td_grad, xc_code, dmvo, dmoo=None, with_vxc=True,
                        with_kxc=True, max_memory=2000):
    mol = td_grad.mol
    mf = td_grad.base._scf
    grids = mf.grids

    ni = mf._numint
    xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao = mo_coeff[0].shape[0]
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = [(dmvo[0] + dmvo[0].T) * .5, # because K_{ia,jb} == K_{ia,jb}
            (dmvo[1] + dmvo[1].T) * .5]

    f1vo = numpy.zeros((2,4,nao,nao))
    deriv = 2
    if dmoo is not None:
        f1oo = numpy.zeros((2,4,nao,nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((2,4,nao,nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((2,4,nao,nao))
        deriv = 3
    else:
        k1ao = None

    if xctype == 'LDA':
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao[0], mo_coeff[0], mo_occ[0], mask, 'LDA'),
                   ni.eval_rho2(mol, ao[0], mo_coeff[1], mo_occ[1], mask, 'LDA'))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            u_u, u_d, d_d = fxc[0].T * weight
            rho1a = ni.eval_rho(mol, ao[0], dmvo[0], mask, 'LDA')
            rho1b = ni.eval_rho(mol, ao[0], dmvo[1], mask, 'LDA')
            aow = (numpy.einsum('pi,p,p->pi', ao[0], u_u, rho1a) +
                   numpy.einsum('pi,p,p->pi', ao[0], u_d, rho1b),
                   numpy.einsum('pi,p,p->pi', ao[0], u_d, rho1a) +
                   numpy.einsum('pi,p,p->pi', ao[0], d_d, rho1b))
            for k in range(4):
                f1vo[0,k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask, shls_slice, ao_loc)
                f1vo[1,k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask, shls_slice, ao_loc)
            if dmoo is not None:
                rho2a = ni.eval_rho(mol, ao[0], dmoo[0], mask, 'LDA')
                rho2b = ni.eval_rho(mol, ao[0], dmoo[1], mask, 'LDA')
                aow = (numpy.einsum('pi,p,p->pi', ao[0], u_u, rho2a) +
                       numpy.einsum('pi,p,p->pi', ao[0], u_d, rho2b),
                       numpy.einsum('pi,p,p->pi', ao[0], u_d, rho2a) +
                       numpy.einsum('pi,p,p->pi', ao[0], d_d, rho2b))
                for k in range(4):
                    f1oo[0,k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask, shls_slice, ao_loc)
                    f1oo[1,k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask, shls_slice, ao_loc)
            if with_vxc:
                vrho = vxc[0].T * weight
                aow = (numpy.einsum('pi,p->pi', ao[0], vrho[0]),
                       numpy.einsum('pi,p->pi', ao[0], vrho[1]))
                for k in range(4):
                    v1ao[0,k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask, shls_slice, ao_loc)
                    v1ao[1,k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask, shls_slice, ao_loc)
            if with_kxc:
                u_u_u, u_u_d, u_d_d, d_d_d = kxc[0].T * weight
                aow = (numpy.einsum('pi,p,p,p->pi', ao[0], u_u_u, rho1a, rho1a) +
                       numpy.einsum('pi,p,p,p->pi', ao[0], u_u_d, rho1a, rho1b)*2 +
                       numpy.einsum('pi,p,p,p->pi', ao[0], u_d_d, rho1b, rho1b),
                       numpy.einsum('pi,p,p,p->pi', ao[0], u_u_d, rho1a, rho1a) +
                       numpy.einsum('pi,p,p,p->pi', ao[0], u_d_d, rho1a, rho1b)*2 +
                       numpy.einsum('pi,p,p,p->pi', ao[0], d_d_d, rho1b, rho1b))
                for k in range(4):
                    k1ao[0,k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask, shls_slice, ao_loc)
                    k1ao[1,k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask, shls_slice, ao_loc)
            vxc = fxc = kxc = aow = rho = rho1 = rho2 = None

    elif xctype == 'GGA':
        def gga_sum_(vmat, ao, wv, mask):
            aow  = numpy.einsum('pi,p->pi', ao[0], wv[0])
            aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
            tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
            vmat[0] += tmp + tmp.T
            rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)
        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao, mo_coeff[0], mo_occ[0], mask, 'GGA'),
                   ni.eval_rho2(mol, ao, mo_coeff[1], mo_occ[1], mask, 'GGA'))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            rho1 = (ni.eval_rho(mol, ao, dmvo[0], mask, 'GGA'),
                    ni.eval_rho(mol, ao, dmvo[1], mask, 'GGA'))
            wv = numint._uks_gga_wv1(rho, rho1, vxc, fxc, weight)
            gga_sum_(f1vo[0], ao, wv[0], mask)
            gga_sum_(f1vo[1], ao, wv[1], mask)

            if dmoo is not None:
                rho2 = (ni.eval_rho(mol, ao, dmoo[0], mask, 'GGA'),
                        ni.eval_rho(mol, ao, dmoo[1], mask, 'GGA'))
                wv = numint._uks_gga_wv1(rho, rho2, vxc, fxc, weight)
                gga_sum_(f1oo[0], ao, wv[0], mask)
                gga_sum_(f1oo[1], ao, wv[1], mask)
            if with_vxc:
                wv = numint._uks_gga_wv0(rho, vxc, weight)
                gga_sum_(v1ao[0], ao, wv[0], mask)
                gga_sum_(v1ao[1], ao, wv[1], mask)
            if with_kxc:
                wv = numint._uks_gga_wv2(rho, rho1, fxc, kxc, weight)
                gga_sum_(k1ao[0], ao, wv[0], mask)
                gga_sum_(k1ao[1], ao, wv[1], mask)
            vxc = fxc = kxc = rho = rho1 = None

    else:
        raise NotImplementedError('meta-GGA')

    f1vo[:,1:] *= -1
    if f1oo is not None: f1oo[:,1:] *= -1
    if v1ao is not None: v1ao[:,1:] *= -1
    if k1ao is not None: k1ao[:,1:] *= -1
    return f1vo, f1oo, v1ao, k1ao
예제 #40
0
파일: rks.py 프로젝트: berquist/pyscf
def _contract_xc_kernel(td, xc_code, dmvo, singlet=True, max_memory=2000):
    mf = td._scf
    mol = td.mol
    grids = mf.grids

    if USE_XCFUN:
        ni = copy.copy(mf._numint)
        try:
            ni.libxc = dft.xcfun
            xctype = ni._xc_type(xc_code)
        except (ImportError, KeyError, NotImplementedError):
            ni.libxc = dft.libxc
            xctype = ni._xc_type(xc_code)
    else:
        ni = mf._numint
        xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao, nmo = mo_coeff.shape
    ndm = len(dmvo)

    dmvo = numpy.asarray(dmvo)
    dmvo = (dmvo + dmvo.transpose(0,2,1)) * .5
    v1ao = numpy.zeros((ndm,nao,nao))
    if xctype == 'LDA':
        ao_deriv = 0
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory, ni.non0tab):
            rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, mask, 'LDA')
            rho *= .5  # alpha density
            fxc = ni.eval_xc(xc_code, (rho,rho), 1, deriv=2)[2]
            u_u, u_d, d_d = v2rho2 = fxc[0].T
            if singlet:
                frho = u_u + u_d
            else:
                frho = u_u - u_d

            for i, dm in enumerate(dmvo):
                rho1 = ni.eval_rho(mol, ao, dm, mask, xctype)
                aow = numpy.einsum('pi,p->pi', ao, weight*frho*rho1)
                v1ao[i] += numint._dot_ao_ao(mol, aow, ao, nao, weight.size, mask)
                rho1 = aow = None

        for i in range(ndm):
            v1ao[i] = (v1ao[i] + v1ao[i].T) * .5

    elif xctype == 'GGA':
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory, ni.non0tab):
            rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, mask, 'GGA')
            rho *= .5  # alpha density
            vxc, fxc = ni.eval_xc(xc_code, (rho,rho), 1, deriv=2)[1:3]

            vsigma = vxc[1].T
            u_u, u_d, d_d = fxc[0].T  # v2rho2
            u_uu, u_ud, u_dd, d_uu, d_ud, d_dd = fxc[1].T  # v2rhosigma
            uu_uu, uu_ud, uu_dd, ud_ud, ud_dd, dd_dd = fxc[2].T  # v2sigma2
            if singlet:
                fgamma = 2*vsigma[0] + vsigma[1]
                frho = u_u + u_d
                fgg = uu_uu + .5*ud_ud + 2*uu_ud + uu_dd
                frhogamma = u_uu + u_dd + u_ud
            else:
                fgamma = 2*vsigma[0] - vsigma[1]
                frho = u_u - u_d
                fgg = uu_uu - uu_dd
                frhogamma = u_uu - u_dd

            ngrid = weight.size
            wv = numpy.empty((4,ngrid))
            for i, dm in enumerate(dmvo):
                # rho1[0 ] = |b><j| z_{bj}
                # rho1[1:] = \nabla(|b><j|) z_{bj}
                rho1 = ni.eval_rho(mol, ao, dm, mask, 'GGA')
                # sigma1 = \nabla(\rho_\alpha+\rho_\beta) dot \nabla(|b><j|) z_{bj}
                # *2 for alpha + beta
                sigma1 = numpy.einsum('xi,xi->i', rho[1:], rho1[1:]) * 2

                wv[0 ]  = frho * rho1[0]
                wv[0 ] += frhogamma * sigma1
                wv[1:]  = (fgg * sigma1 + frhogamma * rho1[0]) * rho[1:]
                wv[1:] *= 2  # because \nabla\rho = \nabla(\rho_\alpha+\rho_\beta)
                wv[1:] += fgamma * rho1[1:]
                wv[1:] *= 2  # because +h.c for (\nabla\mu) \nu, which are symmetrized at the end
                wv *= weight
                aow = numpy.einsum('nip,ni->ip', ao, wv)
                v1ao[i] += numint._dot_ao_ao(mol, ao[0], aow, nao, ngrid, mask)

        for i in range(ndm):
            v1ao[i] = (v1ao[i] + v1ao[i].T) * .5
    else:
        raise NotImplementedError('meta-GGA')

    return v1ao
예제 #41
0
파일: rks.py 프로젝트: v1j4y/pyscf
def _contract_xc_kernel(mf, xc_code, dms, max_memory=2000):
    mol = mf.mol
    grids = mf.grids

    ni = copy.copy(mf._numint)
    if USE_XCFUN:
        try:
            ni.libxc = dft.xcfun
            xctype = ni._xc_type(xc_code)
        except (ImportError, KeyError, NotImplementedError):
            ni.libxc = dft.libxc
            xctype = ni._xc_type(xc_code)
    else:
        xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao, nmo = mo_coeff.shape
    ndm = len(dms)

    dms = numpy.asarray(dms)
    dms = (dms + dms.transpose(0,2,1)) * .5
    v1ao = numpy.zeros((ndm,nao,nao))
    if xctype == 'LDA':
        ao_deriv = 0
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory, ni.non0tab):
            rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, mask, 'LDA')
            fxc = ni.eval_xc(xc_code, rho, 0, deriv=2)[2]
            frho = fxc[0]

            for i, dm in enumerate(dms):
                rho1 = ni.eval_rho(mol, ao, dm, mask, xctype)
                aow = numpy.einsum('pi,p->pi', ao, weight*frho*rho1)
                v1ao[i] += numint._dot_ao_ao(mol, aow, ao, nao, weight.size, mask)
                rho1 = aow = None

    elif xctype == 'GGA':
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory, ni.non0tab):
            rho = ni.eval_rho2(mol, ao[:4], mo_coeff, mo_occ, mask, 'GGA')
            vxc, fxc = ni.eval_xc(xc_code, rho, 0, deriv=2)[1:3]
            vgamma = vxc[1]
            frr, frg, fgg = fxc[:3]
            for i, dm in enumerate(dms):
                rho1 = ni.eval_rho(mol, ao, dm, mask, 'GGA')
                sigma1 = numpy.einsum('xi,xi->i', rho[1:], rho1[1:])
                ngrid = weight.size
                wv = numpy.empty((4,ngrid))
                wv[0]  = frr * rho1[0]
                wv[0] += frg * sigma1 * 2
                wv[1:]  = (fgg * sigma1 * 4 + frg * rho1[0] * 2) * rho[1:]
                wv[1:] += vgamma * rho1[1:] * 2
                wv[1:] *= 2  # for (\nabla\mu) \nu + \mu (\nabla\nu)
                wv *= weight
                aow = numpy.einsum('npi,np->pi', ao, wv)
                v1ao[i] += numint._dot_ao_ao(mol, aow, ao[0], nao, ngrid, mask)
    else:
        raise NotImplementedError('meta-GGA')

    for i in range(ndm):
        v1ao[i] = (v1ao[i] + v1ao[i].T) * .5
    return v1ao
예제 #42
0
파일: uks.py 프로젝트: pulkin/pyscf
def get_vxc_giao(ni, mol, grids, xc_code, dms, max_memory=2000, verbose=None):
    xctype = ni._xc_type(xc_code)
    make_rhoa, nset, nao = ni._gen_rho_evaluator(mol, dms[0], hermi=1)
    make_rhob = ni._gen_rho_evaluator(mol, dms[1], hermi=1)[0]
    ngrids = len(grids.weights)
    BLKSIZE = numint.BLKSIZE
    blksize = min(
        int(max_memory / 12 * 1e6 / 8 / nao / BLKSIZE) * BLKSIZE, ngrids)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    vmat = numpy.zeros((2, 3, nao, nao))
    if xctype == 'LDA':
        buf = numpy.empty((4, blksize, nao))
        ao_deriv = 0
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize, buf=buf):
            rho_a = make_rhoa(0, ao, mask, 'LDA')
            rho_b = make_rhob(0, ao, mask, 'LDA')
            vxc = ni.eval_xc(xc_code, (rho_a, rho_b), 1, deriv=1)[1]
            vrho = vxc[0]
            giao = mol.eval_gto('GTOval_ig',
                                coords,
                                comp=3,
                                non0tab=mask,
                                out=buf[1:])
            aow = numpy.einsum('pi,p->pi', ao, weight * vrho[:, 0])
            vmat[0, 0] += numint._dot_ao_ao(mol, aow, giao[0], mask,
                                            shls_slice, ao_loc)
            vmat[0, 1] += numint._dot_ao_ao(mol, aow, giao[1], mask,
                                            shls_slice, ao_loc)
            vmat[0, 2] += numint._dot_ao_ao(mol, aow, giao[2], mask,
                                            shls_slice, ao_loc)
            aow = numpy.einsum('pi,p->pi', ao, weight * vrho[:, 1])
            vmat[1, 0] += numint._dot_ao_ao(mol, aow, giao[0], mask,
                                            shls_slice, ao_loc)
            vmat[1, 1] += numint._dot_ao_ao(mol, aow, giao[1], mask,
                                            shls_slice, ao_loc)
            vmat[1, 2] += numint._dot_ao_ao(mol, aow, giao[2], mask,
                                            shls_slice, ao_loc)
            rho = vxc = vrho = aow = None
    elif xctype == 'GGA':
        buf = numpy.empty((10, blksize, nao))
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize, buf=buf):
            rho_a = make_rhoa(0, ao, mask, 'GGA')
            rho_b = make_rhob(0, ao, mask, 'GGA')
            vxc = ni.eval_xc(xc_code, (rho_a, rho_b), 1, deriv=1)[1]
            vrho, vsigma = vxc[:2]
            giao = mol.eval_gto('GTOval_ig',
                                coords,
                                3,
                                non0tab=mask,
                                out=buf[4:])

            wva = numpy.empty_like(rho_a)
            wva[0] = weight * vrho[:, 0]
            wva[1:] = rho_a[1:] * (weight * vsigma[:, 0] * 2)  # sigma_uu
            wva[1:] += rho_b[1:] * (weight * vsigma[:, 1])  # sigma_ud
            wvb = numpy.empty_like(rho_b)
            wvb[0] = weight * vrho[:, 1]
            wvb[1:] = rho_b[1:] * (weight * vsigma[:, 2] * 2)  # sigma_dd
            wvb[1:] += rho_a[1:] * (weight * vsigma[:, 1])  # sigma_ud

            aow = numpy.einsum('npi,np->pi', ao[:4], wva)
            vmat[0, 0] += numint._dot_ao_ao(mol, aow, giao[0], mask,
                                            shls_slice, ao_loc)
            vmat[0, 1] += numint._dot_ao_ao(mol, aow, giao[1], mask,
                                            shls_slice, ao_loc)
            vmat[0, 2] += numint._dot_ao_ao(mol, aow, giao[2], mask,
                                            shls_slice, ao_loc)
            aow = numpy.einsum('npi,np->pi', ao[:4], wvb)
            vmat[1, 0] += numint._dot_ao_ao(mol, aow, giao[0], mask,
                                            shls_slice, ao_loc)
            vmat[1, 1] += numint._dot_ao_ao(mol, aow, giao[1], mask,
                                            shls_slice, ao_loc)
            vmat[1, 2] += numint._dot_ao_ao(mol, aow, giao[2], mask,
                                            shls_slice, ao_loc)

            giao = mol.eval_gto('GTOval_ipig',
                                coords,
                                9,
                                non0tab=mask,
                                out=buf[1:])
            rks_nmr._gga_sum_(vmat[0], mol, ao, giao, wva, mask, shls_slice,
                              ao_loc)
            rks_nmr._gga_sum_(vmat[1], mol, ao, giao, wvb, mask, shls_slice,
                              ao_loc)
            rho = vxc = vrho = vsigma = wv = aow = None
    else:
        raise NotImplementedError('meta-GGA')

    return vmat - vmat.transpose(0, 1, 3, 2)
예제 #43
0
파일: tduks.py 프로젝트: chrinide/pyscf
 def gga_sum_(vmat, ao, wv, mask):
     aow  = numpy.einsum('pi,p->pi', ao[0], wv[0])
     aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
     tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
     vmat[0] += tmp + tmp.T
     rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)
예제 #44
0
 def gga_sum_(vmat, ao, wv, mask):
     aow = numint._scale_ao(ao[:4], wv[:4])
     tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice,
                             ao_loc)
     vmat[0] += tmp + tmp.T
     rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)
예제 #45
0
파일: rks.py 프로젝트: yidapa/pyscf
def _get_vxc(ni, mol, grids, x_id, c_id, dms, relativity=0, hermi=1,
             max_memory=2000, verbose=None):
    natocc = []
    natorb = []
    if isinstance(dms, numpy.ndarray) and dms.ndim == 2:
        e, c = scipy.linalg.eigh(dms)
        natocc.append(e)
        natorb.append(c)
        nao = dms.shape[0]
    else:
        for dm in dms:
            e, c = scipy.linalg.eigh(dm)
            natocc.append(e)
            natorb.append(c)
        nao = dms[0].shape[0]

    xctype = numint._xc_type(x_id, c_id)
    ngrids = len(grids.weights)
    BLKSIZE = numint.BLKSIZE
    blksize = min(int(max_memory/6*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids)

    nset = len(natocc)
    nelec = numpy.zeros(nset)
    excsum = numpy.zeros(nset)
    vmat = numpy.zeros((nset,3,nao,nao))
    if xctype == 'LDA':
        buf = numpy.empty((4,blksize,nao))
        for ip0, ip1 in numint.prange(0, ngrids, blksize):
            coords = grids.coords[ip0:ip1]
            weight = grids.weights[ip0:ip1]
            non0tab = ni.non0tab[ip0//BLKSIZE:]
            ao = ni.eval_ao(mol, coords, deriv=1, non0tab=non0tab, out=buf)
            for idm in range(nset):
                rho = ni.eval_rho2(mol, ao[0], natorb[idm], natocc[idm], non0tab, xctype)
                exc, vxc = ni.eval_xc(x_id, c_id, rho, 0, relativity, 1, verbose)[:2]
                vrho = vxc[0]
                den = rho * weight
                nelec[idm] += den.sum()
                excsum[idm] += (den * exc).sum()
                aow = numpy.einsum('pi,p->pi', ao[0], weight*vrho)
                vmat[idm,0] += numint._dot_ao_ao(mol, ao[1], aow, nao, ip1-ip0, non0tab)
                vmat[idm,1] += numint._dot_ao_ao(mol, ao[2], aow, nao, ip1-ip0, non0tab)
                vmat[idm,2] += numint._dot_ao_ao(mol, ao[3], aow, nao, ip1-ip0, non0tab)
                rho = exc = vxc = vrho = aow = None
    elif xctype == 'GGA':
        buf = numpy.empty((10,blksize,nao))
        XX, XY, XZ = 4, 5, 6
        YX, YY, YZ = 5, 7, 8
        ZX, ZY, ZZ = 6, 8, 9
        for ip0, ip1 in numint.prange(0, ngrids, blksize):
            coords = grids.coords[ip0:ip1]
            weight = grids.weights[ip0:ip1]
            non0tab = ni.non0tab[ip0//BLKSIZE:]
            ao = ni.eval_ao(mol, coords, deriv=2, non0tab=non0tab, out=buf)
            for idm in range(nset):
                rho = ni.eval_rho2(mol, ao, natorb[idm], natocc[idm], non0tab, xctype)
                exc, vxc = ni.eval_xc(x_id, c_id, rho, 0, relativity, 1, verbose)[:2]
                vrho, vsigma = vxc[:2]
                den = rho[0] * weight
                nelec[idm] += den.sum()
                excsum[idm] += (den * exc).sum()
                wv = numpy.empty_like(rho)
                # *.5 because vmat + vmat.T implicitly
                wv[0]  = weight * vrho * .5
                wv[1:] = rho[1:] * (weight * vsigma * 2)

                aow = numpy.einsum('npi,np->pi', ao[:4], wv)
                vmat[idm,0] += numint._dot_ao_ao(mol, ao[1], aow, nao, ip1-ip0, non0tab)
                vmat[idm,1] += numint._dot_ao_ao(mol, ao[2], aow, nao, ip1-ip0, non0tab)
                vmat[idm,2] += numint._dot_ao_ao(mol, ao[3], aow, nao, ip1-ip0, non0tab)

                aow = numpy.einsum('pi,p->pi', ao[1] , wv[0])
                aow+= numpy.einsum('pi,p->pi', ao[XX], wv[1])
                aow+= numpy.einsum('pi,p->pi', ao[XY], wv[2])
                aow+= numpy.einsum('pi,p->pi', ao[XZ], wv[3])
                vmat[idm,0] += numint._dot_ao_ao(mol, aow, ao[0], nao, ip1-ip0, non0tab)
                aow = numpy.einsum('pi,p->pi', ao[2] , wv[0])
                aow+= numpy.einsum('pi,p->pi', ao[YX], wv[1])
                aow+= numpy.einsum('pi,p->pi', ao[YY], wv[2])
                aow+= numpy.einsum('pi,p->pi', ao[YZ], wv[3])
                vmat[idm,1] += numint._dot_ao_ao(mol, aow, ao[0], nao, ip1-ip0, non0tab)
                aow = numpy.einsum('pi,p->pi', ao[3] , wv[0])
                aow+= numpy.einsum('pi,p->pi', ao[ZX], wv[1])
                aow+= numpy.einsum('pi,p->pi', ao[ZY], wv[2])
                aow+= numpy.einsum('pi,p->pi', ao[ZZ], wv[3])
                vmat[idm,2] += numint._dot_ao_ao(mol, aow, ao[0], nao, ip1-ip0, non0tab)
                rho = exc = vxc = vrho = vsigma = wv = aow = None
    else:
        raise NotImplementedError('meta-GGA')

    if nset == 1:
        vmat = vmat.reshape(3,nao,nao)
    return vmat
예제 #46
0
파일: rks_grad.py 프로젝트: berquist/pyscf
 def gga_sum_(vmat, ao, wv, mask):
     aow  = numpy.einsum('pi,p->pi', ao[0], wv[0]*.5)
     aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
     tmp = numint._dot_ao_ao(mol, ao[0], aow, nao, weight.size, mask)
     vmat[0] += tmp + tmp.T
     vmat[1:] += rks_grad._gga_grad_sum(mol, ao, wv, mask)
예제 #47
0
파일: uks.py 프로젝트: sunqm/pyscf-test
 def contract_(mat, ao, aoidx, wv, mask):
     aow = numpy.einsum('pi,p->pi', ao[aoidx[0]], wv[1])
     aow+= numpy.einsum('pi,p->pi', ao[aoidx[1]], wv[2])
     aow+= numpy.einsum('pi,p->pi', ao[aoidx[2]], wv[3])
     mat += numint._dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)
예제 #48
0
파일: numint.py 프로젝트: ncrubin/pyscf
def eval_mat(mol, ao, weight, rho, vrho, vsigma=None, non0tab=None,
             xctype='LDA', verbose=None):
    '''Calculate the XC potential AO matrix.

    Args:
        mol : instance of :class:`Mole` or :class:`Cell`

        ao : ([4,] nx*ny*nz, nao=cell.nao_nr()) ndarray
            The value of the AO crystal orbitals on the real-space grid by default.
            If xctype='GGA', also contains the value of the gradient in the x, y,
            and z directions.

        rho : ([4,] nx*ny*nz) ndarray
            The value of the density on the real-space grid. If xctype='GGA',
            also contains the value of the gradient in the x, y, and z
            directions.

    See Also:
        pyscf.dft.numint.eval_mat

    '''

    if xctype == 'GGA':
        ngrids, nao = ao[0].shape
    else:
        ngrids, nao = ao.shape

    if non0tab is None:
        non0tab = numpy.ones(((ngrids+BLKSIZE-1)//BLKSIZE,mol.nbas),
                             dtype=numpy.int8)

    if numpy.iscomplexobj(ao):
        if xctype == 'GGA':
            assert(vsigma is not None and rho.ndim==2)
            #wv = weight * vsigma * 2
            #aow  = numpy.einsum('pi,p->pi', ao[1], rho[1]*wv)
            #aow += numpy.einsum('pi,p->pi', ao[2], rho[2]*wv)
            #aow += numpy.einsum('pi,p->pi', ao[3], rho[3]*wv)
            #aow += numpy.einsum('pi,p->pi', ao[0], .5*weight*vrho)
            wv = numpy.empty_like(rho)
            wv[0]  = weight * vrho * .5
            wv[1:] = rho[1:] * (weight * vsigma * 2)
            aow = numpy.einsum('npi,np->pi', ao, wv)

            ao_re = numpy.ascontiguousarray(ao[0].real)
            ao_im = numpy.ascontiguousarray(ao[0].imag)

            aow_re = numpy.ascontiguousarray(aow.real)
            aow_im = numpy.ascontiguousarray(aow.imag)

        else:
            # *.5 because return mat + mat.T
            #:aow = numpy.einsum('pi,p->pi', ao, .5*weight*vrho)
            ao_re = numpy.ascontiguousarray(ao.real)
            ao_im = numpy.ascontiguousarray(ao.imag)

            aow_re = ao_re * (.5*weight*vrho).reshape(-1,1)
            aow_im = ao_im * (.5*weight*vrho).reshape(-1,1)
            #mat = pyscf.lib.dot(ao.T, aow)

        mat_re = _dot_ao_ao(mol, ao_re, aow_re, nao, ngrids, non0tab)
        mat_re += _dot_ao_ao(mol, ao_im, aow_im, nao, ngrids, non0tab)
        mat_im = _dot_ao_ao(mol, ao_re, aow_im, nao, ngrids, non0tab)
        mat_im -= _dot_ao_ao(mol, ao_im, aow_re, nao, ngrids, non0tab)

        mat = mat_re + 1j*mat_im

        return (mat + mat.T.conj())

    else:
        return pyscf.dft.numint.eval_mat(mol, ao, weight, rho, vrho,
                                         vsigma=None, non0tab=None,
                                         xctype='LDA', verbose=None)
예제 #49
0
파일: rks.py 프로젝트: cheaps10/pyscf
def _contract_xc_kernel(td, x_id, c_id, dmvo, singlet=True, max_memory=2000):
    mf = td._scf
    mol = td.mol
    ni = mf._numint
    grids = mf.grids

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao, nmo = mo_coeff.shape
    ndm = len(dmvo)

    dmvo = numpy.asarray(dmvo)
    dmvo = (dmvo + dmvo.transpose(0,2,1)) * .5

    xctype = numint._xc_type(x_id, c_id)
    ngrids = len(grids.weights)
    BLKSIZE = numint.BLKSIZE
    blksize = min(int(max_memory*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids)

    v1ao = numpy.zeros((ndm,nao,nao))
    if xctype == 'LDA':
        buf = numpy.empty((blksize,nao))
        if singlet:
            for ip0, ip1 in numint.prange(0, ngrids, blksize):
                coords = grids.coords[ip0:ip1]
                weight = grids.weights[ip0:ip1]
                non0tab = ni.non0tab[ip0//BLKSIZE:]
                ao = ni.eval_ao(mol, coords, deriv=0, non0tab=non0tab, out=buf)
                rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, non0tab, 'LDA')
                rho *= .5  # alpha density
                fxc = ni.eval_xc(x_id, c_id, (rho,rho), 1, deriv=2)[2]
                u_u, u_d, d_d = v2rho2 = fxc[0].T
                frho = u_u + u_d
                for i, dm in enumerate(dmvo):
                    rho1 = ni.eval_rho(mol, ao, dm, non0tab, xctype)
                    aow = numpy.einsum('pi,p->pi', ao, weight*frho*rho1)
                    v1ao[i] += numint._dot_ao_ao(mol, aow, ao, nao, ip1-ip0, non0tab)
                    rho1 = aow = None

            for i in range(ndm):
                v1ao[i] = (v1ao[i] + v1ao[i].T) * .5
        else:
            # because frho = u_u - u_d = 0
            pass

    elif xctype == 'GGA':
        buf = numpy.empty((4,blksize,nao))
        for ip0, ip1 in numint.prange(0, ngrids, blksize):
            coords = grids.coords[ip0:ip1]
            weight = grids.weights[ip0:ip1]
            non0tab = ni.non0tab[ip0//BLKSIZE:]
            ao = ni.eval_ao(mol, coords, deriv=1, non0tab=non0tab, out=buf)
            rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, non0tab, 'GGA')
            rho *= .5  # alpha density
            vxc, fxc = ni.eval_xc(x_id, c_id, (rho,rho), 1, deriv=2)[1:3]

            vsigma = vxc[1].T
            u_u, u_d, d_d = fxc[0].T  # v2rho2
            u_uu, u_ud, u_dd, d_uu, d_ud, d_dd = fxc[1].T  # v2rhosigma
            uu_uu, uu_ud, uu_dd, ud_ud, ud_dd, dd_dd = fxc[2].T  # v2sigma2
            if singlet:
                fgamma = 2*vsigma[0] + vsigma[1]
                frho = u_u + u_d
                fgg = uu_uu + .5*ud_ud + 2*uu_ud + uu_dd
                frhogamma = u_uu + u_dd + u_ud
            else:
                fgamma = 2*vsigma[0] - vsigma[1]
                frho = u_u - u_d
                fgg = uu_uu - uu_dd
                frhogamma = u_uu - u_dd

            for i, dm in enumerate(dmvo):
                # rho1[0 ] = |b><j| z_{bj}
                # rho1[1:] = \nabla(|b><j|) z_{bj}
                rho1 = ni.eval_rho(mol, ao, dm, non0tab, 'GGA')
                # sigma1 = \nabla(\rho_\alpha+\rho_\beta) dot \nabla(|b><j|) z_{bj}
                # *2 for alpha + beta
                sigma1 = numpy.einsum('xi,xi->i', rho[1:], rho1[1:]) * 2

                wv  = frho * rho1[0]
                wv += frhogamma * sigma1
                wv *= weight
                if c_id == 131 or x_id in (402, 404, 411, 416, 419):
                    # second derivative of LYP functional in libxc library diverge
                    wv[rho[0] < 4.57e-11] = 0
                aow = numpy.einsum('pi,p->pi', ao[0], wv)
                v1ao[i] += numint._dot_ao_ao(mol, aow, ao[0], nao, ip1-ip0, non0tab)

                for k in range(3):
                    wv  = fgg * sigma1 * rho[1+k]
                    wv += frhogamma * rho1[0] * rho[1+k]
                    wv *= 2 # *2 because \nabla\rho = \nabla(\rho_\alpha+\rho_\beta)
                    wv += fgamma * rho1[1+k]
                    wv *= weight
                    if c_id == 131 or x_id in (402, 404, 411, 416, 419):
                        # second derivative of LYP functional in libxc library diverge
                        wv[rho[0] < 4.57e-11] = 0
                    aow = numpy.einsum('ip,i->ip', ao[0], wv)
                    #v1ao += numint._dot_ao_ao(mol, aow, ao[1+k], nao, ip1-ip0, non0tab)
                    #v1ao += numint._dot_ao_ao(mol, ao[1+k], aow, nao, ip1-ip0, non0tab)
                    # v1ao+v1ao.T at the end
                    v1ao[i] += 2*numint._dot_ao_ao(mol, aow, ao[1+k], nao, ip1-ip0, non0tab)
                aow = None
        for i in range(ndm):
            v1ao[i] = (v1ao[i] + v1ao[i].T) * .5
    else:
        raise NotImplementedError('meta-GGA')

    return v1ao
예제 #50
0
파일: rks_grad.py 프로젝트: cheaps10/pyscf
def _contract_xc_kernel(td_grad, x_id, c_id, xai, oovv=None, with_vxc=True,
                        with_kxc=True, singlet=True, max_memory=4000):
    mol = td_grad.mol
    mf = td_grad._scf
    ni = mf._numint
    grids = mf.grids

    mo_coeff = mf.mo_coeff
    mo_energy = mf.mo_energy
    mo_occ = mf.mo_occ
    nao, nmo = mo_coeff.shape
    nocc = (mo_occ>0).sum()
    orbv = mo_coeff[:,nocc:]
    orbo = mo_coeff[:,:nocc]

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = (xai + xai.T) * .5 # because K_{ai,bj} == K_{ai,bj}

    f1vo = numpy.zeros((4,nao,nao))
    deriv = 2
    if oovv is not None:
        f1oo = numpy.zeros((4,nao,nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((4,nao,nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((4,nao,nao))
        deriv = 3
    else:
        k1ao = None

    xctype = numint._xc_type(x_id, c_id)
    ngrids = len(grids.weights)
    BLKSIZE = numint.BLKSIZE
    max_memory = max_memory - 4*nao**2*8/1e6
    blksize = min(int(max_memory/6*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids)

    if xctype == 'LDA':
        buf = numpy.empty((4,blksize,nao))
        for ip0, ip1 in numint.prange(0, ngrids, blksize):
            coords = grids.coords[ip0:ip1]
            weight = grids.weights[ip0:ip1]
            non0tab = ni.non0tab[ip0//BLKSIZE:]
            ao = ni.eval_ao(mol, coords, deriv=1, non0tab=non0tab, out=buf)
            rho = ni.eval_rho2(mol, ao[0], mo_coeff, mo_occ, non0tab, 'LDA')
            vxc, fxc, kxc = ni.eval_xc(x_id, c_id, rho, 0, deriv=deriv)[1:]

            wfxc = fxc[0] * weight * 2  # *2 for alpha+beta
            if singlet:
                rho1 = ni.eval_rho(mol, ao[0], dmvo, non0tab, 'LDA')
                aow = numpy.einsum('pi,p->pi', ao[0], wfxc*rho1)
                for k in range(4):
                    f1vo[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, ip1-ip0, non0tab)
            if oovv is not None:
                rho2 = ni.eval_rho(mol, ao[0], oovv, non0tab, 'LDA')
                aow = numpy.einsum('pi,p->pi', ao[0], wfxc*rho2)
                for k in range(4):
                    f1oo[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, ip1-ip0, non0tab)
            if with_vxc:
                aow = numpy.einsum('pi,p->pi', ao[0], vxc[0]*weight)
                for k in range(4):
                    v1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, ip1-ip0, non0tab)
            if singlet and with_kxc:
                aow = numpy.einsum('pi,p->pi', ao[0], kxc[0]*weight*rho1**2)
                for k in range(4):
                    k1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, ip1-ip0, non0tab)
            vxc = fxc = kxc = aow = rho = rho1 = rho2 = None
        if singlet and with_kxc:
            k1ao *= 4

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

    f1vo[1:] *= -1
    if f1oo is not None: f1oo[1:] *= -1
    if v1ao is not None: v1ao[1:] *= -1
    if k1ao is not None: k1ao[1:] *= -1
    return f1vo, f1oo, v1ao, k1ao
예제 #51
0
파일: uks.py 프로젝트: chrinide/pyscf
def _get_vxc_diag(hessobj, mo_coeff, mo_occ, max_memory):
    mol = hessobj.mol
    mf = hessobj.base
    if hessobj.grids is not None:
        grids = hessobj.grids
    else:
        grids = mf.grids
    if grids.coords is None:
        grids.build(with_non0tab=True)

    nao, nmo = mo_coeff[0].shape
    ni = mf._numint
    xctype = ni._xc_type(mf.xc)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    vmata = numpy.zeros((6,nao,nao))
    vmatb = numpy.zeros((6,nao,nao))
    if xctype == 'LDA':
        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rhoa = ni.eval_rho2(mol, ao[0], mo_coeff[0], mo_occ[0], mask, 'LDA')
            rhob = ni.eval_rho2(mol, ao[0], mo_coeff[1], mo_occ[1], mask, 'LDA')
            vxc = ni.eval_xc(mf.xc, (rhoa,rhob), 1, deriv=1)[1]
            vrho = vxc[0]
            aowa = numpy.einsum('pi,p->pi', ao[0], weight*vrho[:,0])
            aowb = numpy.einsum('pi,p->pi', ao[0], weight*vrho[:,1])
            for i in range(6):
                vmata[i] += numint._dot_ao_ao(mol, ao[i+4], aowa, mask, shls_slice, ao_loc)
                vmatb[i] += numint._dot_ao_ao(mol, ao[i+4], aowb, mask, shls_slice, ao_loc)
            aowa = aowb = None

    elif xctype == 'GGA':
        def contract_(mat, ao, aoidx, wv, mask):
            aow = numpy.einsum('pi,p->pi', ao[aoidx[0]], wv[1])
            aow+= numpy.einsum('pi,p->pi', ao[aoidx[1]], wv[2])
            aow+= numpy.einsum('pi,p->pi', ao[aoidx[2]], wv[3])
            mat += numint._dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)

        ao_deriv = 3
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rhoa = ni.eval_rho2(mol, ao[:4], mo_coeff[0], mo_occ[0], mask, 'GGA')
            rhob = ni.eval_rho2(mol, ao[:4], mo_coeff[1], mo_occ[1], mask, 'GGA')
            vxc = ni.eval_xc(mf.xc, (rhoa,rhob), 1, deriv=1)[1]

            wva, wvb = numint._uks_gga_wv0((rhoa,rhob), vxc, weight)
            # *2 because v.T is not applied.
            wva[0] *= 2
            wvb[0] *= 2
            aowa = numpy.einsum('npi,np->pi', ao[:4], wva)
            aowb = numpy.einsum('npi,np->pi', ao[:4], wvb)
            for i in range(6):
                vmata[i] += numint._dot_ao_ao(mol, ao[i+4], aowa, mask, shls_slice, ao_loc)
                vmatb[i] += numint._dot_ao_ao(mol, ao[i+4], aowb, mask, shls_slice, ao_loc)
            contract_(vmata[0], ao, [XXX,XXY,XXZ], wva, mask)
            contract_(vmata[1], ao, [XXY,XYY,XYZ], wva, mask)
            contract_(vmata[2], ao, [XXZ,XYZ,XZZ], wva, mask)
            contract_(vmata[3], ao, [XYY,YYY,YYZ], wva, mask)
            contract_(vmata[4], ao, [XYZ,YYZ,YZZ], wva, mask)
            contract_(vmata[5], ao, [XZZ,YZZ,ZZZ], wva, mask)
            contract_(vmatb[0], ao, [XXX,XXY,XXZ], wvb, mask)
            contract_(vmatb[1], ao, [XXY,XYY,XYZ], wvb, mask)
            contract_(vmatb[2], ao, [XXZ,XYZ,XZZ], wvb, mask)
            contract_(vmatb[3], ao, [XYY,YYY,YYZ], wvb, mask)
            contract_(vmatb[4], ao, [XYZ,YYZ,YZZ], wvb, mask)
            contract_(vmatb[5], ao, [XZZ,YZZ,ZZZ], wvb, mask)
            rho = vxc = aowa = aowb = None

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

    vmata = vmata[[0,1,2, 1,3,4, 2,4,5]].reshape(3,3,nao,nao)
    vmatb = vmatb[[0,1,2, 1,3,4, 2,4,5]].reshape(3,3,nao,nao)
    return vmata, vmatb
예제 #52
0
파일: rks.py 프로젝트: chrinide/pyscf
def _get_vxc_diag(hessobj, mo_coeff, mo_occ, max_memory):
    mol = hessobj.mol
    mf = hessobj.base
    if hessobj.grids is not None:
        grids = hessobj.grids
    else:
        grids = mf.grids
    if grids.coords is None:
        grids.build(with_non0tab=True)

    nao, nmo = mo_coeff.shape
    ni = mf._numint
    xctype = ni._xc_type(mf.xc)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    vmat = numpy.zeros((6,nao,nao))
    if xctype == 'LDA':
        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = ni.eval_rho2(mol, ao[0], mo_coeff, mo_occ, mask, 'LDA')
            vxc = ni.eval_xc(mf.xc, rho, 0, deriv=1)[1]
            vrho = vxc[0]
            aow = numpy.einsum('pi,p->pi', ao[0], weight*vrho)
            for i in range(6):
                vmat[i] += numint._dot_ao_ao(mol, ao[i+4], aow, mask, shls_slice, ao_loc)
            aow = None

    elif xctype == 'GGA':
        def contract_(mat, ao, aoidx, wv, mask):
            aow = numpy.einsum('pi,p->pi', ao[aoidx[0]], wv[1])
            aow+= numpy.einsum('pi,p->pi', ao[aoidx[1]], wv[2])
            aow+= numpy.einsum('pi,p->pi', ao[aoidx[2]], wv[3])
            mat += numint._dot_ao_ao(mol, aow, ao[0], mask, shls_slice, ao_loc)

        ao_deriv = 3
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = ni.eval_rho2(mol, ao[:4], mo_coeff, mo_occ, mask, 'GGA')
            vxc = ni.eval_xc(mf.xc, rho, 0, deriv=1)[1]

            wv = numint._rks_gga_wv0(rho, vxc, weight)
            # *2 because v.T is not applied. Only v is computed in the next _dot_ao_ao 
            wv[0] *= 2
            aow = numpy.einsum('npi,np->pi', ao[:4], wv)
            for i in range(6):
                vmat[i] += numint._dot_ao_ao(mol, ao[i+4], aow, mask, shls_slice, ao_loc)

            contract_(vmat[0], ao, [XXX,XXY,XXZ], wv, mask)
            contract_(vmat[1], ao, [XXY,XYY,XYZ], wv, mask)
            contract_(vmat[2], ao, [XXZ,XYZ,XZZ], wv, mask)
            contract_(vmat[3], ao, [XYY,YYY,YYZ], wv, mask)
            contract_(vmat[4], ao, [XYZ,YYZ,YZZ], wv, mask)
            contract_(vmat[5], ao, [XZZ,YZZ,ZZZ], wv, mask)
            rho = vxc = wv = aow = None

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

    vmat = vmat[[0,1,2,
                 1,3,4,
                 2,4,5]]
    return vmat.reshape(3,3,nao,nao)
예제 #53
0
파일: ddcosmo.py 프로젝트: chrinide/pyscf
def make_psi_vmat(pcmobj, dm, r_vdw, ui, grids, ylm_1sph, cached_pol, L_X, L):
    mol = pcmobj.mol
    natm = mol.natm
    lmax = pcmobj.lmax
    nlm = (lmax+1)**2

    i1 = 0
    scaled_weights = numpy.empty(grids.weights.size)
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        eta_nj = 0
        p1 = 0
        for l in range(lmax+1):
            fac = 4*numpy.pi/(l*2+1)
            p0, p1 = p1, p1 + (l*2+1)
            eta_nj += fac * numpy.einsum('mn,m->n', fak_pol[l], L_X[ia,p0:p1])
        scaled_weights[i0:i1] = eta_nj * grids.weights[i0:i1]

    if not (isinstance(dm, numpy.ndarray) and dm.ndim == 2):
        dm = dm[0] + dm[1]
    ni = numint.NumInt()
    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    make_rho, nset, nao = ni._gen_rho_evaluator(mol, dm)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()
    den = numpy.empty(grids.weights.size)
    vmat = numpy.zeros((nao,nao))
    p1 = 0
    aow = None
    for ao, mask, weight, coords \
            in ni.block_loop(mol, grids, nao, 0, max_memory):
        p0, p1 = p1, p1 + weight.size
        den[p0:p1] = weight * make_rho(0, ao, mask, 'LDA')
        aow = numpy.ndarray(ao.shape, order='F', buffer=aow)
        aow = numpy.einsum('pi,p->pi', ao, scaled_weights[p0:p1], out=aow)
        vmat -= numint._dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    ao = aow = scaled_weights = None

    nelec_leak = 0
    psi = numpy.empty((natm,nlm))
    i1 = 0
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        nelec_leak += den[i0:i1][leak_idx].sum()
        p1 = 0
        for l in range(lmax+1):
            fac = 4*numpy.pi/(l*2+1)
            p0, p1 = p1, p1 + (l*2+1)
            psi[ia,p0:p1] = -fac * numpy.einsum('n,mn->m', den[i0:i1], fak_pol[l])
# Contribution of nuclear charge to the total density
# The factor numpy.sqrt(4*numpy.pi) is due to the product of 4*pi * Y_0^0
        psi[ia,0] += numpy.sqrt(4*numpy.pi)/r_vdw[ia] * mol.atom_charge(ia)
    logger.debug(pcmobj, 'electron leak %f', nelec_leak)

    # <Psi, L^{-1}g> -> Psi = SL the adjoint equation to LX = g
    L_S = numpy.linalg.solve(L.T.reshape(natm*nlm,-1), psi.ravel()).reshape(natm,-1)
    coords_1sph, weights_1sph = make_grids_one_sphere(pcmobj.lebedev_order)
    # JCP, 141, 184108, Eq (39)
    xi_jn = numpy.einsum('n,jn,xn,jx->jn', weights_1sph, ui, ylm_1sph, L_S)
    extern_point_idx = ui > 0
    cav_coords = (mol.atom_coords().reshape(natm,1,3)
                  + numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))
    cav_coords = cav_coords[extern_point_idx]
    xi_jn = xi_jn[extern_point_idx]

    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    blksize = int(max(max_memory*1e6/8/nao**2, 400))

    vmat_tril = 0
    for i0, i1 in lib.prange(0, xi_jn.size, blksize):
        fakemol = gto.fakemol_for_charges(cav_coords[i0:i1])
        v_nj = df.incore.aux_e2(mol, fakemol, intor='int3c2e', aosym='s2ij')
        vmat_tril += numpy.einsum('xn,n->x', v_nj, xi_jn[i0:i1])
    vmat += lib.unpack_tril(vmat_tril)
    return psi, vmat, L_S
예제 #54
0
파일: rks_grad.py 프로젝트: berquist/pyscf
def _contract_xc_kernel(td_grad, xc_code, xai, oovv=None, with_vxc=True,
                        with_kxc=True, singlet=True, max_memory=2000):
    mol = td_grad.mol
    mf = td_grad._scf
    grids = mf.grids

    ni = copy.copy(mf._numint)
    if rks.USE_XCFUN:
        try:
            ni.libxc = dft.xcfun
            xctype = ni._xc_type(xc_code)
        except (ImportError, KeyError, NotImplementedError):
            ni.libxc = dft.libxc
            xctype = ni._xc_type(xc_code)
    else:
        xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_energy = mf.mo_energy
    mo_occ = mf.mo_occ
    nao, nmo = mo_coeff.shape
    nocc = (mo_occ>0).sum()
    orbv = mo_coeff[:,nocc:]
    orbo = mo_coeff[:,:nocc]

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = (xai + xai.T) * .5 # because K_{ai,bj} == K_{ai,bj}

    f1vo = numpy.zeros((4,nao,nao))
    deriv = 2
    if oovv is not None:
        f1oo = numpy.zeros((4,nao,nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((4,nao,nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((4,nao,nao))
        deriv = 3
    else:
        k1ao = None

    if xctype == 'LDA':
        ao_deriv = 1
        if singlet:
            for ao, mask, weight, coords \
                    in ni.block_loop(mol, grids, nao, ao_deriv, max_memory, ni.non0tab):
                rho = ni.eval_rho2(mol, ao[0], mo_coeff, mo_occ, mask, 'LDA')
                vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 0, deriv=deriv)[1:]

                wfxc = fxc[0] * weight * 2  # *2 for alpha+beta
                rho1 = ni.eval_rho(mol, ao[0], dmvo, mask, 'LDA')
                aow = numpy.einsum('pi,p->pi', ao[0], wfxc*rho1)
                for k in range(4):
                    f1vo[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, weight.size, mask)
                if oovv is not None:
                    rho2 = ni.eval_rho(mol, ao[0], oovv, mask, 'LDA')
                    aow = numpy.einsum('pi,p->pi', ao[0], wfxc*rho2)
                    for k in range(4):
                        f1oo[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, weight.size, mask)
                if with_vxc:
                    aow = numpy.einsum('pi,p->pi', ao[0], vxc[0]*weight)
                    for k in range(4):
                        v1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, weight.size, mask)
                if with_kxc:
                    aow = numpy.einsum('pi,p->pi', ao[0], kxc[0]*weight*rho1**2)
                    for k in range(4):
                        k1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, weight.size, mask)
                vxc = fxc = kxc = aow = rho = rho1 = rho2 = None
            if with_kxc:  # for (rho1*2)^2, *2 for alpha+beta in singlet
                k1ao *= 4

        else:
            raise NotImplementedError('LDA triplet')

    elif xctype == 'GGA':
        if singlet:
            def gga_sum_(vmat, ao, wv, mask):
                aow  = numpy.einsum('pi,p->pi', ao[0], wv[0]*.5)
                aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
                tmp = numint._dot_ao_ao(mol, ao[0], aow, nao, weight.size, mask)
                vmat[0] += tmp + tmp.T
                vmat[1:] += rks_grad._gga_grad_sum(mol, ao, wv, mask)

            ao_deriv = 2
            for ao, mask, weight, coords \
                    in ni.block_loop(mol, grids, nao, ao_deriv, max_memory, ni.non0tab):
                rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, mask, 'GGA')
                vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 0, deriv=deriv)[1:]

                vrho, vgamma = vxc[:2]
                frr, frg, fgg = fxc[:3]

                rho1 = ni.eval_rho(mol, ao, dmvo, mask, 'GGA') * 2  # *2 for alpha + beta
                sigma1 = numpy.einsum('xi,xi->i', rho[1:], rho1[1:])
                wv = numpy.empty_like((rho))
                wv[0]  = frr * rho1[0]
                wv[0] += frg * sigma1 * 2
                wv[1:]  = (fgg * sigma1 * 4 + frg * rho1[0] * 2) * rho[1:]
                wv[1:] += vgamma * rho1[1:] * 2
                wv *= weight
                gga_sum_(f1vo, ao, wv, mask)

                if oovv is not None:
                    rho2 = ni.eval_rho(mol, ao, oovv, mask, 'GGA') * 2
                    sigma2 = numpy.einsum('xi,xi->i', rho[1:], rho2[1:])
                    wv[0]  = frr * rho2[0]
                    wv[0] += frg * sigma2 * 2
                    wv[1:]  = (fgg * sigma2 * 4 + frg * rho2[0] * 2) * rho[1:]
                    wv[1:] += vgamma * rho2[1:] * 2
                    wv *= weight
                    gga_sum_(f1oo, ao, wv, mask)
                if with_vxc:
                    wv[0]  = vrho
                    wv[1:] = 2 * vgamma * rho[1:]
                    wv *= weight
                    gga_sum_(v1ao, ao, wv, mask)
                if with_kxc:
                    frrr, frrg, frgg, fggg = kxc
                    r1r1 = rho1[0]**2
                    s1s1 = sigma1**2
                    r1s1 = rho1[0] * sigma1
                    sigma2 = numpy.einsum('xi,xi->i', rho1[1:], rho1[1:])
                    wv[0]  = frrr * r1r1
                    wv[0] += 4 * frrg * r1s1
                    wv[0] += 4 * frgg * s1s1
                    wv[0] += 2 * frg * sigma2
                    wv[1:]  = 2 * frrg * r1r1 * rho[1:]
                    wv[1:] += 8 * frgg * r1s1 * rho[1:]
                    wv[1:] += 4 * frg * rho1[0] * rho1[1:]
                    wv[1:] += 4 * fgg * sigma2 * rho[1:]
                    wv[1:] += 8 * fgg * sigma1 * rho1[1:]
                    wv[1:] += 8 * fggg * s1s1 * rho[1:]
                    wv *= weight
                    gga_sum_(k1ao, ao, wv, mask)
                vxc = fxc = kxc = rho = rho1 = rho2 = sigma1 = sigma2 = None

        else:
            raise NotImplementedError('GGA triplet')

    else:
        raise NotImplementedError('meta-GGA')

    f1vo[1:] *= -1
    if f1oo is not None: f1oo[1:] *= -1
    if v1ao is not None: v1ao[1:] *= -1
    if k1ao is not None: k1ao[1:] *= -1
    return f1vo, f1oo, v1ao, k1ao
예제 #55
0
파일: tdrks.py 프로젝트: chrinide/pyscf
def _contract_xc_kernel(td_grad, xc_code, dmvo, dmoo=None, with_vxc=True,
                        with_kxc=True, singlet=True, max_memory=2000):
    mol = td_grad.mol
    mf = td_grad.base._scf
    grids = mf.grids

    ni = mf._numint
    xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao, nmo = mo_coeff.shape
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = (dmvo + dmvo.T) * .5 # because K_{ia,jb} == K_{ia,jb}

    f1vo = numpy.zeros((4,nao,nao))  # 0th-order, d/dx, d/dy, d/dz
    deriv = 2
    if dmoo is not None:
        f1oo = numpy.zeros((4,nao,nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((4,nao,nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((4,nao,nao))
        deriv = 3
    else:
        k1ao = None

    if xctype == 'LDA':
        ao_deriv = 1
        if singlet:
            for ao, mask, weight, coords \
                    in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
                rho = ni.eval_rho2(mol, ao[0], mo_coeff, mo_occ, mask, 'LDA')
                vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 0, deriv=deriv)[1:]

                wfxc = fxc[0] * weight * 2  # *2 for alpha+beta
                rho1 = ni.eval_rho(mol, ao[0], dmvo, mask, 'LDA')
                aow = numpy.einsum('pi,p,p->pi', ao[0], wfxc, rho1)
                for k in range(4):
                    f1vo[k] += numint._dot_ao_ao(mol, ao[k], aow, mask, shls_slice, ao_loc)
                if dmoo is not None:
                    rho2 = ni.eval_rho(mol, ao[0], dmoo, mask, 'LDA')
                    aow = numpy.einsum('pi,p,p->pi', ao[0], wfxc, rho2)
                    for k in range(4):
                        f1oo[k] += numint._dot_ao_ao(mol, ao[k], aow, mask, shls_slice, ao_loc)
                if with_vxc:
                    aow = numpy.einsum('pi,p,p->pi', ao[0], vxc[0], weight)
                    for k in range(4):
                        v1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, mask, shls_slice, ao_loc)
                if with_kxc:
                    aow = numpy.einsum('pi,p,p,p->pi', ao[0], kxc[0], weight, rho1**2)
                    for k in range(4):
                        k1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, mask, shls_slice, ao_loc)
                vxc = fxc = kxc = aow = rho = rho1 = rho2 = None
            if with_kxc:  # for (rho1*2)^2, *2 for alpha+beta in singlet
                k1ao *= 4

        else:
            raise NotImplementedError('LDA triplet')

    elif xctype == 'GGA':
        if singlet:
            def gga_sum_(vmat, ao, wv, mask):
                aow  = numpy.einsum('pi,p->pi', ao[0], wv[0])
                aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
                tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
                vmat[0] += tmp + tmp.T
                rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)
            ao_deriv = 2
            for ao, mask, weight, coords \
                    in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
                rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, mask, 'GGA')
                vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 0, deriv=deriv)[1:]

                rho1 = ni.eval_rho(mol, ao, dmvo, mask, 'GGA') * 2  # *2 for alpha + beta
                wv = numint._rks_gga_wv1(rho, rho1, vxc, fxc, weight)
                gga_sum_(f1vo, ao, wv, mask)

                if dmoo is not None:
                    rho2 = ni.eval_rho(mol, ao, dmoo, mask, 'GGA') * 2
                    wv = numint._rks_gga_wv1(rho, rho2, vxc, fxc, weight)
                    gga_sum_(f1oo, ao, wv, mask)
                if with_vxc:
                    wv = numint._rks_gga_wv0(rho, vxc, weight)
                    gga_sum_(v1ao, ao, wv, mask)
                if with_kxc:
                    wv = numint._rks_gga_wv2(rho, rho1, fxc, kxc, weight)
                    gga_sum_(k1ao, ao, wv, mask)
                vxc = fxc = kxc = rho = rho1 = None

        else:
            raise NotImplementedError('GGA triplet')

    else:
        raise NotImplementedError('meta-GGA')

    f1vo[1:] *= -1
    if f1oo is not None: f1oo[1:] *= -1
    if v1ao is not None: v1ao[1:] *= -1
    if k1ao is not None: k1ao[1:] *= -1
    return f1vo, f1oo, v1ao, k1ao
예제 #56
0
파일: rks_nmr.py 프로젝트: matk86/pyscf
def _get_vxc_giao(ni, mol, grids, x_id, c_id, dm,
                  max_memory=2000, verbose=None):
    natocc, natorb = scipy.linalg.eigh(dm)
    nao = dm.shape[0]

    xctype = numint._xc_type(x_id, c_id)
    ngrids = len(grids.weights)
    BLKSIZE = numint.BLKSIZE
    blksize = min(int(max_memory/6*1e6/12/nao/BLKSIZE)*BLKSIZE, ngrids)

    vmat = numpy.zeros((3,nao,nao))
    if xctype == 'LDA':
        buf = numpy.empty((4,blksize,nao))
        for ip0, ip1 in numint.prange(0, ngrids, blksize):
            coords = grids.coords[ip0:ip1]
            weight = grids.weights[ip0:ip1]
            non0tab = ni.non0tab[ip0//BLKSIZE:]
            ao = ni.eval_ao(mol, coords, deriv=0, non0tab=non0tab, out=buf)
            rho = ni.eval_rho2(mol, ao, natorb, natocc, non0tab, xctype)
            vxc = ni.eval_xc(x_id, c_id, rho, 0, deriv=1)[1]
            vrho = vxc[0]
            aow = numpy.einsum('pi,p->pi', ao, weight*vrho)
            giao = mol.eval_gto('GTOval_ig_sph', coords, comp=3,
                                non0tab=non0tab, out=buf[1:])
            vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], nao, ip1-ip0, non0tab)
            vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], nao, ip1-ip0, non0tab)
            vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], nao, ip1-ip0, non0tab)
            rho = vxc = vrho = aow = giao = None
    elif xctype == 'GGA':
        buf = numpy.empty((10,blksize,nao))
        XX, XY, XZ = 0, 1, 2
        YX, YY, YZ = 3, 4, 5
        ZX, ZY, ZZ = 6, 7, 8
        for ip0, ip1 in numint.prange(0, ngrids, blksize):
            coords = grids.coords[ip0:ip1]
            weight = grids.weights[ip0:ip1]
            non0tab = ni.non0tab[ip0//BLKSIZE:]
            ao = ni.eval_ao(mol, coords, deriv=1, non0tab=non0tab, out=buf)
            rho = ni.eval_rho2(mol, ao, natorb, natocc, non0tab, xctype)
            vxc = ni.eval_xc(x_id, c_id, rho, 0, deriv=1)[1]
            vrho, vsigma = vxc[:2]
            wv = numpy.empty_like(rho)
            wv[0]  = weight * vrho
            wv[1:] = rho[1:] * (weight * vsigma * 2)

            aow = numpy.einsum('npi,np->pi', ao[:4], wv)
            giao = mol.eval_gto('GTOval_ig_sph', coords, 3,
                                non0tab=non0tab, out=buf[4:])
            vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], nao, ip1-ip0, non0tab)
            vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], nao, ip1-ip0, non0tab)
            vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], nao, ip1-ip0, non0tab)

            giao = mol.eval_gto('GTOval_ipig_sph', coords, 9,
                                non0tab=non0tab, out=buf[1:])
            aow = numpy.einsum('pi,p->pi', giao[XX], wv[1])
            aow+= numpy.einsum('pi,p->pi', giao[YX], wv[2])
            aow+= numpy.einsum('pi,p->pi', giao[ZX], wv[3])
            vmat[0] += numint._dot_ao_ao(mol, ao[0], aow, nao, ip1-ip0, non0tab)
            aow = numpy.einsum('pi,p->pi', giao[XY], wv[1])
            aow+= numpy.einsum('pi,p->pi', giao[YY], wv[2])
            aow+= numpy.einsum('pi,p->pi', giao[ZY], wv[3])
            vmat[1] += numint._dot_ao_ao(mol, ao[0], aow, nao, ip1-ip0, non0tab)
            aow = numpy.einsum('pi,p->pi', giao[XZ], wv[1])
            aow+= numpy.einsum('pi,p->pi', giao[YZ], wv[2])
            aow+= numpy.einsum('pi,p->pi', giao[ZZ], wv[3])
            vmat[2] += numint._dot_ao_ao(mol, ao[0], aow, nao, ip1-ip0, non0tab)
            rho = vxc = vrho = vsigma = wv = aow = giao = None
    else:
        raise NotImplementedError('meta-GGA')

    return vmat - vmat.transpose(0,2,1)