def test_get_lattice_Ls(self): numpy.random.seed(2) cl1 = pbcgto.M(a = numpy.random.random((3,3))*3, mesh = [3]*3, atom ='''He .1 .0 .0''', basis = 'ccpvdz') Ls = tools.get_lattice_Ls(cl1) self.assertEqual(Ls.shape, (2099,3)) Ls = tools.get_lattice_Ls(cl1, rcut=0) self.assertEqual(Ls.shape, (1,3))
def test_get_lattice_Ls1(self): cell = pbcgto.Cell() cell.verbose = 0 cell.a = ''' -10.11124892 0. 10.11124892 0. 10.11124892 10.11124892 -10.11124892 10.11124892 0. ''' cell.atom = ''' C 0. 0. 0. C 13.48166522 6.74083261 6.74083261 C 15.16687337 8.42604076 8.42604076 C 13.48166522 10.11124892 10.11124892 C 15.16687337 11.79645707 11.79645707 C 10.11124892 13.48166522 10.11124892 C 11.79645707 15.16687337 11.79645707 C 13.48166522 13.48166522 13.48166522 C 15.16687337 15.16687337 15.16687337 ''' cell.unit= 'B' cell.basis = 'gth-dzvp' cell.pseudo = 'gth-pade' cell.precision = 1e-10 cell.build() Ls = cell.get_lattice_Ls() self.assertTrue(Ls.shape[0] > 140) S = cell.pbc_intor('int1e_ovlp') w, v = numpy.linalg.eigh(S) self.assertTrue(w.min() > 0) self.assertAlmostEqual(abs(S - S.T.conj()).max(), 0, 13) self.assertAlmostEqual(w.min(), 0.0007176363230, 8) Ls = tools.get_lattice_Ls(cl1, rcut=0) self.assertEqual(Ls.shape, (1,3))
def eval_ao(cell, coords, kpt=None, deriv=0, relativity=0, bastart=0, bascount=None, non0tab=None, verbose=None): '''Collocate AO crystal orbitals (opt. gradients) on the real-space grid. Args: cell : instance of :class:`Cell` coords : (nx*ny*nz, 3) ndarray The real-space grid point coordinates. Kwargs: kpt : (3,) ndarray The k-point corresponding to the crystal AO. deriv : int AO derivative order. It affects the shape of the return array. If deriv=0, the returned AO values are stored in a (N,nao) array. Otherwise the AO values are stored in an array of shape (M,N,nao). Here N is the number of grids, nao is the number of AO functions, M is the size associated to the derivative deriv. Returns: aoR : ([4,] nx*ny*nz, nao=cell.nao_nr()) ndarray The value of the AO crystal orbitals on the real-space grid by default. If deriv=1, also contains the value of the orbitals gradient in the x, y, and z directions. It can be either complex or float array, depending on the kpt argument. If kpt is not given (gamma point), aoR is a float array. See Also: pyscf.dft.numint.eval_ao ''' aoR = 0 for L in tools.get_lattice_Ls(cell, cell.nimgs): if kpt is None: aoR += pyscf.dft.numint.eval_ao(cell, coords-L, deriv, relativity, bastart, bascount, non0tab, verbose) else: factor = numpy.exp(1j*numpy.dot(kpt,L)) aoR += pyscf.dft.numint.eval_ao(cell, coords-L, deriv, relativity, bastart, bascount, non0tab, verbose) * factor if cell.ke_cutoff is not None: ke = 0.5*numpy.einsum('gi,gi->g', cell.Gv, cell.Gv) ke_mask = ke < cell.ke_cutoff aoG = numpy.zeros_like(aoR) for i in range(cell.nao_nr()): if deriv == 1: for c in range(4): aoG[c][ke_mask, i] = tools.fft(aoR[c][:,i], cell.gs)[ke_mask] aoR[c][:,i] = tools.ifft(aoG[c][:,i], cell.gs) else: aoG[ke_mask, i] = tools.fft(aoR[:,i], cell.gs)[ke_mask] aoR[:,i] = tools.ifft(aoG[:,i], cell.gs) return numpy.asarray(aoR)
def test_get_lattice_Ls(self): numpy.random.seed(2) cl1 = pbcgto.M(a=numpy.random.random((3, 3)) * 3, gs=[1] * 3, atom='''He .1 .0 .0''', basis='ccpvdz') Ls = tools.get_lattice_Ls(cl1) self.assertEqual(Ls.shape, (1725, 3))
def test_get_lattice_Ls(self): numpy.random.seed(2) cl1 = pbcgto.M(a = numpy.random.random((3,3))*3, mesh = [3]*3, atom ='''He .1 .0 .0''', basis = 'ccpvdz') Ls = tools.get_lattice_Ls(cl1) self.assertEqual(Ls.shape, (1725,3))
def cell_plus_imgs(cell, nimgs): """Create a supercell via nimgs[i] in each +/- direction, as in get_lattice_Ls(). Args: cell : instance of :class:`Cell` nimgs : (3,) array Returns: supcell : instance of :class:`Cell` """ Ls = tools.get_lattice_Ls(cell, nimgs) supcell = cell.copy() supcell.atom = [] for L in Ls: atom1 = [] for ia in range(cell.natm): atom1.append([cell._atom[ia][0], cell._atom[ia][1] + L]) supcell.atom.extend(atom1) supcell.unit = "B" supcell.h = np.dot(cell._h, np.diag(nimgs)) supcell.build(False, False, verbose=0) return supcell
def get_int1e_cross(intor, cell1, cell2, kpt=None, comp=1): r'''1-electron integrals from two molecules like .. math:: \langle \mu | intor | \nu \rangle, \mu \in cell1, \nu \in cell2 ''' nimgs = np.max((cell1.nimgs, cell2.nimgs), axis=0) Ls = tools.get_lattice_Ls(cell1, nimgs) # Change the basis position only, keep all other envrionments cellL = cell2.copy() ptr_coord = cellL._atm[:,pyscf.gto.PTR_COORD] _envL = cellL._env int1e = 0 for L in Ls: _envL[ptr_coord+0] = cell2._env[ptr_coord+0] + L[0] _envL[ptr_coord+1] = cell2._env[ptr_coord+1] + L[1] _envL[ptr_coord+2] = cell2._env[ptr_coord+2] + L[2] if kpt is None: int1e += pyscf.gto.intor_cross(intor, cell1, cellL, comp) else: factor = np.exp(1j*np.dot(kpt, L)) int1e += pyscf.gto.intor_cross(intor, cell1, cellL, comp) * factor return int1e