Exemple #1
0
    def test_eval_rho(self):
        cell, grids = make_grids([61]*3)
        numpy.random.seed(10)
        nao = 10
        ngrids = 500
        dm = numpy.random.random((nao,nao))
        dm = dm + dm.T
        ao =(numpy.random.random((10,ngrids,nao)) +
             numpy.random.random((10,ngrids,nao))*1j)
        ao = ao.transpose(0,2,1).copy().transpose(0,2,1)

        rho0 = numpy.zeros((6,ngrids), dtype=numpy.complex128)
        rho0[0] = numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[0].conj())
        rho0[1] = numpy.einsum('pi,ij,pj->p', ao[1], dm, ao[0].conj()) + numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[1].conj())
        rho0[2] = numpy.einsum('pi,ij,pj->p', ao[2], dm, ao[0].conj()) + numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[2].conj())
        rho0[3] = numpy.einsum('pi,ij,pj->p', ao[3], dm, ao[0].conj()) + numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[3].conj())
        rho0[4]+= numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[4].conj()) + numpy.einsum('pi,ij,pj->p', ao[4], dm, ao[0].conj())
        rho0[4]+= numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[7].conj()) + numpy.einsum('pi,ij,pj->p', ao[7], dm, ao[0].conj())
        rho0[4]+= numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[9].conj()) + numpy.einsum('pi,ij,pj->p', ao[9], dm, ao[0].conj())
        rho0[5]+= numpy.einsum('pi,ij,pj->p', ao[1], dm, ao[1].conj())
        rho0[5]+= numpy.einsum('pi,ij,pj->p', ao[2], dm, ao[2].conj())
        rho0[5]+= numpy.einsum('pi,ij,pj->p', ao[3], dm, ao[3].conj())
        rho0[4]+= rho0[5]*2
        rho0[5] *= .5

        rho1 = numint.eval_rho(cell, ao, dm, xctype='MGGA')
        self.assertTrue(numpy.allclose(rho0, rho1))

        rho1 = numint.eval_rho(cell, ao, dm, xctype='GGA')
        self.assertAlmostEqual(finger(rho1), -255.45150185669198, 7)

        rho1 = numint.eval_rho(cell, ao[0], dm, xctype='LDA')
        self.assertAlmostEqual(finger(rho1), -17.198879910245601, 7)
Exemple #2
0
    def test_eval_rho(self):
        cell, grids = make_grids(30)
        numpy.random.seed(10)
        nao = 10
        ngrids = 500
        dm = numpy.random.random((nao,nao))
        dm = dm + dm.T
        ao =(numpy.random.random((10,ngrids,nao)) +
             numpy.random.random((10,ngrids,nao))*1j)

        rho0 = numpy.zeros((6,ngrids), dtype=numpy.complex128)
        rho0[0] = numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[0].conj())
        rho0[1] = numpy.einsum('pi,ij,pj->p', ao[1], dm, ao[0].conj()) + numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[1].conj())
        rho0[2] = numpy.einsum('pi,ij,pj->p', ao[2], dm, ao[0].conj()) + numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[2].conj())
        rho0[3] = numpy.einsum('pi,ij,pj->p', ao[3], dm, ao[0].conj()) + numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[3].conj())
        rho0[4]+= numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[4].conj()) + numpy.einsum('pi,ij,pj->p', ao[4], dm, ao[0].conj())
        rho0[4]+= numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[7].conj()) + numpy.einsum('pi,ij,pj->p', ao[7], dm, ao[0].conj())
        rho0[4]+= numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[9].conj()) + numpy.einsum('pi,ij,pj->p', ao[9], dm, ao[0].conj())
        rho0[5]+= numpy.einsum('pi,ij,pj->p', ao[1], dm, ao[1].conj())
        rho0[5]+= numpy.einsum('pi,ij,pj->p', ao[2], dm, ao[2].conj())
        rho0[5]+= numpy.einsum('pi,ij,pj->p', ao[3], dm, ao[3].conj())
        rho0[4]+= rho0[5]*2
        rho0[5] *= .5

        rho1 = numint.eval_rho(cell, ao, dm, xctype='MGGA')
        self.assertTrue(numpy.allclose(rho0, rho1))
Exemple #3
0
def get_j_kpts(mydf, dm_kpts, hermi=1, kpts=np.zeros((1, 3)), kpts_band=None):
    '''Get the Coulomb (J) AO matrix at sampled k-points.

    Args:
        dm_kpts : (nkpts, nao, nao) ndarray or a list of (nkpts,nao,nao) ndarray
            Density matrix at each k-point.  If a list of k-point DMs, eg,
            UHF alpha and beta DM, the alpha and beta DMs are contracted
            separately.
        kpts : (nkpts, 3) ndarray

    Kwargs:
        kpts_band : (3,) ndarray or (*,3) ndarray
            A list of arbitrary "band" k-points at which to evalute the matrix.

    Returns:
        vj : (nkpts, nao, nao) ndarray
        or list of vj if the input dm_kpts is a list of DMs
    '''
    cell = mydf.cell
    mesh = mydf.mesh
    low_dim_ft_type = mydf.low_dim_ft_type

    dm_kpts = lib.asarray(dm_kpts, order='C')
    dms = _format_dms(dm_kpts, kpts)
    nset, nkpts, nao = dms.shape[:3]

    coulG = tools.get_coulG(cell, mesh=mesh, low_dim_ft_type=low_dim_ft_type)
    ngrids = len(coulG)

    vR = rhoR = np.zeros((nset, ngrids))
    for ao_ks_etc, p0, p1 in mydf.aoR_loop(mydf.grids, kpts):
        ao_ks = ao_ks_etc[0]
        for k, ao in enumerate(ao_ks):
            for i in range(nset):
                rhoR[i, p0:p1] += numint.eval_rho(cell, ao, dms[i, k])
        ao = ao_ks = None

    for i in range(nset):
        rhoR[i] *= 1. / nkpts
        rhoG = tools.fft(rhoR[i], mesh)
        vG = coulG * rhoG
        vR[i] = tools.ifft(vG, mesh).real

    kpts_band, input_band = _format_kpts_band(kpts_band, kpts), kpts_band
    nband = len(kpts_band)
    weight = cell.vol / ngrids
    vR *= weight
    if gamma_point(kpts_band):
        vj_kpts = np.zeros((nset, nband, nao, nao))
    else:
        vj_kpts = np.zeros((nset, nband, nao, nao), dtype=np.complex128)
    for ao_ks_etc, p0, p1 in mydf.aoR_loop(mydf.grids, kpts_band):
        ao_ks = ao_ks_etc[0]
        for k, ao in enumerate(ao_ks):
            for i in range(nset):
                vj_kpts[i, k] += lib.dot(ao.T.conj() * vR[i, p0:p1], ao)

    return _format_jks(vj_kpts, dm_kpts, input_band, kpts)
Exemple #4
0
def get_vjR(cell, dm, aoR):
    coulG = tools.get_coulG(cell)

    rhoR = numint.eval_rho(cell, aoR, dm)
    rhoG = tools.fft(rhoR, cell.gs)

    vG = coulG * rhoG
    vR = tools.ifft(vG, cell.gs)
    if rhoR.dtype == np.double:
        vR = vR.real
    return vR
Exemple #5
0
def get_j_kpts(mydf, dm_kpts, hermi=1, kpts=np.zeros((1,3)), kpt_band=None):
    '''Get the Coulomb (J) AO matrix at sampled k-points.

    Args:
        dm_kpts : (nkpts, nao, nao) ndarray or a list of (nkpts,nao,nao) ndarray
            Density matrix at each k-point.  If a list of k-point DMs, eg,
            UHF alpha and beta DM, the alpha and beta DMs are contracted
            separately.
        kpts : (nkpts, 3) ndarray

    Kwargs:
        kpt_band : (3,) ndarray
            An arbitrary "band" k-point at which to evalute the matrix.

    Returns:
        vj : (nkpts, nao, nao) ndarray
        or list of vj if the input dm_kpts is a list of DMs
    '''
    cell = mydf.cell
    gs = mydf.gs

    dm_kpts = lib.asarray(dm_kpts, order='C')
    dms = _format_dms(dm_kpts, kpts)
    nset, nkpts, nao = dms.shape[:3]

    coulG = tools.get_coulG(cell, gs=gs)
    ngs = len(coulG)

    vR = rhoR = np.zeros((nset,ngs))
    for k, aoR in mydf.aoR_loop(gs, kpts):
        for i in range(nset):
            rhoR[i] += numint.eval_rho(cell, aoR, dms[i,k])
    for i in range(nset):
        rhoR[i] *= 1./nkpts
        rhoG = tools.fft(rhoR[i], gs)
        vG = coulG * rhoG
        vR[i] = tools.ifft(vG, gs).real

    if kpt_band is not None:
        for k, aoR_kband in mydf.aoR_loop(gs, kpts, kpt_band):
            pass
        vj_kpts = [cell.vol/ngs * lib.dot(aoR_kband.T.conj()*vR[i], aoR_kband)
                   for i in range(nset)]
        if dm_kpts.ndim == 3:  # One set of dm_kpts for KRHF
            vj_kpts = vj_kpts[0]
        return lib.asarray(vj_kpts)
    else:
        vj_kpts = []
        weight = cell.vol / ngs
        for k, aoR in mydf.aoR_loop(gs, kpts):
            for i in range(nset):
                vj_kpts.append(weight * lib.dot(aoR.T.conj()*vR[i], aoR))
        vj_kpts = lib.asarray(vj_kpts).reshape(nkpts,nset,nao,nao)
        return vj_kpts.transpose(1,0,2,3).reshape(dm_kpts.shape)
Exemple #6
0
def get_vjR(cell, dm, aoR):
    coulG = tools.get_coulG(cell)

    rhoR = numint.eval_rho(cell, aoR, dm)
    rhoG = tools.fft(rhoR, cell.gs)

    vG = coulG*rhoG
    vR = tools.ifft(vG, cell.gs)
    if rhoR.dtype == np.double:
        vR = vR.real
    return vR
Exemple #7
0
def get_j_kpts(mydf, dm_kpts, hermi=1, kpts=np.zeros((1, 3)), kpt_band=None):
    """Get the Coulomb (J) AO matrix at sampled k-points.

    Args:
        dm_kpts : (nkpts, nao, nao) ndarray or a list of (nkpts,nao,nao) ndarray
            Density matrix at each k-point.  If a list of k-point DMs, eg,
            UHF alpha and beta DM, the alpha and beta DMs are contracted
            separately.
        kpts : (nkpts, 3) ndarray

    Kwargs:
        kpt_band : (3,) ndarray
            An arbitrary "band" k-point at which to evalute the matrix.

    Returns:
        vj : (nkpts, nao, nao) ndarray
        or list of vj if the input dm_kpts is a list of DMs
    """
    cell = mydf.cell
    gs = mydf.gs

    dm_kpts = lib.asarray(dm_kpts, order="C")
    dms = _format_dms(dm_kpts, kpts)
    nset, nkpts, nao = dms.shape[:3]

    coulG = tools.get_coulG(cell, gs=gs)
    ngs = len(coulG)

    vR = rhoR = np.zeros((nset, ngs))
    for k, aoR in mydf.aoR_loop(gs, kpts):
        for i in range(nset):
            rhoR[i] += numint.eval_rho(cell, aoR, dms[i, k])
    for i in range(nset):
        rhoR[i] *= 1.0 / nkpts
        rhoG = tools.fft(rhoR[i], gs)
        vG = coulG * rhoG
        vR[i] = tools.ifft(vG, gs).real

    if kpt_band is not None:
        for k, aoR_kband in mydf.aoR_loop(gs, kpts, kpt_band):
            pass
        vj_kpts = [cell.vol / ngs * lib.dot(aoR_kband.T.conj() * vR[i], aoR_kband) for i in range(nset)]
        if dm_kpts.ndim == 3:  # One set of dm_kpts for KRHF
            vj_kpts = vj_kpts[0]
        return lib.asarray(vj_kpts)
    else:
        vj_kpts = []
        weight = cell.vol / ngs
        for k, aoR in mydf.aoR_loop(gs, kpts):
            for i in range(nset):
                vj_kpts.append(weight * lib.dot(aoR.T.conj() * vR[i], aoR))
        vj_kpts = lib.asarray(vj_kpts).reshape(nkpts, nset, nao, nao)
        return vj_kpts.transpose(1, 0, 2, 3).reshape(dm_kpts.shape)
Exemple #8
0
def density(cell, outfile, dm, nx=60, ny=60, nz=60, moN=-1, fileFormat="cube"):
    '''Calculates electron density and write out in CHGCAR format.

    Args:
        cell : Cell
            pbc Cell
        outfile : str
            Name of Cube file to be written.
        dm : ndarray
            Density matrix of molecule.

    Kwargs:
        nx : int
            Number of grid point divisions in x direction.
            Note this is function of the molecule's size; a larger molecule
            will have a coarser representation than a smaller one for the
            same value.
        ny : int
            Number of grid point divisions in y direction.
        nz : int
            Number of grid point divisions in z direction.

    Returns:
        No return value. This function outputs a VASP chgcarlike file
        (with phase if desired)...it can be opened in VESTA or VMD or
        many other softwares
    
    Examples:

        >>> # generates the first MO from the list of mo_coefficents 
        >>> from pyscf.pbc import gto, scf
        >>> from pyscf.tools import chgcar
        >>> cell = gto.M(atom='H 0 0 0; H 0 0 1', a=numpy.eye(3)*3)
        >>> mf = scf.RHF(cell).run()
        >>> chgcar.density(cell, 'h2.CHGCAR', mf.make_rdm1())

    '''
    assert (isinstance(cell, pbcgto.Cell))

    cc = CHGCAR(cell, nx=nx, ny=ny, nz=nz)

    coords = cc.get_coords()
    ngrids = cc.get_ngrids()
    blksize = min(8000, ngrids)
    rho = numpy.empty(ngrids)
    for ip0, ip1 in lib.prange(0, ngrids, blksize):
        ao = numint.eval_ao(cell, coords[ip0:ip1])
        rho[ip0:ip1] = numint.eval_rho(cell, ao, dm)
    rho = rho.reshape(nx, ny, nz)

    cc.write(rho, outfile)
Exemple #9
0
def get_j_kpts(mydf, dm_kpts, hermi=1, kpts=np.zeros((1, 3)), kpts_band=None):
    '''Get the Coulomb (J) AO matrix at sampled k-points.

    Args:
        dm_kpts : (nkpts, nao, nao) ndarray or a list of (nkpts,nao,nao) ndarray
            Density matrix at each k-point.  If a list of k-point DMs, eg,
            UHF alpha and beta DM, the alpha and beta DMs are contracted
            separately.
        kpts : (nkpts, 3) ndarray

    Kwargs:
        kpts_band : (3,) ndarray or (*,3) ndarray
            A list of arbitrary "band" k-points at which to evalute the matrix.

    Returns:
        vj : (nkpts, nao, nao) ndarray
        or list of vj if the input dm_kpts is a list of DMs
    '''
    cell = mydf.cell
    gs = mydf.gs

    dm_kpts = lib.asarray(dm_kpts, order='C')
    dms = _format_dms(dm_kpts, kpts)
    nset, nkpts, nao = dms.shape[:3]

    coulG = tools.get_coulG(cell, gs=gs)
    ngs = len(coulG)

    vR = rhoR = np.zeros((nset, ngs))
    for k, aoR in mydf.aoR_loop(gs, kpts):
        for i in range(nset):
            rhoR[i] += numint.eval_rho(cell, aoR, dms[i, k])
    for i in range(nset):
        rhoR[i] *= 1. / nkpts
        rhoG = tools.fft(rhoR[i], gs)
        vG = coulG * rhoG
        vR[i] = tools.ifft(vG, gs).real

    kpts_band, single_kpt_band = _format_kpts_band(kpts_band, kpts)
    nband = len(kpts_band)
    vj_kpts = []
    weight = cell.vol / ngs
    if gamma_point(kpts_band):
        vj_kpts = np.empty((nset, nband, nao, nao))
    else:
        vj_kpts = np.empty((nset, nband, nao, nao), dtype=np.complex128)
    for k, aoR in mydf.aoR_loop(gs, kpts_band):
        for i in range(nset):
            vj_kpts[i, k] = weight * lib.dot(aoR.T.conj() * vR[i], aoR)

    return _format_jks(vj_kpts, dm_kpts, kpts_band, kpts, single_kpt_band)
Exemple #10
0
def get_vjR_kpts(cell, dm_kpts, aoR_kpts):
    nkpts = len(aoR_kpts)
    coulG = tools.get_coulG(cell)

    rhoR = 0
    for k in range(nkpts):
        rhoR += 1. / nkpts * numint.eval_rho(cell, aoR_kpts[k], dm_kpts[k])
    rhoG = tools.fft(rhoR, cell.gs)

    vG = coulG * rhoG
    vR = tools.ifft(vG, cell.gs)
    if rhoR.dtype == np.double:
        vR = vR.real
    return vR
Exemple #11
0
def get_vjR_kpts(cell, dm_kpts, aoR_kpts):
    nkpts = len(aoR_kpts)
    coulG = tools.get_coulG(cell)

    rhoR = 0
    for k in range(nkpts):
        rhoR += 1./nkpts*numint.eval_rho(cell, aoR_kpts[k], dm_kpts[k])
    rhoG = tools.fft(rhoR, cell.gs)

    vG = coulG*rhoG
    vR = tools.ifft(vG, cell.gs)
    if rhoR.dtype == np.double:
        vR = vR.real
    return vR
Exemple #12
0
def get_j_kpts(mydf, dm_kpts, hermi=1, kpts=numpy.zeros((1,3)),
               kpts_band=None):
    mydf = _sync_mydf(mydf)
    cell = mydf.cell
    mesh = mydf.mesh

    dm_kpts = lib.asarray(dm_kpts, order='C')
    dms = _format_dms(dm_kpts, kpts)
    nset, nkpts, nao = dms.shape[:3]

    coulG = tools.get_coulG(cell, mesh=mesh)
    ngrids = len(coulG)

    vR = rhoR = numpy.zeros((nset,ngrids))
    for ao_ks_etc, p0, p1 in mydf.mpi_aoR_loop(mydf.grids, kpts):
        ao_ks = ao_ks_etc[0]
        for k, ao in enumerate(ao_ks):
            for i in range(nset):
                rhoR[i,p0:p1] += numint.eval_rho(cell, ao, dms[i,k])
        ao = ao_ks = None

    rhoR = mpi.allreduce(rhoR)
    for i in range(nset):
        rhoR[i] *= 1./nkpts
        rhoG = tools.fft(rhoR[i], mesh)
        vG = coulG * rhoG
        vR[i] = tools.ifft(vG, mesh).real

    kpts_band, input_band = _format_kpts_band(kpts_band, kpts), kpts_band
    nband = len(kpts_band)
    weight = cell.vol / ngrids
    vR *= weight
    if gamma_point(kpts_band):
        vj_kpts = numpy.zeros((nset,nband,nao,nao))
    else:
        vj_kpts = numpy.zeros((nset,nband,nao,nao), dtype=numpy.complex128)
    for ao_ks_etc, p0, p1 in mydf.mpi_aoR_loop(mydf.grids, kpts_band):
        ao_ks = ao_ks_etc[0]
        for k, ao in enumerate(ao_ks):
            for i in range(nset):
                vj_kpts[i,k] += lib.dot(ao.T.conj()*vR[i,p0:p1], ao)

    vj_kpts = mpi.reduce(vj_kpts)
    if gamma_point(kpts_band):
        vj_kpts = vj_kpts.real
    return _format_jks(vj_kpts, dm_kpts, input_band, kpts)
Exemple #13
0
    def test_eval_rho(self):
        cell, grids = make_grids(30)
        numpy.random.seed(10)
        nao = 10
        ngrids = 500
        dm = numpy.random.random((nao, nao))
        dm = dm + dm.T
        ao = (numpy.random.random((10, ngrids, nao)) + numpy.random.random(
            (10, ngrids, nao)) * 1j)

        rho0 = numpy.zeros((6, ngrids), dtype=numpy.complex128)
        rho0[0] = numpy.einsum('pi,ij,pj->p', ao[0], dm, ao[0].conj())
        rho0[1] = numpy.einsum('pi,ij,pj->p', ao[1], dm,
                               ao[0].conj()) + numpy.einsum(
                                   'pi,ij,pj->p', ao[0], dm, ao[1].conj())
        rho0[2] = numpy.einsum('pi,ij,pj->p', ao[2], dm,
                               ao[0].conj()) + numpy.einsum(
                                   'pi,ij,pj->p', ao[0], dm, ao[2].conj())
        rho0[3] = numpy.einsum('pi,ij,pj->p', ao[3], dm,
                               ao[0].conj()) + numpy.einsum(
                                   'pi,ij,pj->p', ao[0], dm, ao[3].conj())
        rho0[4] += numpy.einsum('pi,ij,pj->p', ao[0], dm,
                                ao[4].conj()) + numpy.einsum(
                                    'pi,ij,pj->p', ao[4], dm, ao[0].conj())
        rho0[4] += numpy.einsum('pi,ij,pj->p', ao[0], dm,
                                ao[7].conj()) + numpy.einsum(
                                    'pi,ij,pj->p', ao[7], dm, ao[0].conj())
        rho0[4] += numpy.einsum('pi,ij,pj->p', ao[0], dm,
                                ao[9].conj()) + numpy.einsum(
                                    'pi,ij,pj->p', ao[9], dm, ao[0].conj())
        rho0[5] += numpy.einsum('pi,ij,pj->p', ao[1], dm, ao[1].conj())
        rho0[5] += numpy.einsum('pi,ij,pj->p', ao[2], dm, ao[2].conj())
        rho0[5] += numpy.einsum('pi,ij,pj->p', ao[3], dm, ao[3].conj())
        rho0[4] += rho0[5] * 2
        rho0[5] *= .5

        rho1 = numint.eval_rho(cell, ao, dm, xctype='MGGA')
        self.assertTrue(numpy.allclose(rho0, rho1))
Exemple #14
0
def test_components(pseudo=None):
    # The molecular calculation
    mol = gto.Mole()
    mol.unit = 'B'
    L = 60
    mol.atom.extend([['He', (L/2.,L/2.,L/2.)], ])
    mol.basis = 'sto-3g'
    mol.build()

    m = rks.RKS(mol)
    m.xc = 'LDA,VWN_RPA'
    print(m.scf()) # -2.90705411168
    dm = m.make_rdm1()

    # The periodic calculation
    cell = pbcgto.Cell()
    cell.unit = 'B'
    cell.a = np.diag([L,L,L])
    cell.gs = np.array([80,80,80])

    cell.atom = mol.atom
    cell.basis = mol.basis
    cell.pseudo = pseudo
    cell.build()

    # These should match reasonably well (roughly with accuracy of normalization)
    print "Kinetic energy" 
    tao = pbchf.get_t(cell) 
    tao2 = mol.intor_symmetric('cint1e_kin_sph') 
    print np.dot(np.ravel(tao), np.ravel(dm))  # 2.82793077196
    print np.dot(np.ravel(tao2), np.ravel(dm)) # 2.82352636524
    
    print "Overlap"
    sao = pbchf.get_ovlp(cell)
    print np.dot(np.ravel(sao), np.ravel(dm)) # 1.99981725342
    print np.dot(np.ravel(m.get_ovlp()), np.ravel(dm)) # 2.0

    # The next two entries should *not* match, since G=0 component is removed
    print "Coulomb (G!=0)"
    jao = pbchf.get_j(cell, dm)
    print np.dot(np.ravel(dm),np.ravel(jao))  # 4.03425518427
    print np.dot(np.ravel(dm),np.ravel(m.get_j(dm))) # 4.22285177049

    # The next two entries should *not* match, since G=0 component is removed
    print "Nuc-el (G!=0)"
    if cell.pseudo:
        vppao = pbchf.get_pp(cell)
        print np.dot(np.ravel(dm), np.ravel(vppao)) 
    else:
        neao = pbchf.get_nuc(cell)
        print np.dot(np.ravel(dm), np.ravel(neao))  # -6.50203360062
    vne = mol.intor_symmetric('cint1e_nuc_sph') 
    print np.dot(np.ravel(dm), np.ravel(vne))   # -6.68702326551

    print "Normalization" 
    coords = gen_uniform_grids(cell)
    aoR = eval_ao(cell, coords)
    rhoR = eval_rho(cell, aoR, dm)
    print cell.vol/len(rhoR)*np.sum(rhoR) # 1.99981725342 (should be 2.0)
    
    print "(Hartree + vne) * DM"
    print np.dot(np.ravel(dm),np.ravel(m.get_j(dm)))+np.dot(np.ravel(dm), np.ravel(vne))
    if cell.pseudo:
        print np.einsum("ij,ij", dm, vppao + jao + pbchf.get_jvloc_G0(cell))
    else:
        print np.einsum("ij,ij", dm, neao + jao)

    ew_cut = (40,40,40)
    ew_eta = 0.05
    for ew_eta in [0.1, 0.5, 1.]:
        ew = pbchf.ewald(cell, ew_eta, ew_cut)
        print "Ewald (eta, energy)", ew_eta, ew # should be same for all eta

    print "Ewald divergent terms summation", ew

    # These two should now match if the box is reasonably big to
    # remove images, and ngs is big.
    print "Total coulomb (analytic) ", 
    print (.5*np.dot(np.ravel(dm), np.ravel(m.get_j(dm))) 
            + np.dot(np.ravel(dm), np.ravel(vne)) ) # -4.57559738004
    if not cell.pseudo:
        print "Total coulomb (fft coul + ewald)", 
        print np.einsum("ij,ij", dm, neao + .5*jao) + ew # -4.57948259115

    # Exc
    cell.ew_eta, cell.ew_cut = ew_eta, ew_cut
    mf = pbcdft.RKS(cell)
    mf.xc = 'LDA,VWN_RPA'

    rks.get_veff(mf, cell, dm)
    print "Exc", mf._exc # -1.05967570089
Exemple #15
0
def test_components(pseudo=None):
    # The molecular calculation
    mol = gto.Mole()
    mol.unit = 'B'
    L = 60
    mol.atom.extend([
        ['He', (L / 2., L / 2., L / 2.)],
    ])
    mol.basis = 'sto-3g'
    mol.build()

    m = rks.RKS(mol)
    m.xc = 'LDA,VWN_RPA'
    print(m.scf())  # -2.90705411168
    dm = m.make_rdm1()

    # The periodic calculation
    cell = pbcgto.Cell()
    cell.unit = 'B'
    cell.a = np.diag([L, L, L])
    cell.gs = np.array([80, 80, 80])

    cell.atom = mol.atom
    cell.basis = mol.basis
    cell.pseudo = pseudo
    cell.build()

    # These should match reasonably well (roughly with accuracy of normalization)
    print "Kinetic energy"
    tao = pbchf.get_t(cell)
    tao2 = mol.intor_symmetric('cint1e_kin_sph')
    print np.dot(np.ravel(tao), np.ravel(dm))  # 2.82793077196
    print np.dot(np.ravel(tao2), np.ravel(dm))  # 2.82352636524

    print "Overlap"
    sao = pbchf.get_ovlp(cell)
    print np.dot(np.ravel(sao), np.ravel(dm))  # 1.99981725342
    print np.dot(np.ravel(m.get_ovlp()), np.ravel(dm))  # 2.0

    # The next two entries should *not* match, since G=0 component is removed
    print "Coulomb (G!=0)"
    jao = pbchf.get_j(cell, dm)
    print np.dot(np.ravel(dm), np.ravel(jao))  # 4.03425518427
    print np.dot(np.ravel(dm), np.ravel(m.get_j(dm)))  # 4.22285177049

    # The next two entries should *not* match, since G=0 component is removed
    print "Nuc-el (G!=0)"
    if cell.pseudo:
        vppao = pbchf.get_pp(cell)
        print np.dot(np.ravel(dm), np.ravel(vppao))
    else:
        neao = pbchf.get_nuc(cell)
        print np.dot(np.ravel(dm), np.ravel(neao))  # -6.50203360062
    vne = mol.intor_symmetric('cint1e_nuc_sph')
    print np.dot(np.ravel(dm), np.ravel(vne))  # -6.68702326551

    print "Normalization"
    coords = gen_uniform_grids(cell)
    aoR = eval_ao(cell, coords)
    rhoR = eval_rho(cell, aoR, dm)
    print cell.vol / len(rhoR) * np.sum(rhoR)  # 1.99981725342 (should be 2.0)

    print "(Hartree + vne) * DM"
    print np.dot(np.ravel(dm), np.ravel(m.get_j(dm))) + np.dot(
        np.ravel(dm), np.ravel(vne))
    if cell.pseudo:
        print np.einsum("ij,ij", dm, vppao + jao + pbchf.get_jvloc_G0(cell))
    else:
        print np.einsum("ij,ij", dm, neao + jao)

    ew_cut = (40, 40, 40)
    ew_eta = 0.05
    for ew_eta in [0.1, 0.5, 1.]:
        ew = pbchf.ewald(cell, ew_eta, ew_cut)
        print "Ewald (eta, energy)", ew_eta, ew  # should be same for all eta

    print "Ewald divergent terms summation", ew

    # These two should now match if the box is reasonably big to
    # remove images, and ngs is big.
    print "Total coulomb (analytic) ",
    print(.5 * np.dot(np.ravel(dm), np.ravel(m.get_j(dm))) +
          np.dot(np.ravel(dm), np.ravel(vne)))  # -4.57559738004
    if not cell.pseudo:
        print "Total coulomb (fft coul + ewald)",
        print np.einsum("ij,ij", dm, neao + .5 * jao) + ew  # -4.57948259115

    # Exc
    cell.ew_eta, cell.ew_cut = ew_eta, ew_cut
    mf = pbcdft.RKS(cell)
    mf.xc = 'LDA,VWN_RPA'

    rks.get_veff(mf, cell, dm)
    print "Exc", mf._exc  # -1.05967570089
Exemple #16
0
def _eval_rhoG(mydf, dm_kpts, hermi=1, kpts=numpy.zeros((1, 3)), deriv=0):
    log = lib.logger.Logger(mydf.stdout, mydf.verbose)
    cell = mydf.cell

    dm_kpts = lib.asarray(dm_kpts, order='C')
    dms = _format_dms(dm_kpts, kpts)
    nset, nkpts, nao = dms.shape[:3]

    tasks = getattr(mydf, 'tasks', None)
    if tasks is None:
        mydf.tasks = tasks = multi_grids_tasks(cell, log)
        log.debug('Multigrid ntasks %s', len(tasks))

    assert (deriv <= 2)
    if abs(dms - dms.transpose(0, 1, 3, 2).conj()).max() < 1e-9:

        def dot_bra(bra, aodm):
            rho = numpy.einsum('pi,pi->p', bra.real, aodm.real)
            if aodm.dtype == numpy.complex:
                rho += numpy.einsum('pi,pi->p', bra.imag, aodm.imag)
            return rho

        if deriv == 0:
            xctype = 'LDA'
            rhodim = 1

            def make_rho(ao_l, ao_h, dm_lh, dm_hl):
                c0 = lib.dot(ao_l, dm_lh)
                rho = dot_bra(ao_h, c0)
                return rho * 2

        elif deriv == 1:
            xctype = 'GGA'
            rhodim = 4

            def make_rho(ao_l, ao_h, dm_lh, dm_hl):
                ngrids = ao_l[0].shape[0]
                rho = numpy.empty((4, ngrids))
                c0 = lib.dot(ao_l[0], dm_lh)
                rho[0] = dot_bra(ao_h[0], c0)
                for i in range(1, 4):
                    rho[i] = dot_bra(ao_h[i], c0)
                c0 = lib.dot(ao_h[0], dm_hl)
                for i in range(1, 4):
                    rho[i] += dot_bra(ao_l[i], c0)
                return rho * 2  # *2 for dm_lh+dm_hl.T

        elif deriv == 2:
            xctype = 'MGGA'
            rhodim = 6

            def make_rho(ao_l, ao_h, dm_lh, dm_hl):
                ngrids = ao_l[0].shape[0]
                rho = numpy.empty((6, ngrids))
                c = [lib.dot(ao_l[i], dm_lh) for i in range(4)]
                rho[0] = dot_bra(ao_h[0], c[0])
                rho[5] = 0
                for i in range(1, 4):
                    rho[i] = dot_bra(ao_h[i], c[0])
                    rho[i] += dot_bra(ao_h[0], c[i])
                    rho[5] += dot_bra(ao_h[i], c[i]) * 2
                XX, YY, ZZ = 4, 7, 9
                ao2 = ao_h[XX] + ao_h[YY] + ao_h[ZZ]
                rho[4] = dot_bra(ao2, c[0])
                ao2 = lib.dot(ao_l[XX] + ao_l[YY] + ao_l[ZZ], dm_lh)
                rho[4] += dot_bra(ao2, ao_h[0])
                rho[4] += rho[5] * 2
                rho[5] *= .5
                return rho * 2  # *2 for dm_lh+dm_hl.T
    else:
        raise NotImplementedError('Non-hermitian density matrices')

    ni = mydf._numint
    nx, ny, nz = cell.mesh
    rhoG = numpy.zeros((nset * rhodim, nx, ny, nz), dtype=numpy.complex)
    for grids_high, grids_low in tasks:
        cell_high = grids_high.cell
        mesh = grids_high.mesh
        coords_idx = grids_high.coords_idx
        ngrids0 = numpy.prod(mesh)
        ngrids1 = grids_high.coords.shape[0]
        log.debug('mesh %s, ngrids %s/%s', mesh, ngrids1, ngrids0)

        idx_h = grids_high.ao_idx
        dms_hh = numpy.asarray(dms[:, :, idx_h[:, None], idx_h], order='C')
        if grids_low is not None:
            idx_l = grids_low.ao_idx
            dms_hl = numpy.asarray(dms[:, :, idx_h[:, None], idx_l], order='C')
            dms_lh = numpy.asarray(dms[:, :, idx_l[:, None], idx_h], order='C')

        rho = numpy.zeros((nset, rhodim, ngrids1))
        if grids_low is None:
            for ao_h_etc, p0, p1 in mydf.aoR_loop(grids_high, kpts, deriv):
                ao_h, mask = ao_h_etc[0], ao_h_etc[2]
                for k in range(nkpts):
                    for i in range(nset):
                        rho_sub = numint.eval_rho(cell_high, ao_h[k],
                                                  dms_hh[i, k], mask, xctype,
                                                  hermi)
                        rho[i, :, p0:p1] += rho_sub.real
                ao_h = ao_h_etc = None
        else:
            for ao_h_etc, ao_l_etc in zip(
                    mydf.aoR_loop(grids_high, kpts, deriv),
                    mydf.aoR_loop(grids_low, kpts, deriv)):
                p0, p1 = ao_h_etc[1:3]
                ao_h, mask = ao_h_etc[0][0], ao_h_etc[0][2]
                ao_l = ao_l_etc[0][0]
                for k in range(nkpts):
                    for i in range(nset):
                        rho_sub = numint.eval_rho(cell_high, ao_h[k],
                                                  dms_hh[i, k], mask, xctype,
                                                  hermi)
                        rho[i, :, p0:p1] += rho_sub.real
                        rho_sub = make_rho(ao_l[k], ao_h[k], dms_lh[i, k],
                                           dms_hl[i, k])
                        rho[i, :, p0:p1] += rho_sub.real
                ao_h = ao_l = ao_h_etc = ao_l_etc = None

        rho *= 1. / nkpts
        rhoR = numpy.zeros((nset * rhodim, ngrids0))
        rhoR[:, coords_idx] = rho.reshape(nset * rhodim, ngrids1)
        gx = numpy.fft.fftfreq(mesh[0], 1. / mesh[0]).astype(int)
        gy = numpy.fft.fftfreq(mesh[1], 1. / mesh[1]).astype(int)
        gz = numpy.fft.fftfreq(mesh[2], 1. / mesh[2]).astype(int)
        rho_freq = tools.fft(rhoR, mesh) * cell.vol / ngrids0
        for i in range(nset * rhodim):
            rhoG[i, gx[:, None, None], gy[:, None],
                 gz] += rho_freq[i].reshape(mesh)

    return rhoG.reshape(nset, rhodim, ngrids0)