Esempio n. 1
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
Esempio n. 2
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
Esempio n. 3
0
def compute_nad_terms(mol0, mol1, dm0, dm1, emb_args):
    """Compute the non-additive potentials and energies.

    Parameters
    ----------
    mol : PySCF gto.M
        Molecule objects.
    emb_args : dict
        Information of embedding calculation.

    """
    # Create supersystem
    newatom = '\n'.join([mol0.atom, mol1.atom])
    system = gto.M(atom=newatom, basis=mol0.basis)
    # Construct grid for complex
    grids = gen_grid.Grids(system)
    grids.level = 4
    grids.build()
    ao_mol0 = eval_ao(mol0, grids.coords, deriv=0)
    ao_mol1 = eval_ao(mol1, grids.coords, deriv=0)
    # Make Complex DM
    ao_both = eval_ao(system, grids.coords, deriv=0)
    nao_mol0 = mol0.nao_nr()
    nao_mol1 = mol1.nao_nr()
    nao_tot = nao_mol0 + nao_mol1
    dm_both = np.zeros((nao_tot, nao_tot))

    dm_both[:nao_mol0, :nao_mol0] = dm0
    dm_both[nao_mol0:, nao_mol0:] = dm1

    # Compute DFT non-additive potential and energies
    rho_mol0 = eval_rho(mol0, ao_mol0, dm0, xctype='LDA')
    rho_mol1 = eval_rho(mol1, ao_mol1, dm1, xctype='LDA')
    rho_both = eval_rho(system, ao_both, dm_both, xctype='LDA')
    # Compute all densities on a grid
    xc_code = emb_args["xc_code"]
    t_code = emb_args["t_code"]
    excs, vxcs = get_dft_grid_stuff(xc_code, rho_both, rho_mol0, rho_mol1)
    ets, vts = get_dft_grid_stuff(t_code, rho_both, rho_mol0, rho_mol1)
    vxc_emb = vxcs[0][0] - vxcs[1][0]
    vt_emb = vts[0][0] - vts[1][0]
    # Energy functionals:
    exc_nad = get_nad_energy(grids, excs, rho_both, rho_mol0, rho_mol1)
    et_nad = get_nad_energy(grids, ets, rho_both, rho_mol0, rho_mol1)

    v_nad_xc = eval_mat(mol0,
                        ao_mol0,
                        grids.weights,
                        rho_mol0,
                        vxc_emb,
                        xctype='LDA')
    v_nad_t = eval_mat(mol0,
                       ao_mol0,
                       grids.weights,
                       rho_mol0,
                       vt_emb,
                       xctype='LDA')
    return (exc_nad, et_nad, v_nad_xc, v_nad_t)
Esempio n. 4
0
def density_cut(mol, dm, nx=80, ny=80, z_value=0):
    from scipy.constants import physical_constants
    from pyscf import lib
    from pyscf.dft import gen_grid, numint

    nz = 1

    coord = mol.atom_coords()
    box = np.max(coord,axis=0) - np.min(coord,axis=0) + 6
    boxorig = np.min(coord,axis=0) - 3
    xs = np.arange(nx) * (box[0]/nx)
    ys = np.arange(ny) * (box[1]/ny)
    zs = np.array([z_value]) 
    #zs = np.arange(nz) * (box[2]/nz)
    coords = lib.cartesian_prod([xs,ys,zs])
    coords = np.asarray(coords, order='C') - (-boxorig)

    ngrids = nx * ny * nz
    blksize = min(8000, ngrids)
    rho = np.empty(ngrids)
    ao = None
    for ip0, ip1 in gen_grid.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, coords[ip0:ip1], out=ao)
        rho[ip0:ip1] = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape(nx,ny)

    # needed for conversion as x,y are in bohr for some reason
    a0 = physical_constants["Bohr radius"][0]

    return rho.T, (xs + boxorig[0]) * a0, (ys + boxorig[1]) * a0
Esempio n. 5
0
def density_cut_old(mol, dm, nx=80, ny=80):
    """ Calculates the density in the x-y plane on a grid"""
    
    from pyscf import lib
    from pyscf.dft import gen_grid, numint

    coords = mol.atom_coords()
    coords[:, 2] = 0 # set z-coordinate 0

    lower = np.min(coords, axis=0)
    upper = np.max(coords, axis=0)
    grid_x, grid_y = np.meshgrid(
        np.linspace(lower[0], upper[0], nx),
        np.linspace(lower[1], upper[1], ny)
    )
    

    grid = np.array(
        [grid_x.flatten(), 
        grid_y[:].flatten(), 
        np.zeros(grid_x.shape).flatten()]
    ).T

    ao = numint.eval_ao(mol, grid)
    rho = numint.eval_rho(mol, ao, dm)
    return rho.reshape(nx, ny)
Esempio n. 6
0
    def test_mcol_mgga_vxc_mat(self):
        nao = mol.nao
        n2c = nao * 2
        ao_loc = mol.ao_loc
        numpy.random.seed(12)
        dm = numpy.random.rand(n2c, n2c) * .01
        dm += numpy.eye(n2c)
        dm = dm + dm.T
        ngrids = 8
        coords = numpy.random.rand(ngrids, 3)
        weight = numpy.random.rand(ngrids)

        ao = numint.eval_ao(mol, coords, deriv=1)
        rho = numint2c.eval_rho(mol,
                                ao,
                                dm,
                                xctype='MGGA',
                                hermi=1,
                                with_lapl=False)
        vxc = numpy.random.rand(4, 5, ngrids)
        mask = numpy.ones((100, mol.nbas), dtype=numpy.uint8)
        shls_slice = (0, mol.nbas)
        v0 = numint2c._mcol_mgga_vxc_mat(mol, ao, weight, rho, vxc.copy(),
                                         mask, shls_slice, ao_loc, 0)
        v1 = numint2c._mcol_mgga_vxc_mat(mol, ao, weight, rho, vxc.copy(),
                                         mask, shls_slice, ao_loc, 1)
        v1 = v1 + v1.conj().T
        self.assertAlmostEqual(abs(v0 - v1).max(), 0, 14)
        self.assertAlmostEqual(lib.fp(v0),
                               0.45641500123185696 - 0.11533144122332428j, 12)
Esempio n. 7
0
    def test_mcol_gga_vxc_mat(self):
        nao = mol.nao
        n2c = nao * 2
        ao_loc = mol.ao_loc
        numpy.random.seed(12)
        dm = numpy.random.rand(n2c, n2c) * .01
        dm += numpy.eye(n2c)
        dm = dm + dm.T
        ngrids = 8
        coords = numpy.random.rand(ngrids, 3)
        weight = numpy.random.rand(ngrids)

        ao = numint.eval_ao(mol, coords, deriv=1)
        rho = numint2c.eval_rho(mol, ao, dm, xctype='GGA', hermi=1)
        vxc = numpy.random.rand(4, 4, ngrids)
        mask = numpy.ones((100, mol.nbas), dtype=numpy.uint8)
        shls_slice = (0, mol.nbas)
        v0 = numint2c._mcol_gga_vxc_mat(mol, ao, weight, rho, vxc.copy(), mask,
                                        shls_slice, ao_loc, 0)
        v1 = numint2c._mcol_gga_vxc_mat(mol, ao, weight, rho, vxc.copy(), mask,
                                        shls_slice, ao_loc, 1)
        v1 = v1 + v1.conj().T
        self.assertAlmostEqual(abs(v0 - v1).max(), 0, 14)
        self.assertAlmostEqual(lib.fp(v0),
                               -0.889763561992794 - 0.013552640219244905j, 12)
Esempio n. 8
0
def fo(mf, fod, s=0):
    """docstring for fo"""
    ksocc = np.where(mf.mo_occ[s] > 1e-6)[0][-1] + 1
    #print("ksocc: {0}".format(ksocc))
    #print np.where(self.mf.mo_occ[self.s] > 1e-6)
    mol = mf.mol
    ao = numint.eval_ao(mol, [fod])

    # first index is nfod, second is orbital
    psi = ao.dot(mf.mo_coeff[s][:, :ksocc])
    #print psi.shape
    #sys.exit()

    # get total spin density at point self.fpos
    sd = np.sqrt(np.sum(psi**2, axis=1))
    #print sd.shape
    #print sd
    #sys.exit()
    # get value of each ks-orbital at point fpos
    _ks = mf.mo_coeff[s][:, 0:ksocc]
    #print _ks.shape
    #sys.exit()
    #print np.array_str(_ks, precision=4, max_line_width=120)

    _R = np.zeros((ksocc), dtype=_ks.dtype)
    _R = psi[0, :] / sd

    #_R = np.reshape(psi/sd, (ksocc))
    fo = np.matmul(_R, _ks.transpose())

    #print fo

    return fo
Esempio n. 9
0
def density(mol, outfile, dm, nx=80, ny=80, nz=80):
    coord = mol.atom_coords()
    box = numpy.max(coord, axis=0) - numpy.min(coord, axis=0) + 4
    boxorig = numpy.min(coord, axis=0) - 2
    xs = numpy.arange(nx) * (box[0] / nx)
    ys = numpy.arange(ny) * (box[1] / ny)
    zs = numpy.arange(nz) * (box[2] / nz)
    coords = lib.cartesian_prod([xs, ys, zs])
    coords = numpy.asarray(coords, order="C") - (-boxorig)

    nao = mol.nao_nr()
    ngrids = nx * ny * nz
    blksize = min(200, ngrids)
    rho = numpy.empty(ngrids)
    for ip0, ip1 in gen_grid.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, coords[ip0:ip1])
        rho[ip0:ip1] = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape(nx, ny, nz)

    with open(outfile, "w") as f:
        f.write("Density in real space\n")
        f.write("Comment line\n")
        f.write("%5d" % mol.natm)
        f.write(" %14.8f %14.8f %14.8f\n" % tuple(boxorig.tolist()))
        f.write("%5d %14.8f %14.8f %14.8f\n" % (nx, xs[1], 0, 0))
        f.write("%5d %14.8f %14.8f %14.8f\n" % (ny, 0, ys[1], 0))
        f.write("%5d %14.8f %14.8f %14.8f\n" % (nz, 0, 0, zs[1]))
        for ia in range(mol.natm):
            chg = mol.atom_charge(ia)
            f.write("%5d %f" % (chg, chg))
            f.write(" %14.8f %14.8f %14.8f\n" % tuple(coord[ia]))
        fmt = " %14.8e" * nz + "\n"
        for ix in range(nx):
            for iy in range(ny):
                f.write(fmt % tuple(rho[ix, iy].tolist()))
Esempio n. 10
0
def density(mol, outfile, dm, nx=80, ny=80, nz=80):
    coord = [mol.atom_coord(ia) for ia in range(mol.natm)]
    box = numpy.max(coord,axis=0) - numpy.min(coord,axis=0) + 4
    boxorig = numpy.min(coord,axis=0) - 2
    xs = numpy.arange(nx) * (box[0]/nx)
    ys = numpy.arange(ny) * (box[1]/ny)
    zs = numpy.arange(nz) * (box[2]/nz)
    coords = numpy.vstack(numpy.meshgrid(xs,ys,zs)).reshape(3,-1).T
    coords = numpy.asarray(coords, order='C') - (-boxorig)

    nao = mol.nao_nr()
    ngrids = nx * ny * nz
    blksize = min(200, ngrids)
    rho = numpy.empty(ngrids)
    for ip0, ip1 in numint.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, coords[ip0:ip1])
        rho[ip0:ip1] = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape(nx,ny,nz)

    with open(outfile, 'w') as f:
        f.write('Density in real space\n')
        f.write('Comment line\n')
        f.write('%5d' % mol.natm)
        f.write(' %14.8f %14.8f %14.8f\n' % tuple(boxorig.tolist()))
        f.write('%5d %14.8f %14.8f %14.8f\n' % (nx, xs[1], 0, 0))
        f.write('%5d %14.8f %14.8f %14.8f\n' % (ny, 0, ys[1], 0))
        f.write('%5d %14.8f %14.8f %14.8f\n' % (nz, 0, 0, zs[1]))
        for ia in range(mol.natm):
            chg = mol.atom_charge(ia)
            f.write('%5d %f' % (chg, chg))
            f.write(' %14.8f %14.8f %14.8f\n' % tuple(mol.atom_coord(ia).tolist()))
        fmt = ' %14.8f' * nz + '\n'
        for ix in range(nx):
            for iy in range(ny):
                f.write(fmt % tuple(rho[ix,iy].tolist()))
Esempio n. 11
0
def MO(mol,
       C,
       orbital,
       outfile='orbital',
       nx=80,
       ny=80,
       nz=80,
       resolution=None,
       save=True):
    """Calculates electron density and write out in cube format.

    Args:
        mol : Mole
            Molecule to calculate the electron density for.
        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. Conflicts to keyword resolution.
        ny : int
            Number of grid point divisions in y direction.
        nz : int
            Number of grid point divisions in z direction.
        resolution: float
            Resolution of the mesh grid in the cube box. If resolution is
            given in the input, the input nx/ny/nz have no effects.  The value
            of nx/ny/nz will be determined by the resolution and the cube box
            size.
    """

    cc = Cube(mol, nx, ny, nz, resolution)

    # Compute density on the .cube grid
    coords = cc.get_coords()
    ngrids = cc.get_ngrids()
    #blksize = min(8000, ngrids)
    blksize = ngrids
    rho = np.empty(ngrids)
    for ip0, ip1 in lib.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, coords[ip0:ip1])
    MO = np.array([i @ C[:, orbital] for i in ao])
    MO = MO.reshape((nx, ny, nz))
    if save:
        cc.write(MO,
                 outfile,
                 comment='Orbital ' + str(orbital) +
                 ' in real space (e/Bohr^3)')
    x = (coords[:, 0].min(), coords[:, 0].max(), nx)
    y = (coords[:, 1].min(), coords[:, 1].max(), ny)
    z = (coords[:, 2].min(), coords[:, 2].max(), nz)
    return MO, np.array([y, x, z])
Esempio n. 12
0
def make_h1_fc(mol, mo_coeff, mo_occ, atmlst):
    coords = mol.atom_coords()
    ao = numint.eval_ao(mol, coords)
    mo = ao.dot(mo_coeff)
    orbo = mo[:,mo_occ> 0]
    orbv = mo[:,mo_occ==0]
    fac = 8*numpy.pi/3 *.5  # *.5 due to s = 1/2 * pauli-matrix
    h1 = []
    for ia in atmlst:
        h1.append(fac * numpy.einsum('p,i->pi', orbv[ia], orbo[ia]))
    return h1
Esempio n. 13
0
def make_h1_fc(mol, mo_coeff, mo_occ, atmlst):
    coords = mol.atom_coords()
    ao = numint.eval_ao(mol, coords)
    mo = ao.dot(mo_coeff)
    orbo = mo[:, mo_occ > 0]
    orbv = mo[:, mo_occ == 0]
    fac = 8 * numpy.pi / 3 * .5  # *.5 due to s = 1/2 * pauli-matrix
    h1 = []
    for ia in atmlst:
        h1.append(fac * numpy.einsum('p,i->pi', orbv[ia], orbo[ia]))
    return h1
Esempio n. 14
0
def dia(gobj, mol, dm0, hfc_nuc=None, verbose=None):
    log = logger.new_logger(gobj, verbose)
    if hfc_nuc is None:
        hfc_nuc = range(mol.natm)
    if isinstance(dm0, numpy.ndarray) and dm0.ndim == 2:  # RHF DM
        return numpy.zeros((3, 3))

    dma, dmb = dm0
    spindm = dma - dmb
    effspin = mol.spin * .5

    mu_B = 1  # lib.param.BOHR_MAGNETON
    mu_N = lib.param.PROTON_MASS * mu_B
    fac = lib.param.ALPHA / 2 / effspin
    fac *= lib.param.G_ELECTRON * mu_B * mu_N

    coords = mol.atom_coords()
    ao = numint.eval_ao(mol, coords)

    nao = dma.shape[0]
    dia = []
    for i, atm_id in enumerate(hfc_nuc):
        Z = mole._charge(mol.atom_symbol(atm_id))
        nuc_spin, g_nuc = parameters.ISOTOPE[Z][1:3]
        # g factor of other isotopes can be found in file nuclear_g_factor.dat
        gyromag = 1e-6 / (
            2 * numpy.pi) * parameters.g_factor_to_gyromagnetic_ratio(g_nuc)
        log.info(
            'Atom %d %s  nuc-spin %g  nuc-g-factor %g  gyromagnetic ratio %g (in MHz)',
            atm_id, mol.atom_symbol(atm_id), nuc_spin, g_nuc, gyromag)
        mol.set_rinv_origin(mol.atom_coord(atm_id))
        # a01p[mu,sigma] the imaginary part of integral <vec{r}/r^3 cross p>
        # mu = gN * I * mu_N
        a01p = mol.intor('int1e_sa01sp', 12).reshape(3, 4, nao, nao)
        h11 = a01p[:, 1:] - a01p[:, 1:].transpose(0, 1, 3, 2)
        e11 = numpy.einsum('xyij,ji->xy', h11, spindm)
        e11 *= fac * gyromag
        # e11 includes fermi-contact and spin-dipolar contriutions and a rank-2 contact
        # term.  We ignore the contribution of rank-2 contact term, view it as part of
        # SD contribution.  See also TCA, 73, 173
        fermi_contact = (
            4 * numpy.pi / 3 * fac * gyromag *
            numpy.einsum('i,j,ji', ao[atm_id], ao[atm_id], spindm))
        dip = e11 - numpy.eye(3) * fermi_contact
        log.info('FC %s', fermi_contact)
        if gobj.verbose >= logger.INFO:
            _write(gobj, dip, 'SD')
        dia.append(e11)
    return numpy.asarray(dia)
Esempio n. 15
0
    def densdiff(x0):
        #print ig_fod
        #print(s)
        _x = np.reshape(x0, (-1, 3))
        lfo = fo(mf, _x, s)

        mol = mf.mol
        ao1 = numint.eval_ao(mol, ongrid.coords)
        _fo = ao1.dot(lfo)

        dens_fo = np.conjugate(_fo) * _fo * ongrid.weights

        ##print dens_fo.shape
        ##print dens.shape

        diff = np.linalg.norm(dens_fo - dens)

        return diff
Esempio n. 16
0
 def fock_hook(self, mf, dm=None, h1e=None, vhf=None, cycle=-1, **envs):
     # cycle > 0 means it is doing scf iteration
     if 0 <= cycle < self.start_cycle:
         return 0
     if self.grids.coords is None:
         self.grids.build()
     if self.ao_value is None:
         self.ao_value = numint.eval_ao(mf.mol, self.grids.coords, deriv=0)
     tic = (time.clock(), time.time())
     rho_diff = numint.eval_rho(mf.mol, self.ao_value, dm - self.dm_t)
     v_p = numint.eval_mat(mf.mol, self.ao_value, self.grids.weights,
                           rho_diff, rho_diff)
     # cycle < 0 means it is just checking, we only print here
     if cycle < 0 and mf.verbose >= 4:
         diff_norm = np.sum(np.abs(rho_diff) * self.grids.weights)
         logger.info(mf, f"  Density Penalty: |diff| = {diff_norm}")
         logger.timer(mf, "dens_pnt", *tic)
     return self.strength * v_p
Esempio n. 17
0
def orbital(mol, outfile, coeff, nx=80, ny=80, nz=80, resolution=RESOLUTION):
    """Calculate orbital value on real space grid and write out in cube format.

    Args:
        mol : Mole
            Molecule to calculate the electron density for.
        outfile : str
            Name of Cube file to be written.
        coeff : 1D array
            coeff coefficient.

    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. Conflicts to keyword resolution.
        ny : int
            Number of grid point divisions in y direction.
        nz : int
            Number of grid point divisions in z direction.
        resolution: float
            Resolution of the mesh grid in the cube box. If resolution is
            given in the input, the input nx/ny/nz have no effects.  The value
            of nx/ny/nz will be determined by the resolution and the cube box
            size.
    """
    cc = Cube(mol, nx, ny, nz, resolution)

    # Compute density on the .cube grid
    coords = cc.get_coords()
    ngrids = cc.get_ngrids()
    blksize = min(8000, ngrids)
    orb_on_grid = numpy.empty(ngrids)
    for ip0, ip1 in lib.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, coords[ip0:ip1])
        orb_on_grid[ip0:ip1] = numpy.dot(ao, coeff)
    orb_on_grid = orb_on_grid.reshape(cc.nx, cc.ny, cc.nz)

    # Write out orbital to the .cube file
    cc.write(orb_on_grid,
             outfile,
             comment='Orbital value in real space (1/Bohr^3)')
    return orb_on_grid
Esempio n. 18
0
def make_h1_fc(mol, mo_coeff, mo_occ, atmlst):
    coords = mol.atom_coords()
    ao = numint.eval_ao(mol, coords)
    moa = ao.dot(mo_coeff[0])
    mob = ao.dot(mo_coeff[1])
    orboa = moa[:,mo_occ[0]> 0]
    orbva = moa[:,mo_occ[0]==0]
    orbob = mob[:,mo_occ[1]> 0]
    orbvb = mob[:,mo_occ[1]==0]
    h1aa = []
    h1ab = []
    h1ba = []
    h1bb = []
    fac = 8*numpy.pi/3 *.5  # *.5 due to s = 1/2 * pauli-matrix
    h1aa = fac * numpy.einsum('zp,zi->zpi', orbva[atmlst], orboa[atmlst])
    h1ab = fac * numpy.einsum('zp,zi->zpi', orbva[atmlst], orbob[atmlst])
    h1ba = fac * numpy.einsum('zp,zi->zpi', orbvb[atmlst], orboa[atmlst])
    h1bb =-fac * numpy.einsum('zp,zi->zpi', orbvb[atmlst], orbob[atmlst])
    return h1aa, h1ab, h1ba, h1bb
Esempio n. 19
0
def make_h1_fc(mol, mo_coeff, mo_occ, atmlst):
    coords = mol.atom_coords()
    ao = numint.eval_ao(mol, coords)
    moa = ao.dot(mo_coeff[0])
    mob = ao.dot(mo_coeff[1])
    orboa = moa[:, mo_occ[0] > 0]
    orbva = moa[:, mo_occ[0] == 0]
    orbob = mob[:, mo_occ[1] > 0]
    orbvb = mob[:, mo_occ[1] == 0]
    h1aa = []
    h1ab = []
    h1ba = []
    h1bb = []
    fac = 8 * numpy.pi / 3 * .5  # *.5 due to s = 1/2 * pauli-matrix
    h1aa = fac * numpy.einsum('zp,zi->zpi', orbva[atmlst], orboa[atmlst])
    h1ab = fac * numpy.einsum('zp,zi->zpi', orbva[atmlst], orbob[atmlst])
    h1ba = fac * numpy.einsum('zp,zi->zpi', orbvb[atmlst], orboa[atmlst])
    h1bb = -fac * numpy.einsum('zp,zi->zpi', orbvb[atmlst], orbob[atmlst])
    return h1aa, h1ab, h1ba, h1bb
Esempio n. 20
0
def get_com_fast(mf, p):
    ''' calculates COMS in mo_coeff space '''
    ao1 = numint.eval_ao(mf.mol, mf.grids.coords)
    l_com = []
    for s in range(p.nspin):
        s_com = []
        occ = len(p.pycom_orb[s][mf.mo_occ[s] == 1])
        for i in range(occ):
            phi = ao1.dot(p.pycom_orb[s][:, i])
            dens = numpy.conjugate(phi) * phi * mf.grids.weights
            # COM
            x = numpy.sum(dens * mf.grids.coords[:, 0]) * Bohr
            y = numpy.sum(dens * mf.grids.coords[:, 1]) * Bohr
            z = numpy.sum(dens * mf.grids.coords[:, 2]) * Bohr
            print("{} COM: {} {} {}".format(p.pycom_loc, x, y, z))
            s_com.append([x, y, z])
        l_com.append(s_com)
    p.l_com = l_com
    return p
Esempio n. 21
0
def AO(mol,
       C,
       outfile='AO_dir/AOs',
       nx=80,
       ny=80,
       nz=80,
       resolution=None,
       save=True):
    counter = 1
    if not os.path.exists(outfile):
        os.makedirs(outfile)
    else:
        exists = True
        while exists:
            cache = outfile + '_' + str(counter)
            exists = os.path.exists(cache)
            counter += 1
        outfile = cache
        os.makedirs(cache)
    cc = Cube(mol, nx, ny, nz, resolution)
    # Compute density on the .cube grid
    coords = cc.get_coords()
    ngrids = cc.get_ngrids()
    #blksize = min(8000, ngrids)
    blksize = ngrids
    rho = np.empty(ngrids)
    for ip0, ip1 in lib.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, coords[ip0:ip1])
    x = (coords[:, 0].min(), coords[:, 0].max(), nx)
    y = (coords[:, 1].min(), coords[:, 1].max(), ny)
    z = (coords[:, 2].min(), coords[:, 2].max(), nz)
    if save:
        np.savetxt(outfile + '/AOs', ao)
        np.savetxt(outfile + '/C', C)

        np.savetxt(outfile + '/coords', np.array([y, x, z]))
        f = open(outfile + '/geom_basis', 'w')
        f.write(str(mol.atom) + '_')
        f.write(str(mol.basis))
        f.close()
        #cc.write(np.array([]),outfile + '_geom',comment = 'Geometry')
    return ao, np.array([y, x, z])
Esempio n. 22
0
  def test_cube_c(self):
    """ Compute the density and store into a cube file  """

    # Initialize the class cube_c
    cc = Cube(mol, nx=20, ny=20, nz=20)
    
    # Compute density on the .cube grid
    coords = cc.get_coords()
    ngrids = cc.get_ngrids()
    blksize = min(8000, ngrids)
    rho = np.empty(ngrids)
    ao = None
    dm = mf.make_rdm1()
    for ip0, ip1 in gen_grid.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, coords[ip0:ip1], out=ao)
        rho[ip0:ip1] = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape(cc.nx,cc.ny,cc.nz)
    
    # Write out density to the .cube file
    cc.write(rho, "h2o_den_cube_c.cube", comment='Electron density in real space (e/Bohr^3)')
Esempio n. 23
0
def make_h1_fc(mol, mo_coeff, mo_occ, atmlst):
    coords = mol.atom_coords()
    ao = numint.eval_ao(mol, coords)
    moa = ao.dot(mo_coeff[0])
    mob = ao.dot(mo_coeff[1])
    orboa = moa[:,mo_occ[0]> 0]
    orbva = moa[:,mo_occ[0]==0]
    orbob = mob[:,mo_occ[1]> 0]
    orbvb = mob[:,mo_occ[1]==0]
    h1aa = []
    h1ab = []
    h1ba = []
    h1bb = []
    fac = 8*numpy.pi/3 *.5  # *.5 due to s = 1/2 * pauli-matrix
    for ia in atmlst:
        h1aa.append(fac * numpy.einsum('p,i->pi', orbva[ia], orboa[ia]))
        h1ab.append(fac * numpy.einsum('p,i->pi', orbva[ia], orbob[ia]))
        h1ba.append(fac * numpy.einsum('p,i->pi', orbvb[ia], orboa[ia]))
        h1bb.append(fac * numpy.einsum('p,i->pi', orbvb[ia], orbob[ia]))
    return h1aa, h1ab, h1ba, h1bb
Esempio n. 24
0
    def test_mcol_lda_vxc_mat(self):
        nao = mol.nao
        n2c = nao * 2
        ao_loc = mol.ao_loc
        numpy.random.seed(12)
        dm = numpy.random.rand(n2c, n2c) * .001
        dm += numpy.eye(n2c)
        dm = dm + dm.T
        ngrids = 8
        coords = numpy.random.rand(ngrids, 3)
        weight = numpy.random.rand(ngrids)

        ao = numint.eval_ao(mol, coords, deriv=0)
        rho = numint2c.eval_rho(mol, ao, dm, xctype='LDA', hermi=1)
        ni = numint2c.NumInt2C()
        vxc = ni.eval_xc_eff('lda,', rho, deriv=1)[1]
        mask = numpy.ones((100, mol.nbas), dtype=numpy.uint8)
        shls_slice = (0, mol.nbas)
        v0 = numint2c._ncol_lda_vxc_mat(mol, ao, weight, rho, vxc.copy(), mask,
                                        shls_slice, ao_loc, 0)
        v1 = numint2c._ncol_lda_vxc_mat(mol, ao, weight, rho, vxc.copy(), mask,
                                        shls_slice, ao_loc, 1)
        v1 = v1 + v1.conj().T
        ref = v0
        self.assertAlmostEqual(abs(v0 - v1).max(), 0, 14)
        self.assertAlmostEqual(lib.fp(v0), 0.19683067215390423, 12)

        ni.collinear = 'mcol'
        eval_xc = ni.mcfun_eval_xc_adapter('lda,')
        vxc = eval_xc('lda,', rho, deriv=1)[1]
        mask = numpy.ones((100, mol.nbas), dtype=numpy.uint8)
        shls_slice = (0, mol.nbas)
        v0 = numint2c._mcol_lda_vxc_mat(mol, ao, weight, rho, vxc.copy(), mask,
                                        shls_slice, ao_loc, 0)
        v1 = numint2c._mcol_lda_vxc_mat(mol, ao, weight, rho, vxc.copy(), mask,
                                        shls_slice, ao_loc, 1)
        v1 = v1 + v1.conj().T
        self.assertAlmostEqual(abs(v0 - ref).max(), 0, 3)
        self.assertAlmostEqual(abs(v0 - v1).max(), 0, 14)
def basis_values(mol, basis, coords, coeffs=None, positions=None):
    """ Calculate the orbital's value at a position in space

    Args:
        mol (moldesign.Molecule): Molecule to attach basis set to
        basis (moldesign.orbitals.BasisSet): set of basis functions
        coords (Array[length]): List of coordinates (with shape ``(len(coords), 3)``)
        coeffs (Vector): List of ao coefficients (optional; if not passed, all basis fn
                 values are returned)

    Returns:
        Array[length]: if ``coeffs`` is not passed, an array of basis fn values at each
               coordinate. Otherwise, a list of orbital values at each coordinate
    """
    # TODO: more than just create the basis by name ...
    pmol = mol_to_pyscf(mol, basis=basis.basisname, positions=positions)
    aovals = numint.eval_ao(pmol,
                            np.ascontiguousarray(coords.value_in(u.bohr)))
    if coeffs is None:
        return aovals
    else:
        return aovals.dot(coeffs)
def basis_values(mol, basis, coords, coeffs=None, positions=None):
    """ Calculate the orbital's value at a position in space

    Args:
        mol (moldesign.Molecule): Molecule to attach basis set to
        basis (moldesign.orbitals.BasisSet): set of basis functions
        coords (Array[length]): List of coordinates (with shape ``(len(coords), 3)``)
        coeffs (Vector): List of ao coefficients (optional; if not passed, all basis fn
                 values are returned)

    Returns:
        Array[length**(-1.5)]: if ``coeffs`` is not passed, an array of basis fn values at each
               coordinate. Otherwise, a list of orbital values at each coordinate
    """
    from pyscf.dft import numint

    # TODO: more than just create the basis by name ...
    pmol = mol_to_pyscf(mol, basis=basis.basisname, positions=positions)
    aovals = numint.eval_ao(pmol, np.ascontiguousarray(coords.value_in(u.bohr))) * (u.a0**-1.5)
    if coeffs is None:
        return aovals
    else:
        return aovals.dot(coeffs.T)
Esempio n. 27
0
def density(mol, outfile, dm, nx=80, ny=80, nz=80, resolution=RESOLUTION):
    """Calculates electron density and write out in cube format.

    Args:
        mol : Mole
            Molecule to calculate the electron density for.
        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.
    """

    cc = Cube(mol, nx, ny, nz, resolution)

    # Compute density on the .cube grid
    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(mol, coords[ip0:ip1])
        rho[ip0:ip1] = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape(cc.nx, cc.ny, cc.nz)

    # Write out density to the .cube file
    cc.write(rho, outfile, comment='Electron density in real space (e/Bohr^3)')
Esempio n. 28
0
def make_fcsd(hfcobj, dm0, hfc_nuc=None, verbose=None):
    log = logger.new_logger(hfcobj, verbose)
    mol = hfcobj.mol
    if hfc_nuc is None:
        hfc_nuc = range(mol.natm)
    if isinstance(dm0, numpy.ndarray) and dm0.ndim == 2: # RHF DM
        return numpy.zeros((3,3))

    dma, dmb = dm0
    spindm = dma - dmb
    effspin = mol.spin * .5

    e_gyro = .5 * lib.param.G_ELECTRON
    nuc_mag = .5 * (lib.param.E_MASS/lib.param.PROTON_MASS)  # e*hbar/2m
    au2MHz = lib.param.HARTREE2J / lib.param.PLANCK * 1e-6
    fac = lib.param.ALPHA**2 / 2 / effspin * e_gyro * au2MHz

    coords = mol.atom_coords()
    ao = numint.eval_ao(mol, coords)

    nao = dma.shape[0]
    hfc = []
    for i, atm_id in enumerate(hfc_nuc):
        nuc_gyro = get_nuc_g_factor(mol.atom_symbol(atm_id)) * nuc_mag
        mol.set_rinv_origin(mol.atom_coord(atm_id))
# a01p[mu,sigma] the imaginary part of integral <vec{r}/r^3 cross p>
        a01p = mol.intor('int1e_sa01sp', 12).reshape(3,4,nao,nao)
        h1 = -(a01p[:,:3] + a01p[:,:3].transpose(0,1,3,2))
        fcsd = numpy.einsum('xyij,ji->xy', h1, spindm)
        fc = 8*numpy.pi/3 * numpy.einsum('i,j,ji', ao[atm_id], ao[atm_id], spindm)
        sd = fcsd - numpy.eye(3) * fc

        log.info('FC of atom %d  %s (in MHz)', atm_id, fac * nuc_gyro * fc)
        if hfcobj.verbose >= logger.INFO:
            _write(hfcobj, align(fac*nuc_gyro*sd)[0], 'SD of atom %d (in MHz)' % atm_id)
        hfc.append(fac * nuc_gyro * fcsd)
    return numpy.asarray(hfc)
Esempio n. 29
0
def density(mol, outfile, dm, nx=80, ny=80, nz=80, pad=4.0, gridspacing=None):
    """Calculates electron density.

    Args:
        mol (Mole): Molecule to calculate the electron density for.
        outfile (str): Name of Cube file to be written.
        dm (str): Density matrix of molecule.
        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.
        pad (float): Amount of padding (in Angstrom) in all dimensions that will
                     be applied in the automatic construction of the rectangular
                     grid volume based on the geometry of the system.
        gridspacing (float):  Distance, in Angstroms, between points in the grid,
                              in all dimensions. This will override the nx,ny,nz
                              the parameters. Note the following values:
               value/Angstroms  points/Bohr     Gaussian grid term
               0.1763           3                       Coarse
               0.0882           6                       Medium
               0.0441           12                      Fine
    """
    grid = grid_utils.Grid(mol, nx, ny, nz, pad, gridspacing)

    ngrids = grid.coords.shape[0]
    blksize = min(8000, ngrids)
    rho = numpy.empty(ngrids)
    ao = None
    for ip0, ip1 in gen_grid.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, grid.coords[ip0:ip1], out=ao)
        rho[ip0:ip1] = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape(grid.nx, grid.ny, grid.nz)

    grid_utils.write_formatted_cube_file(
        outfile, 'Electron density in real space (e/Bohr^3)', grid, rho)
Esempio n. 30
0
def density(mol, outfile, dm, nx=80, ny=80, nz=80, resolution=RESOLUTION):
    """Calculates electron density and write out in cube format.

    Args:
        mol : Mole
            Molecule to calculate the electron density for.
        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.
    """

    cc = Cube(mol, nx, ny, nz, resolution)

    # Compute density on the .cube grid
    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(mol, coords[ip0:ip1])
        rho[ip0:ip1] = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape(cc.nx,cc.ny,cc.nz)

    # Write out density to the .cube file
    cc.write(rho, outfile, comment='Electron density in real space (e/Bohr^3)')
Esempio n. 31
0
def orbital(mol, outfile, coeff, nx=80, ny=80, nz=80, resolution=RESOLUTION):
    """Calculate orbital value on real space grid and write out in cube format.

    Args:
        mol : Mole
            Molecule to calculate the electron density for.
        outfile : str
            Name of Cube file to be written.
        coeff : 1D array
            coeff coefficient.

    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.
    """
    cc = Cube(mol, nx, ny, nz, resolution)

    # Compute density on the .cube grid
    coords = cc.get_coords()
    ngrids = cc.get_ngrids()
    blksize = min(8000, ngrids)
    orb_on_grid = numpy.empty(ngrids)
    for ip0, ip1 in lib.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, coords[ip0:ip1])
        orb_on_grid[ip0:ip1] = numpy.dot(ao, coeff)
    orb_on_grid = orb_on_grid.reshape(cc.nx,cc.ny,cc.nz)

    # Write out orbital to the .cube file
    cc.write(orb_on_grid, outfile, comment='Orbital value in real space (1/Bohr^3)')
Esempio n. 32
0
def density(mol, outfile, dm, nx=80, ny=80, nz=80):
    coord = mol.atom_coords()
    box = numpy.max(coord, axis=0) - numpy.min(coord, axis=0) + 6
    boxorig = numpy.min(coord, axis=0) - 3
    xs = numpy.arange(nx) * (box[0] / nx)
    ys = numpy.arange(ny) * (box[1] / ny)
    zs = numpy.arange(nz) * (box[2] / nz)
    coords = lib.cartesian_prod([xs, ys, zs])
    coords = numpy.asarray(coords, order='C') - (-boxorig)

    nao = mol.nao_nr()
    ngrids = nx * ny * nz
    blksize = min(200, ngrids)
    rho = numpy.empty(ngrids)
    for ip0, ip1 in gen_grid.prange(0, ngrids, blksize):
        ao = numint.eval_ao(mol, coords[ip0:ip1])
        rho[ip0:ip1] = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape(nx, ny, nz)

    with open(outfile, 'w') as f:
        f.write('Electron density in real space (e/Bohr^3)\n')
        f.write('PySCF Version: %s  Date: %s\n' %
                (pyscf.__version__, time.ctime()))
        f.write('%5d' % mol.natm)
        f.write(' %14.8f %14.8f %14.8f\n' % tuple(boxorig.tolist()))
        f.write('%5d %14.8f %14.8f %14.8f\n' % (nx, xs[1], 0, 0))
        f.write('%5d %14.8f %14.8f %14.8f\n' % (ny, 0, ys[1], 0))
        f.write('%5d %14.8f %14.8f %14.8f\n' % (nz, 0, 0, zs[1]))
        for ia in range(mol.natm):
            chg = mol.atom_charge(ia)
            f.write('%5d %f' % (chg, chg))
            f.write(' %14.8f %14.8f %14.8f\n' % tuple(coord[ia]))
        fmt = ' %14.8e' * nz + '\n'
        for ix in range(nx):
            for iy in range(ny):
                f.write(fmt % tuple(rho[ix, iy].tolist()))
Esempio n. 33
0
mol = gto.M(
    verbose = 0,
    atom = '''
    o    0    0.       0.
    h    0    -0.757   0.587
    h    0    0.757    0.587''',
    basis = '6-31g')

mf = dft.RKS(mol)
mf.kernel()
dm = mf.make_rdm1()

# Use default mesh grids and weights
coords = mf.grids.coords
weights = mf.grids.weights
ao_value = numint.eval_ao(mol, coords, isgga=True)
# The first row of rho is electron density, the rest three rows are electron
# density gradients which are needed for GGA functional
rho = numint.eval_rho(mol, ao_value, dm, isgga=True)
print(rho.shape)
sigma = numpy.einsum('ip,ip->p', rho[1:], rho[1:])

# See pyscf/dft/vxc.py for the XC functional ID
x_id = dft.XC_GGA_X_B88
c_id = dft.XC_GGA_C_P86
ex, vx, vx_sigma = numint.eval_x(x_id, rho[0], sigma)
ec, vc, vc_sigma = numint.eval_c(c_id, rho[0], sigma)
print('Exc = %.12f' % numpy.einsum('i,i,i->', ex+ec, rho[0], weights))
print('Vxc on each grid %s' % str(vx.shape))
print('Vxc_sigma on each grid %s' % str(vx.shape))
Esempio n. 34
0
def lorb2fod(mf, lo_coeff, s=0, grid_level=7):
    """
    lo_coeff[:] localized orbital
    """
    from scipy import optimize
    # get estimate for FOD'position
    # by using the COM of the orbital density
    mol = mf.mol
    ao1 = numint.eval_ao(mol, mf.grids.coords)
    phi = ao1.dot(lo_coeff)
    #print(phi.shape)

    #print('lorb2fod: s={}'.format(s))
    #print('lorb2fod: lo_coeff={}'.format(lo_coeff.sum()))

    #print(np.sum(phi**2*mf.grids.weights))
    dens = np.conjugate(phi) * phi * mf.grids.weights
    # COM
    x = np.sum(dens * mf.grids.coords[:, 0])
    y = np.sum(dens * mf.grids.coords[:, 1])
    z = np.sum(dens * mf.grids.coords[:, 2])
    #print x

    print("  -> COM: {0:7.5f} {1:7.5f} {2:7.5f}".format(
        x * units.Bohr, y * units.Bohr, z * units.Bohr))
    ig_fod = np.array([x, y, z])

    #if s==1:
    #    sys.exit()

    ## build a new, smaller mesh for the density fitting
    # find nearest atom
    dists = np.linalg.norm((mol.atom_coords() - ig_fod), axis=1)
    didx = np.argsort(dists)
    #print dists
    #print didx
    nidx = -1
    for i in range(mol.natm):
        if mol.atom_pure_symbol(i) == 'H': continue
        nidx = didx[i]
        break

    if nidx == -1:
        print("ERROR")
        sys.exit()

    #print nidx, mol.atom_pure_symbol(nidx)

    # build atom object (make sure to enter ccors in Angst)
    acoord = mol.atom_coords()
    atoms = Atoms()
    for na in range(mol.natm):
        aa = Atom(symbol=mol.atom_symbol(na), position=acoord[na] * units.Bohr)
        atoms.extend(aa)

    cutoffs = natural_cutoffs(atoms)

    ##print cutoffs
    nl = NL.NeighborList(cutoffs, self_interaction=False, bothways=True)
    nl.update(atoms)

    # generate a per-atom grid (include neigbours)
    neiatm = nl.get_neighbors(nidx)[0]
    mstr = ''
    for na in neiatm:
        sym = mol.atom_pure_symbol(na)
        pos = mol.atom_coord(na) * units.Bohr  # in Angst
        #print sym, pos
        mstr += "{0} {1:0.12f} {2:0.12f} {3:0.12f};".format(
            sym, pos[0], pos[1], pos[2])

    # also add the nearest Atom to the grid algorithm
    sym = mol.atom_pure_symbol(nidx)
    pos = mol.atom_coord(nidx) * units.Bohr  # in Angst
    #print sym, pos
    mstr += "{0} {1:0.12f} {2:0.12f} {3:0.12f};".format(
        sym, pos[0], pos[1], pos[2])

    #print ">>>"
    #print mstr

    # build a Mole object from subsystem
    b = mol.basis
    try:
        onmol = gto.M(atom=mstr, basis=b, verbose=0)
    except RuntimeError:
        onmol = gto.M(atom=mstr, basis=b, spin=1, verbose=0)

    _mdft = dft.UKS(onmol)
    _mdft.max_cycle = 0
    _mdft.grids.level = grid_level
    _mdft.kernel()
    ongrid = copy.copy(_mdft.grids)

    #print("Original grid size: {0}".format(mf.grids.coords.shape[0]))
    #print("  building FO, grid size: {0}"
    #    .format(ongrid.coords.shape[0]))

    ## re-calculate lo density on O(N) grid
    ao1 = numint.eval_ao(mol, ongrid.coords)
    phi = ao1.dot(lo_coeff)
    dens = np.conjugate(phi) * phi * ongrid.weights

    #sys.exit()

    # now build the corresponding fermi orbital
    #lfo = fo(mf, ig_fod, s)

    def densdiff(x0):
        #print ig_fod
        #print(s)
        _x = np.reshape(x0, (-1, 3))
        lfo = fo(mf, _x, s)

        mol = mf.mol
        ao1 = numint.eval_ao(mol, ongrid.coords)
        _fo = ao1.dot(lfo)

        dens_fo = np.conjugate(_fo) * _fo * ongrid.weights

        ##print dens_fo.shape
        ##print dens.shape

        diff = np.linalg.norm(dens_fo - dens)

        return diff

    options = {
        'disp': False,
        'eps': 1e-05,
        'gtol': 1e-05,
        'maxiter': 299,
    }

    db = 1.5
    if np.linalg.norm(mol.atom_coord(nidx) - ig_fod) < 0.5:
        db = 0.75

    bounds = [(x - db, x + db), (y - db, y + db), (z - db, z + db)]

    res = optimize.minimize(densdiff,
                            ig_fod.flatten(),
                            method='L-BFGS-B',
                            options=options,
                            bounds=bounds)

    #print ">> done <<"
    #print res.x
    #print ig_fod
    #print ">> initial FOD moved by: {0:0.4f} [B]".format(np.linalg.norm(res.x-ig_fod))
    #print ">> density fit quality : {0:0.4f}".format(res.fun)
    print("  -> a_i: {0:7.5f} {1:7.5f} {2:7.5f}"\
      .format(res.x[0]*units.Bohr,res.x[1]*units.Bohr,res.x[2]*units.Bohr))

    return res.x
Esempio n. 35
0
mf = dft.RKS(mol)
mf.xc = 'b3lyp'
mf.kernel()
dm = mf.make_rdm1()
size = 18
# Use default mesh grids and weights
grid = np.linspace(-size // 2, size // 2, int(size / 0.2 + 1))
coords = np.hstack((np.meshgrid(grid, grid, grid)[0].flatten().reshape(
    (int(size / 0.2 + 1)**3, 1)), np.meshgrid(grid, grid,
                                              grid)[1].flatten().reshape(
                                                  (int(size / 0.2 + 1)**3, 1)),
                    np.meshgrid(grid, grid, grid)[2].flatten().reshape(
                        (int(size / 0.2 + 1)**3, 1))))
# weights = mf.grids.weights
# weights_list.append(weights)
ao_value = numint.eval_ao(mol, coords, deriv=1)
# The first row of rho is electron density, the rest three rows are electron
# density gradients which are needed for GGA functional
rho = numint.eval_rho(mol, ao_value, dm, xctype='GGA')
print(rho.shape)
exc, vxc = dft.libxc.eval_xc('b3lyp', rho)[:2]
print('Exc = %.12f' % np.einsum('i,i->', exc, rho[0] / 125.0))
Exc = np.einsum('i,i->', exc, rho[0] / 125.0)
np.save(open("../rho_b3lyp.npy", "rb"), rho[0])
np.save(open("../vxc_b3lyp.npy", "rb"), vxc)
np.save(open("../exc_b3lyp.npy", "rb"), exc)
np.save(open("../Exc_b3lyp.npy", "rb"), Exc)

# coords = mf.grids.coords
# weights = mf.grids.weights
# ao_value = numint.eval_ao(mol, coords, deriv=1)
Esempio n. 36
0
def test_interpolate_helium():
    """Check interpolation for He density."""
    # define ta_object
    dic = os.getenv('FDETADATA')
    filetraj = os.path.join(dic, 'he_traj.txt')
    traj = TrajectoryAnalysis(filetraj)
    box_size = np.array([2, 2, 2])
    grid_size = np.array([5, 5, 5])
    # Use the mdinterface to create a cubic grid
    md = MDInterface(traj, box_size, grid_size)
    # print("Points: \n", md.points)
    # print(md.npoints*3)
    grid = np.zeros((md.npoints, 3))
    grid = md.pbox.get_grid(grid, False)

    # Use PySCF to evaluate density
    from pyscf import gto, scf, dft
    from pyscf import lib
    from pyscf.dft.numint import eval_ao, eval_rho, eval_mat
    from pyscf.dft import gen_grid, libxc

    mol0 = gto.M(atom="""He  0.000   0.000   0.000""", basis='sto-3g')

    # Solve HF and get density
    scfres = scf.RHF(mol0)
    scfres.conv_tol = 1e-12
    scfres.kernel()
    dm0 = scfres.make_rdm1()

    # Take only a plane in z=0
    subgrid = grid[50:75]
    ao_mol0 = eval_ao(mol0, subgrid, deriv=0)
    rho_mol0 = eval_rho(mol0, ao_mol0, dm0, xctype='LDA')
    rho_plot = rho_mol0.reshape((5, 5))

    # Check interpolation in PySCF grid
    from scipy import interpolate
    # whole grid
    ao_all = eval_ao(mol0, grid, deriv=0)
    rho_all = eval_rho(mol0, ao_all, dm0, xctype='LDA')
    xs = grid[:, 0]
    ys = grid[:, 1]
    zs = grid[:, 2]
    # print(rho_all.shape)

    grids = gen_grid.Grids(mol0)
    grids.level = 4
    grids.build()
    # print(rho_all.shape)
    # print(grids.coords.shape)

    xdata = grids.coords[:, 0]
    ydata = grids.coords[:, 1]
    zdata = grids.coords[:, 2]

    # Real values
    real_ao = eval_ao(mol0, grids.coords, deriv=0)
    real_rho = eval_rho(mol0, real_ao, dm0, xctype='LDA')

    # Check with method is the best for Rbf interpolation
    functions = [
        'multiquadric', 'inverse', 'gaussian', 'linear', 'cubic', 'quintic',
        'thin_plate'
    ]
    minmax = []
    for function in functions:
        print(function)
        interpolator = interpolate.Rbf(xs, ys, zs, rho_all, function=function)
        new_rho = interpolator(xdata, ydata, zdata)
        minmax.append([
            function,
            min(abs(new_rho - real_rho)),
            max(abs(new_rho - real_rho))
        ])
    # fig = plt.figure()
    # ax = fig.add_subplot(projection='3d')
    # ax.scatter3D(xdata, ydata, new_rho, c=new_rho, cmap='Greens')
    # ax.scatter3D(xdata, ydata, real_rho, c=real_rho)
    # plt.xlim(-1.0,  1.0)
    # plt.ylim(-1.0, 1.0)
    # plt.show()
    # print(minmax)
    mol1 = gto.M(atom="""He  0.000   0.000   2.500""", basis='sto-3g')
    # Solve HF and get density
    scfres1 = scf.RHF(mol1)
    scfres1.conv_tol = 1e-12
    scfres1.kernel()
    dm1 = scfres1.make_rdm1()

    # whole grid
    ao_all1 = eval_ao(mol1, grid, deriv=0)
    rho_all1 = eval_rho(mol1, ao_all1, dm1, xctype='LDA')
    # Real values
    real_ao1 = eval_ao(mol1, grids.coords, deriv=0)
    real_rho1 = eval_rho(mol1, real_ao1, dm1, xctype='LDA')
    minmax1 = []
    for function in functions:
        interpolator = interpolate.Rbf(xs, ys, zs, rho_all1, function=function)
        new_rho1 = interpolator(xdata, ydata, zdata)
        minmax1.append([
            function,
            min(abs(new_rho1 - real_rho1)),
            max(abs(new_rho1 - real_rho1))
        ])
        p = np.where(abs(new_rho1 - real_rho1) == minmax1[-1][2])
Esempio n. 37
0
mol = gto.M(
    verbose = 0,
    atom = '''
    o    0    0.       0.
    h    0    -0.757   0.587
    h    0    0.757    0.587''',
    basis = '6-31g')

mf = dft.RKS(mol)
mf.kernel()
dm = mf.make_rdm1()

# Use default mesh grids and weights
coords = mf.grids.coords
weights = mf.grids.weights
ao_value = numint.eval_ao(mol, coords, deriv=1)
# The first row of rho is electron density, the rest three rows are electron
# density gradients which are needed for GGA functional
rho = numint.eval_rho(mol, ao_value, dm, xctype='GGA')
print(rho.shape)
sigma = numpy.einsum('ip,ip->p', rho[1:], rho[1:])

# See pyscf/dft/vxc.py for the XC functional ID
x_id = dft.XC_GGA_X_B88
c_id = dft.XC_GGA_C_P86
ex, vx, vx_sigma = numint.eval_x(x_id, rho[0], sigma)
ec, vc, vc_sigma = numint.eval_c(c_id, rho[0], sigma)
print('Exc = %.12f' % numpy.einsum('i,i,i->', ex+ec, rho[0], weights))
print('Vxc on each grid %s' % str(vx.shape))
print('Vxc_sigma on each grid %s' % str(vx.shape))
Esempio n. 38
0
edft = eedft_1 + eedft_2 + enuc
n = np.trace(s @ rdm1dft)
print(' Number of electrons is {0} before diagonalization.'.format(n))
w = linalg.eig(s @ rdm1dft)[0]
n = np.sum(w).real
print(' Number of electrons is {0} after diagonalization.'.format(n))

# Now lets calculate densities in a grid
#coords = np.random.random((100,3)) # 100 random points
# Or we can generate an array
#print(mol.atom_coords())
zz = np.linspace(-2, 4, 500)
coords = [(0, 0, z) for z in zz]

ao = numint.eval_ao(
    mol, coords, deriv=0
)  # we get the AO value for every point in space of coords, returns 2d array (N,nao)
rho_dft = numint.eval_rho(mol, ao, rdm1dft, xctype='LDA',
                          hermi=0)  # we can evaluate rho at any point of space
plt.plot(zz, rho_dft, label='DFT')
plt.legend()
plt.savefig('density_dft.png')

# However if we need the derivatives of the density we need the derivatives of the aos
# so we increase deriv
# this returns (:,N,nao) where we get rho,rhox,rhoy,rhoz,drhodx... etc.

ao = numint.eval_ao(mol, coords, deriv=1)  # 1 for first derivatives
# now we can evaluate \rho and first derivatives
rho, dx_rho, dy_rho, dz_rho = numint.eval_rho(mol,
                                              ao,
Esempio n. 39
0
def dm_on_grid(mol, dm, points):
    """
    """
    ao_mol = eval_ao(mol, points, deriv=0)
    rho = eval_rho(mol, ao_mol, dm, xctype="LDA")
    return rho