Beispiel #1
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
Beispiel #2
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
Beispiel #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)
Beispiel #4
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()))
Beispiel #5
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()))
Beispiel #6
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
Beispiel #7
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)
Beispiel #8
0
def density(mol,
            outfile,
            dm,
            nx=80,
            ny=80,
            nz=80,
            resolution=RESOLUTION,
            margin=BOX_MARGIN):
    """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.
    """
    from pyscf.pbc.gto import Cell
    cc = Cube(mol, nx, ny, nz, resolution, margin)

    GTOval = 'GTOval'
    if isinstance(mol, Cell):
        GTOval = 'PBC' + GTOval

    # 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 = mol.eval_gto(GTOval, 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)')
    return rho
Beispiel #9
0
def density(mol,
            dm,
            outfile='rho',
            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])
        rho[ip0:ip1] = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape((nx, ny, nz))
    if save:
        cc.write(rho,
                 outfile,
                 comment='Electron density 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 rho, np.array([y, x, z])
Beispiel #10
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
Beispiel #11
0
 def write_fields(self, filename):
     """Write voxel data of registered fields in `self.fields` to cube-file."""
     blksize = min(self.ncoords, 8000)
     with open(filename, 'a') as f:
         # Loop over x,y,z coordinates first, then fields!
         for blk0, blk1 in lib.prange(0, self.ncoords, blksize):
             data = np.zeros((blk1 - blk0, self.nfields))
             blk = np.s_[blk0:blk1]
             ao = self.cell.eval_gto('PBCGTOval', self.coords[blk])
             for i, (field, ftype, _) in enumerate(self.fields):
                 if ftype == 'orbital':
                     data[:, i] = np.dot(ao, field)
                 elif ftype == 'density':
                     data[:, i] = numint.eval_rho(self.cell, ao, field)
                 else:
                     raise ValueError('Unknown field type: %s' % ftype)
             data = data.flatten()
             for d0, d1 in lib.prange(0, len(data), 6):
                 f.write(((d1 - d0) * self.fmt + '\n') % tuple(data[d0:d1]))
Beispiel #12
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)')
Beispiel #13
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)
Beispiel #14
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)')
Beispiel #15
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)')
Beispiel #16
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()))
Beispiel #17
0
def density(mol, outfile, dm, nx=80, ny=80, nz=80):
    """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.


    """

    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)

    ngrids = nx * ny * nz
    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, coords[ip0:ip1], out=ao)
        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('%12.6f%12.6f%12.6f\n' % tuple(boxorig.tolist()))
        f.write('%5d%12.6f%12.6f%12.6f\n' % (nx, xs[1], 0, 0))
        f.write('%5d%12.6f%12.6f%12.6f\n' % (ny, 0, ys[1], 0))
        f.write('%5d%12.6f%12.6f%12.6f\n' % (nz, 0, 0, zs[1]))
        for ia in range(mol.natm):
            chg = mol.atom_charge(ia)
            f.write('%5d%12.6f' % (chg, chg))
            f.write('%12.6f%12.6f%12.6f\n' % tuple(coord[ia]))

        for ix in range(nx):
            for iy in range(ny):
                for iz in range(0, nz, 6):
                    remainder = (nz - iz)
                    if (remainder > 6):
                        fmt = '%13.5E' * 6 + '\n'
                        f.write(fmt % tuple(rho[ix, iy, iz:iz + 6].tolist()))
                    else:
                        fmt = '%13.5E' * remainder + '\n'
                        f.write(fmt %
                                tuple(rho[ix, iy, iz:iz + remainder].tolist()))
                        break
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])
Beispiel #19
0
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)
# # 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')
Beispiel #20
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
Beispiel #21
0
def run_co_h2o_pyscf(ibasis, return_matrices=False):
    # Run SCF in pyscf
    h2o = gto.M(
        atom="""
                O  -7.9563726699    1.4854060709    0.1167920007
                H  -6.9923165534    1.4211335985    0.1774706091
                H  -8.1058463545    2.4422204631    0.1115993752
             """,
        basis=ibasis,
    )
    co = gto.M(
        atom="""
                C  -3.6180905689    1.3768035675   -0.0207958979
                O  -4.7356838533    1.5255563000    0.1150239130
             """,
        basis=ibasis,
    )
    system = gto.M(atom=co.atom + h2o.atom, basis=ibasis)
    # Get initial densities from HF
    # H2O
    # TODO: make a wrapper and make sure DMs are correct
    scfres1 = scf.RHF(h2o)
    scfres1.conv_tol = 1e-12
    scfres1.kernel()
    dmb = scfres1.make_rdm1()

    # CO
    scfres2 = scf.RHF(co)
    scfres2.conv_tol = 1e-12
    scfres2.kernel()
    dma = scfres2.make_rdm1()

    # Construct grid for complex
    grids = gen_grid.Grids(system)
    grids.level = 4
    grids.build()
    ao_h2o = eval_ao(h2o, grids.coords, deriv=0)
    ao_co = eval_ao(co, grids.coords, deriv=0)

    # Make Complex DM
    ao_both = eval_ao(system, grids.coords, deriv=0)
    nao_co = co.nao_nr()
    nao_h2o = h2o.nao_nr()
    nao_tot = nao_co + nao_h2o
    dm_both = np.zeros((nao_tot, nao_tot))

    dm_both[:nao_co, :nao_co] = dma
    dm_both[nao_co:, nao_co:] = dmb

    # Compute DFT non-additive potential and energies
    rho_h2o = eval_rho(h2o, ao_h2o, dmb, xctype='LDA')
    rho_co = eval_rho(co, ao_co, dma, xctype='LDA')
    rho_both = eval_rho(system, ao_both, dm_both, xctype='LDA')
    # Compute all densities on a grid
    xc_code = 'LDA,VWN'  # same as xc_code = 'XC_LDA_X + XC_LDA_C_VWN'
    t_code = 'XC_LDA_K_TF'
    excs, vxcs = get_dft_grid_stuff(xc_code, rho_both, rho_co, rho_h2o)
    ets, vts = get_dft_grid_stuff(t_code, rho_both, rho_co, rho_h2o)
    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_co, rho_h2o)
    et_nad = get_nad_energy(grids, ets, rho_both, rho_co, rho_h2o)

    fock_emb_xc = eval_mat(co,
                           ao_co,
                           grids.weights,
                           rho_co,
                           vxc_emb,
                           xctype='LDA')
    fock_emb_t = eval_mat(co,
                          ao_co,
                          grids.weights,
                          rho_co,
                          vt_emb,
                          xctype='LDA')

    # Electrostatic part
    v_coulomb = get_coulomb(co, h2o, dmb)

    # Nuclear-electron integrals
    vAnucB, vBnucA = get_attraction_potential(co, h2o)

    # Perform the HF-in-HF embedding
    # Modify Fock matrix
    focka_ref = scfres2.get_hcore()
    focka = focka_ref.copy()
    focka += fock_emb_t + fock_emb_xc + v_coulomb + vAnucB
    scfres3 = scf.RHF(co)
    scfres3.conv_tol = 1e-12
    scfres3.get_hcore = lambda *args: focka

    # Re-evaluate the energy
    scfres3.kernel()
    # Get density matrix, to only evaluate
    dma_final = scfres3.make_rdm1()

    int_ref_xc = np.einsum('ab,ba', fock_emb_xc, dma)
    int_ref_t = np.einsum('ab,ba', fock_emb_t, dma)
    rhoArhoB = np.einsum('ab,ba', v_coulomb, dma_final)
    nucArhoB = np.einsum('ab,ba', vAnucB, dma_final)
    nucBrhoA = np.einsum('ab,ba', vBnucA, dmb)

    # Linearization terms
    int_emb_xc = np.einsum('ab,ba', fock_emb_xc, dma_final)
    int_emb_t = np.einsum('ab,ba', fock_emb_t, dma_final)
    deltalin = (int_emb_xc - int_ref_xc) + (int_emb_t - int_ref_t)

    # Save terms in dictionary
    embdic = {}
    embdic['rhoArhoB'] = rhoArhoB
    embdic['nucArhoB'] = nucArhoB
    embdic['nucBrhoA'] = nucBrhoA
    embdic['exc_nad'] = exc_nad
    embdic['et_nad'] = et_nad
    embdic['int_ref_xc'] = int_ref_xc
    embdic['int_ref_t'] = int_ref_t
    embdic['int_emb_xc'] = int_emb_xc
    embdic['int_emb_t'] = int_emb_t
    embdic['deltalin'] = deltalin
    if return_matrices:
        matdic = {}
        matdic['dma'] = dma
        matdic['dmb'] = dmb
        matdic['dma_final'] = dma_final
        matdic['fock_emb_xc'] = fock_emb_xc
        matdic['fock_emb_t'] = fock_emb_t
        matdic['v_coulomb'] = v_coulomb
        matdic['vAnucB'] = vAnucB
        matdic['vBnucA'] = vBnucA
        return embdic, matdic
    else:
        return embdic
Beispiel #22
0
      format(efci, ehf, abs(efci - ehf)))  # total energies

# The FCI rdm1 needs to be decontracted from the mo coeffs.
rdm1_corrected = mf.mo_coeff @ rdm1 @ mf.mo_coeff.T

# 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_fci = numint.eval_rho(mol, ao, rdm1_corrected, xctype='LDA',
                          hermi=0)  # we can evaluate rho at any point of space
rho_hf = numint.eval_rho(mol, ao, rdm1hf, xctype='LDA',
                         hermi=0)  # we can evaluate rho at any point of space
plt.plot(zz, rho_fci, label='FCI')
plt.plot(zz, rho_hf, label='HF')
plt.legend()
plt.savefig('densities.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,
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,
                                              rdm1dft,
                                              xctype='GGA',
                                              hermi=0)
Beispiel #24
0
def isomep(mol,
           outfile,
           dm,
           electronic_iso=0.002,
           iso_tol=0.00003,
           nx=80,
           ny=80,
           nz=80,
           pad=4.0,
           gridspacing=None):
    """Calculates MEP on a specific electron density surface.

    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)
    LOGGER.debug("grid coords shape: %s", grid.coords.shape)
    LOGGER.debug("grid coords first element shape: %s", grid.coords[0].shape)
    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)

    LOGGER.note("Total number of density voxels: %d", len(rho))

    is_surface_voxel = numpy.logical_and(rho > (electronic_iso - iso_tol),
                                         rho < (electronic_iso + iso_tol))
    LOGGER.debug("Surface voxel count from logical_and: %d",
                 numpy.count_nonzero(is_surface_voxel))

    surface_voxel_grid_indices = numpy.nonzero(is_surface_voxel)[0]
    LOGGER.debug2("Surface voxel indices: %s", surface_voxel_grid_indices)
    LOGGER.debug2("Surface voxel indices shape: %s",
                  surface_voxel_grid_indices.shape)

    # Number of voxels at the defined electronic_iso surface
    # Used for area
    # Voxels at surface
    #(num > (ISO - TOL) ) && (num < (ISO + TOL) )
    surface_voxel_count = surface_voxel_grid_indices.shape[0]
    surface_voxel_coords = grid.coords[surface_voxel_grid_indices[0]]
    for i in range(1, surface_voxel_grid_indices.shape[0]):
        surface_voxel_coord = grid.coords[surface_voxel_grid_indices[i]]
        LOGGER.debug4("surface voxel coord shape: %s",
                      surface_voxel_coord.shape)
        surface_voxel_coords = numpy.append(surface_voxel_coords,
                                            surface_voxel_coord,
                                            axis=0)
    LOGGER.debug("surface_voxel_coords shape: %s", surface_voxel_coords.shape)
    surface_voxel_coords = surface_voxel_coords.reshape(
        (surface_voxel_grid_indices.shape[0], 3))
    LOGGER.debug("surface_voxel_coords shape: %s", surface_voxel_coords.shape)
    LOGGER.debug3("First coord from grid: %s",
                  grid.coords[surface_voxel_grid_indices[0]])
    LOGGER.debug3("First coord from surf voxel array: %s",
                  surface_voxel_coords[0])

    is_in_surface = numpy.greater(rho, electronic_iso)
    LOGGER.debug("Voxel count from numpy.greater: %d",
                 numpy.count_nonzero(is_in_surface))
    # Number of voxels *within* the defined electronic_iso surface
    # Used for volume
    inner_voxel_count = numpy.count_nonzero(is_in_surface)
    # This time, actually change
    LOGGER.debug("rho shape: %s", rho.shape)
    rho = rho.reshape(grid.nx, grid.ny, grid.nz)
    LOGGER.debug("rho shape: %s", rho.shape)

    LOGGER.note("surface voxels_found: %d", surface_voxel_count)
    voxel_area = gridspacing * gridspacing
    LOGGER.info("Each voxel area /  A^2: %f", voxel_area)
    LOGGER.info("inner surface area / A^2: %f",
                surface_voxel_count * voxel_area)

    LOGGER.info("inner voxel count: %d", inner_voxel_count)
    voxel_volume = gridspacing * gridspacing * gridspacing
    LOGGER.info("Each voxel volume /  A^3: %f", voxel_volume)
    inner_volume = inner_voxel_count * voxel_volume
    LOGGER.info("Total inner volume / A^3: %f", inner_volume)

    mep_values = mep_for_coords(mol, dm, surface_voxel_coords)
    LOGGER.debug("MEP values shape: %s", mep_values.shape)
    mep_values = mep_values.reshape((mep_values.shape[0], 1))
    LOGGER.debug("MEP values shape: %s", mep_values.shape)
    #Add the potentials to the coordinates: each row describes one point.
    coords_with_mep_values = numpy.append(surface_voxel_coords,
                                          mep_values,
                                          axis=1)

    cube_information = "Molecular electrostatic potential in real space on {:.5f} isodensity surface. Volume: {:.6f}".format(
        electronic_iso, inner_volume)

    grid_utils.write_unformatted_cube_file(outfile, cube_information, grid,
                                           coords_with_mep_values)
Beispiel #25
0
    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))

Beispiel #26
0
    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))

Beispiel #27
0
    def get_cubevals_from_dm(
            self,
            dmfile="",
            basfile="",
            g="",
            comment="Obtained from density matrix in file: \n {dmfile} \n"):
        """
        Note
        ----
        Allows to obtain values from a density matrix.
        
        Parameters
        ----------
        dmfile: str or list
            density matrix file, list or "file1,file2"
        basfile: str or list
            basis .nwchem file, list or "file1.nwchem,file2.nwchem"
        g: str or geom obj, or [str,str] or [obj,obj]
            geometry or geometry file which overrides self.geom. Compulsory only for dual basis. 
            For dual basis: "geomA.xyz, geomB.xyz",  ["geomA.xyz"," geomB.xyz"], or [geomA, geomB]
        comment: str
            default writes dmfile, use empty string to leave self.cube
        Sets
        ----
        self.values
            obtained from density matrix
        self.comment
            user-chosen, default is corresponding density matrix
        """
        basfile = list(basfile) if type(
            basfile) == tuple else basfile  # no tuples because immutable
        g = list(g) if type(g) == tuple else g  # no tuples because immutable
        from pyscf import gto
        from pyscf.dft.numint import eval_ao, eval_rho
        import dmtools.dmtools as dmt
        if dmfile == "":
            dmfile = input(
                "You must specify the density matrix file. Can have header or not, can be alpha and beta or not. Please type the filename\n"
            )  #TODO check if it reads a single DM as 2*a or a.
        if basfile == "":
            import glob as gl
            files = gl.glob("*.nwchem")
            if len(files) == 0:
                raise FileNotFoundError(
                    "no *.nwchem file! basis must be in .nwchem!")
            elif len(files) == 1:
                basfile = files[0]
                print(
                    "basfile not specified, using {} as a single basis".format(
                        basfile))
            else:
                basfile = input(
                    "Too many *.nwchem. For single basis, type the one to use. For dual basis, type '[basisA.nwchem],[basisB.nwchem]'\n"
                )
        basfile = [
            i.strip() for i in basfile.split(",")
        ] if "," in basfile else basfile  # turn string to list if dual basis
        if type(basfile) == str:  # then it is not dual basis
            if g != "":
                if type(g) == str:
                    g = geom.from_xyz(g)
            self.geom = g
            self.geom.change_coord_unit("Angstrom")

            with open(basfile, "r") as f:
                ibasis = f.read()
        if type(basfile) == list:  # then it is dual basis
            if g == "":
                g = input(
                    "From basfile I deduce dualbasis, Please type 'geomfileA,geomfileB'\n"
                )
            if type(g) == str:
                if len(g.split(",")) == 2:
                    g = [i.strip() for i in g.split(",")]
                else:
                    raise TypeError(
                        "Cannot obtain two geometries from {}.\n From basfile I deduce dualbasis, so you must give geomA and geomB"
                        .format(g))
            for n in range(2):
                try:
                    g[n] = geom.from_xyz(g[n], identifier=n)
                except:
                    g[n].change_coord_unit("angstrom")
                    g[n].change_identifier(n)
            self.geom = g[0] + g[1]
            ###create ibasis
            for n, i in enumerate(basfile):
                with open(i, "r") as f:
                    basfile[n] = f.read()
            ibasis = {
                i + str(n): basfile[n]
                for n in range(2) for i in set(g[n].atoms)
            }
        geomstring = self.geom.__str__()
        mol = gto.M(atom=geomstring, basis=ibasis)
        dm_obj = dmt.DM.from_dmfile(dmfile)
        dm = dm_obj.get_dm_full()
        self.geom.change_coord_unit("au")
        points = self.get_coordlist()
        ao_mol = eval_ao(mol, points, deriv=0)
        cubevals = eval_rho(mol, ao_mol, dm, xctype='LDA')
        self.values = cubevals.reshape(*self.Np_vect)
        if "{dmfile}" in comment:
            comment = comment.format(dmfile=dmfile)
        self.comment = comment
Beispiel #28
0
def AOtorho(mol, ao, dm, nx, ny, nz):
    rho = np.zeros((ao.shape[0]))
    rho = numint.eval_rho(mol, ao, dm)
    rho = rho.reshape((nx, ny, nz))
    return rho