Exemple #1
0
def get_hcore(cell, kpts):
    '''Part of the nuclear gradients of core Hamiltonian'''
    h1 = np.asarray(cell.pbc_intor('int1e_ipkin', kpts=kpts))
    dtype = h1.dtype
    if cell._pseudo:
        SI = cell.get_SI()
        nao = cell.nao_nr()
        Gv = cell.Gv
        natom = cell.natm
        coords = cell.get_uniform_grids()
        ngrids, nkpts = len(coords), len(kpts)
        vlocG = get_vlocG(cell)
        vpplocG = -np.einsum('ij,ij->j', SI, vlocG)
        vpplocG[0] = np.sum(get_alphas(cell))
        vpplocR = tools.ifft(vpplocG, cell.mesh).real
        fakemol = _make_fakemol()
        ptr = mole.PTR_ENV_START
        for kn, kpt in enumerate(kpts):
            aos = eval_ao_kpts(cell, coords, kpt, deriv=1)[0]
            vloc = np.einsum('agi,g,gj->aij', aos[1:].conj(), vpplocR, aos[0])
            expir = np.exp(-1j * np.dot(coords, kpt))
            aokG = np.asarray([
                tools.fftk(np.asarray(ao.T, order='C'), cell.mesh, expir).T
                for ao in aos
            ])
            Gk = Gv + kpt
            G_rad = lib.norm(Gk, axis=1)
            vnl = np.zeros(vloc.shape, dtype=np.complex128)
            for ia in range(natom):
                symb = cell.atom_symbol(ia)
                if symb not in cell._pseudo:
                    continue
                pp = cell._pseudo[symb]
                for l, proj in enumerate(pp[5:]):
                    rl, nl, hl = proj
                    if nl > 0:
                        hl = np.asarray(hl)
                        fakemol._bas[0, mole.ANG_OF] = l
                        fakemol._env[ptr + 3] = .5 * rl**2
                        fakemol._env[ptr + 4] = rl**(l + 1.5) * np.pi**1.25
                        pYlm_part = fakemol.eval_gto('GTOval', Gk)
                        pYlm = np.empty((nl, l * 2 + 1, ngrids))
                        for k in range(nl):
                            qkl = _qli(G_rad * rl, l, k)
                            pYlm[k] = pYlm_part.T * qkl
                        SPG_lmi = np.einsum('g,nmg->nmg', SI[ia].conj(), pYlm)
                        SPG_lm_aoG = np.einsum('nmg,agp->anmp', SPG_lmi, aokG)
                        tmp = np.einsum('ij,ajmp->aimp', hl, SPG_lm_aoG[1:])
                        vnl += np.einsum('aimp,imq->apq', tmp.conj(),
                                         SPG_lm_aoG[0])
            vnl *= (1. / ngrids**2)
            if dtype == np.float64:
                h1[kn, :] += vloc.real + vnl.real
            else:
                h1[kn, :] += vloc + vnl
    else:
        raise NotImplementedError
    return h1
Exemple #2
0
def hcore_generator(mf, cell=None, kpts=None):
    if cell is None: cell = mf.cell
    if kpts is None: kpts = mf.kpts
    h1 = get_hcore(cell, kpts)
    dtype = h1.dtype

    aoslices = cell.aoslice_by_atom()
    SI=cell.get_SI()  ##[natom ,grid]
    mesh = cell.mesh
    Gv = cell.Gv    ##[grid, 3]
    ngrids = len(Gv)
    coords = cell.get_uniform_grids()
    vlocG = get_vlocG(cell)  ###[natom, grid]
    ptr = mole.PTR_ENV_START
    def hcore_deriv(atm_id):
        shl0, shl1, p0, p1 = aoslices[atm_id]
        symb = cell.atom_symbol(atm_id)
        fakemol = _make_fakemol()
        vloc_g = 1j * np.einsum('ga,g->ag', Gv, SI[atm_id]*vlocG[atm_id])
        nkpts, nao = h1.shape[0], h1.shape[2]
        hcore = np.zeros([3,nkpts,nao,nao], dtype=h1.dtype)
        for kn, kpt in enumerate(kpts):

            ao = eval_ao_kpts(cell, coords, kpt)[0]
            rho = np.einsum('gi,gj->gij',ao.conj(),ao)
            for ax in range(3):
                vloc_R = tools.ifft(vloc_g[ax], mesh).real
                vloc = np.einsum('gij,g->ij', rho, vloc_R)
                hcore[ax,kn] += vloc
            rho = None
            aokG= tools.fftk(np.asarray(ao.T, order='C'),
                              mesh, np.exp(-1j*np.dot(coords, kpt))).T
            ao = None
            Gk = Gv + kpt
            G_rad = lib.norm(Gk, axis=1)
            if symb not in cell._pseudo: continue
            pp = cell._pseudo[symb]
            for l, proj in enumerate(pp[5:]):
                rl, nl, hl = proj
                if nl >0:
                    hl = np.asarray(hl)
                    fakemol._bas[0,mole.ANG_OF] = l
                    fakemol._env[ptr+3] = .5*rl**2
                    fakemol._env[ptr+4] = rl**(l+1.5)*np.pi**1.25
                    pYlm_part = fakemol.eval_gto('GTOval', Gk)
                    pYlm = np.empty((nl,l*2+1,ngrids))
                    for k in range(nl):
                        qkl = _qli(G_rad*rl, l, k)
                        pYlm[k] = pYlm_part.T * qkl
                    SPG_lmi = np.einsum('g,nmg->nmg', SI[atm_id].conj(), pYlm)
                    SPG_lm_aoG = np.einsum('nmg,gp->nmp', SPG_lmi, aokG)
                    SPG_lmi_G = 1j * np.einsum('nmg, ga->anmg', SPG_lmi, Gv)
                    SPG_lm_G_aoG = np.einsum('anmg, gp->anmp', SPG_lmi_G, aokG)
                    tmp_1 = np.einsum('ij,ajmp->aimp', hl, SPG_lm_G_aoG)
                    tmp_2 = np.einsum('ij,jmp->imp', hl, SPG_lm_aoG)
                    vppnl = np.einsum('imp,aimq->apq', SPG_lm_aoG.conj(), tmp_1) + np.einsum('aimp,imq->apq',   SPG_lm_G_aoG.conj(), tmp_2)
                    vppnl *=(1./ngrids**2)
                    if dtype==np.float64:
                        hcore[:,kn] += vppnl.real
                    else:
                        hcore[:,kn] += vppnl
            hcore[:,kn,p0:p1] -= h1[kn,:,p0:p1]
            hcore[:,kn,:,p0:p1] -= h1[kn,:,p0:p1].transpose(0,2,1).conj()
        return hcore
    return hcore_deriv