def auxmol_set(self, mol, auxbas="weigend"): """ Generate 2c/3c electron integral (eri2c,eri3c) Generate ovlp matrix (S), and AO to Lowdin AO matrix transformation matrix (X) Args: mol: Mole class Default is ks.mol Kwargs: auxbas: str auxilliary basis for 2c/3c eri. Default is weigend Returns: eri3c: float 3 center eri. shape: (AO,AO,AUX) eri2c: float 2 center eri. shape: (AUX,AUX) """ auxmol = gto.Mole() auxmol.atom = mol.atom auxmol.basis = auxbas auxmol.build() self.auxmol = auxmol atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm,\ auxmol._bas, auxmol._env) eri3c = df.incore.aux_e2(mol, auxmol, intor="cint3c2e_sph", aosym="s1",\ comp=1 ) eri2c = df.incore.fill_2c2e(mol, auxmol) self.eri3c = eri3c.copy() self.eri2c = eri2c.copy() return eri3c, eri2c
def fuse_auxcell(mydf, auxcell): chgcell = make_modchg_basis(auxcell, mydf.eta) fused_cell = copy.copy(auxcell) fused_cell._atm, fused_cell._bas, fused_cell._env = \ gto.conc_env(auxcell._atm, auxcell._bas, auxcell._env, chgcell._atm, chgcell._bas, chgcell._env) fused_cell.rcut = max(auxcell.rcut, chgcell.rcut) aux_loc = auxcell.ao_loc_nr() naux = aux_loc[-1] modchg_offset = -numpy.ones((chgcell.natm, 8), dtype=int) smooth_loc = chgcell.ao_loc_nr() for i in range(chgcell.nbas): ia = chgcell.bas_atom(i) l = chgcell.bas_angular(i) modchg_offset[ia, l] = smooth_loc[i] def fuse(Lpq): Lpq, chgLpq = Lpq[:naux], Lpq[naux:] for i in range(auxcell.nbas): l = auxcell.bas_angular(i) ia = auxcell.bas_atom(i) p0 = modchg_offset[ia, l] if p0 >= 0: nd = (aux_loc[i + 1] - aux_loc[i]) // auxcell.bas_nctr(i) for i0, i1 in lib.prange(aux_loc[i], aux_loc[i + 1], nd): Lpq[i0:i1] -= chgLpq[p0:p0 + nd] return Lpq return fused_cell, fuse
def int_ket(_bas, intor): if len(_bas) == 0: return [] atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = [numpy.zeros((ni,nj), order='F', dtype=numpy.complex128) for k in range(nkpts)] out_ptrs = (ctypes.c_void_p*nkpts)( *[x.ctypes.data_as(ctypes.c_void_p) for x in out]) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) ptr_coords = numpy.asarray(atm[:cell.natm,gto.PTR_COORD], dtype=numpy.int32, order='C') drv = libpbc.PBCnr2c_drv drv(fintor, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coords.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), expLk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), (ctypes.c_int*4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p)) return out
def test_aux_e2_diff_bra_ket(self): mol1 = mol.copy() mol1.basis = 'sto3g' mol1.build(0, 0, verbose=0) atm1, bas1, env1 = gto.conc_env(atm, bas, env, mol1._atm, mol1._bas, mol1._env) ao_loc = gto.moleintor.make_loc(bas1, 'int3c2e_sph') shls_slice = (0, mol.nbas, mol.nbas+auxmol.nbas, mol.nbas+auxmol.nbas+mol1.nbas, mol.nbas, mol.nbas+auxmol.nbas) j3c = gto.moleintor.getints3c('int3c2e_sph', atm1, bas1, env1, comp=1, shls_slice=shls_slice, aosym='s1', ao_loc=ao_loc) nao = mol.nao_nr() naoj = mol1.nao_nr() naoaux = auxmol.nao_nr() eri0 = numpy.empty((nao,naoj,naoaux)) pi = 0 for i in range(mol.nbas): pj = 0 for j in range(mol.nbas+auxmol.nbas, len(bas1)): pk = 0 for k in range(mol.nbas, mol.nbas+auxmol.nbas): shls = (i, j, k) buf = gto.moleintor.getints_by_shell('int3c2e_sph', shls, atm1, bas1, env1) di, dj, dk = buf.shape eri0[pi:pi+di,pj:pj+dj,pk:pk+dk] = buf pk += dk pj += dj pi += di self.assertTrue(numpy.allclose(eri0, j3c))
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e_sph'): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3) buf = incore.aux_e2(cell, fakenuc, intor, aosym='s2', kptij_lst=kptij_lst) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) nao_pair = nao * (nao + 1) // 2 buf = buf.reshape(nkpts, nao_pair, nchg) mat = numpy.einsum('kxz,z->kx', buf, charge) if cell.dimension == 3: nucbar = sum([ z / nuccell.bas_exp(i)[0] for i, z in enumerate(cell.atom_charges()) ]) nucbar *= numpy.pi / cell.vol ovlp = cell.pbc_intor('int1e_ovlp_sph', 1, lib.HERMITIAN, kpts) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) mat[k] += nucbar * s return mat
def fuse_auxcell(mydf, auxcell): chgcell = make_modchg_basis(auxcell, mydf.eta) fused_cell = copy.copy(auxcell) fused_cell._atm, fused_cell._bas, fused_cell._env = \ gto.conc_env(auxcell._atm, auxcell._bas, auxcell._env, chgcell._atm, chgcell._bas, chgcell._env) aux_loc = auxcell.ao_loc_nr() naux = aux_loc[-1] modchg_offset = -numpy.ones((chgcell.natm,8), dtype=int) smooth_loc = chgcell.ao_loc_nr() for i in range(chgcell.nbas): ia = chgcell.bas_atom(i) l = chgcell.bas_angular(i) modchg_offset[ia,l] = smooth_loc[i] def fuse(Lpq): Lpq, chgLpq = Lpq[:naux], Lpq[naux:] for i in range(auxcell.nbas): l = auxcell.bas_angular(i) ia = auxcell.bas_atom(i) p0 = modchg_offset[ia,l] if p0 >= 0: nd = (aux_loc[i+1] - aux_loc[i]) // auxcell.bas_nctr(i) for i0, i1 in lib.prange(aux_loc[i], aux_loc[i+1], nd): Lpq[i0:i1] -= chgLpq[p0:p0+nd] return Lpq return fused_cell, fuse
def hellmann_feynman_df(mol, ia): """ Outputs the integral Z_I*<i|(r-R_I)/|r-R_I|^3|j> of only one Gaussian using as second Gaussian an 1s basis funtion of an He atom with alpha=1e-15 and coeff=1.00000. The result is divided by the norm of the He function. """ # Creating auxiliar Molecule intmol = gto.Mole() intmol.atom = '''He 0. 0. 0.''' intmol.basis = He_flat_basis intmol.build() # Merging molecules atm_x, bas_x, env_x = gto.conc_env(intmol._atm, intmol._bas, intmol._env,\ mol._atm, mol._bas, mol._env) PTR_RINV_ORIG = 4 env_x[PTR_RINV_ORIG:PTR_RINV_ORIG + 3] = mol.atom_coord(ia) HF_partial = gto.moleintor.getints('cint1e_drinv_sph', atm_x, bas_x, env_x, comp=3, hermi=0, aosym='s1', out=None) return -mol.atom_charge(ia)*\ np.hstack(HF_partial[:,:,:1])[1:]/gto.gto_norm(0,He_exp_flt)
def integral_one_gaussian_polarization(mol): """ Outputs the integral <i|r|j> with the only-one-Gaussian trick using as second Gaussian an 1s basis funtion of an He atom with alpha=1e-15 and coeff=1.00000. The result is divided by the norm of the 'dummy' He function. """ # Creating auxiliar Molecule intmol = gto.Mole() intmol.atom = '''He 0. 0. 0.''' intmol.basis = He_flat_basis intmol.build() # Merging molecules atm_x, bas_x, env_x = gto.conc_env(intmol._atm, intmol._bas, intmol._env, mol._atm, mol._bas, mol._env) # Computing the overlap PTR_COMMON_ORIG = 1 env_x[PTR_COMMON_ORIG:PTR_COMMON_ORIG + 3] = ( 0., 0., 0.) #(mol.atom_coord(1)-mol.atom_coord(0))/2. #mol.set_common_orig((1.,0.,0.)) HF_partial = gto.moleintor.getints('cint1e_r_sph', atm_x, bas_x, env_x, comp=3, hermi=0, aosym='s1', out=None) return np.hstack(HF_partial[:, :, :1])[1:] / gto.gto_norm(0, He_exp_flt)
def int_ket(_bas, intor): if len(_bas) == 0: return [] intor = cell._add_suffix(intor) atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = numpy.empty((nkpts, ni, nj), dtype=numpy.complex128) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) drv = libpbc.PBCnr2c_drv drv(fintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(nimgs), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, lib.c_null_ptr(), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(env.size)) return out
def test_aux_e2_diff_bra_ket(self): mol1 = mol.copy() mol1.basis = 'sto3g' mol1.build(0, 0, verbose=0) j3c = df.incore.aux_e2(mol, auxmol, intor='cint3c2e_sph', aosym='s1', mol1=mol1) nao = mol.nao_nr() naoj = mol1.nao_nr() naoaux = auxmol.nao_nr() j3c = j3c.reshape(nao,naoj,naoaux) atm1, bas1, env1 = gto.conc_env(atm, bas, env, mol1._atm, mol1._bas, mol1._env) eri0 = numpy.empty((nao,naoj,naoaux)) pi = 0 for i in range(mol.nbas): pj = 0 for j in range(mol.nbas+auxmol.nbas, len(bas1)): pk = 0 for k in range(mol.nbas, mol.nbas+auxmol.nbas): shls = (i, j, k) buf = gto.moleintor.getints_by_shell('cint3c2e_sph', shls, atm1, bas1, env1) di, dj, dk = buf.shape eri0[pi:pi+di,pj:pj+dj,pk:pk+dk] = buf pk += dk pj += dj pi += di self.assertTrue(numpy.allclose(eri0, j3c))
def auxmol_set(self, mol, auxbas = "weigend"): """ Generate 2c/3c electron integral (eri2c,eri3c) Generate ovlp matrix (S), and AO to Lowdin AO matrix transformation matrix (X) Args: mol: Mole class Default is ks.mol Kwargs: auxbas: str auxilliary basis for 2c/3c eri. Default is weigend Returns: eri3c: float 3 center eri. shape: (AO,AO,AUX) eri2c: float 2 center eri. shape: (AUX,AUX) """ auxmol = gto.Mole() auxmol.atom = mol.atom auxmol.basis = auxbas auxmol.build() self.auxmol = auxmol nao = mol.nao_nr() naux = auxmol.nao_nr() atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm,\ auxmol._bas, auxmol._env) eri3c = df.incore.aux_e2(mol, auxmol, intor="cint3c2e_sph", aosym="s1",\ comp=1 ) eri2c = df.incore.fill_2c2e(mol,auxmol) self.eri3c = eri3c.copy() self.eri2c = eri2c.copy() return eri3c, eri2c
def ft_ao(mol, Gv, shls_slice=None, b=numpy.eye(3), gxyz=None, Gvbase=None, verbose=None): ''' FT transform AO ''' if shls_slice is None: shls_slice = (0, mol.nbas) nGv = Gv.shape[0] if (gxyz is None or b is None or Gvbase is None # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int * 3)(0, 0, 0) p_b = (ctypes.c_double * 1)(0) eval_gz = 'GTO_Gv_general' else: if abs(b - numpy.diag(b.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_orth' else: eval_gz = 'GTO_Gv_nonorth' GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), numpy.zeros(3)) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int * 3)(*[len(x) for x in Gvbase]) fn = libcgto.GTO_ft_ovlp_mat intor = getattr(libcgto, 'GTO_ft_ovlp_sph') eval_gz = getattr(libcgto, eval_gz) fill = getattr(libcgto, 'GTO_ft_fill_s1') ghost_atm = numpy.array([[0, 0, 0, 0, 0, 0]], dtype=numpy.int32) ghost_bas = numpy.array([[0, 0, 1, 1, 0, 0, 3, 0]], dtype=numpy.int32) ghost_env = numpy.zeros(4) ghost_env[3] = numpy.sqrt(4 * numpy.pi) # s function spherical norm atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, ghost_atm, ghost_bas, ghost_env) ao_loc = mol.ao_loc_nr() nao = ao_loc[mol.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc, [nao + 1])), dtype=numpy.int32) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] mat = numpy.zeros((nGv, ni), order='F', dtype=numpy.complex) shls_slice = shls_slice + (mol.nbas, mol.nbas + 1) fn(intor, eval_gz, fill, mat.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), ctypes.c_double(0), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(atm)), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(bas)), env.ctypes.data_as(ctypes.c_void_p)) return mat
def int_ket(_bas, intor): if len(_bas) == 0: return [] intor = cell._add_suffix(intor) atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = numpy.empty((nkpts,ni,nj), dtype=numpy.complex128) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) drv = libpbc.PBCnr2c_drv drv(fintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(nimgs), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, lib.c_null_ptr(), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(env.size)) return out
def test_aux_e2_diff_bra_ket(self): mol1 = mol.copy() mol1.basis = 'sto3g' mol1.build(0, 0, verbose=0) atm1, bas1, env1 = gto.conc_env(atm, bas, env, mol1._atm, mol1._bas, mol1._env) ao_loc = gto.moleintor.make_loc(bas1, 'cint3c2e_sph') shls_slice = (0, mol.nbas, mol.nbas+auxmol.nbas, mol.nbas+auxmol.nbas+mol1.nbas, mol.nbas, mol.nbas+auxmol.nbas) j3c = _ri.nr_auxe2('cint3c2e_sph', atm1, bas1, env1, shls_slice, ao_loc, 's1', 1) nao = mol.nao_nr() naoj = mol1.nao_nr() naoaux = auxmol.nao_nr() eri0 = numpy.empty((nao,naoj,naoaux)) pi = 0 for i in range(mol.nbas): pj = 0 for j in range(mol.nbas+auxmol.nbas, len(bas1)): pk = 0 for k in range(mol.nbas, mol.nbas+auxmol.nbas): shls = (i, j, k) buf = gto.moleintor.getints_by_shell('cint3c2e_sph', shls, atm1, bas1, env1) di, dj, dk = buf.shape eri0[pi:pi+di,pj:pj+dj,pk:pk+dk] = buf pk += dk pj += dj pi += di self.assertTrue(numpy.allclose(eri0.reshape(-1,naoaux), j3c))
def integral_one_gaussian_from_overlap(mol): """ Outputs the integral of only one Gaussian using as second Gaussian in <i|j> an 1s basis funtion of an He atom with alpha=1e-15 and coeff=1.00000. The result is divided by the norm of the He function. """ # Creating auxiliar Molecule intmol = gto.Mole() intmol.atom = '''He 0. 0. 0.''' intmol.basis = He_flat_basis intmol.build() # Merging molecules atm_x, bas_x, env_x = gto.conc_env(intmol._atm, intmol._bas, intmol._env, mol._atm, mol._bas, mol._env) # Computing the overlap HF_partial = gto.moleintor.getints('cint1e_ovlp_sph', atm_x, bas_x, env_x, comp=1, hermi=0, aosym='s1', out=None) return np.hstack(HF_partial[:, :1])[1:] / gto.gto_norm(0, He_exp_flt)
def aux_e2(mol, auxmol, intor='cint3c2e_spinor', aosym='s1', comp=1, hermi=0): atm, bas, env = \ gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env) c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, dtype=numpy.double, order='C') natm = ctypes.c_int(mol.natm+auxmol.natm) nbas = ctypes.c_int(mol.nbas) nao = mol.nao_2c() naoaux = auxmol.nao_nr() if aosym == 's1': eri = numpy.empty((nao*nao,naoaux), dtype=numpy.complex) fill = getattr(libri, 'RIfill_r_s1_auxe2') else: eri = numpy.empty((nao*(nao+1)//2,naoaux), dtype=numpy.complex) fill = getattr(libri, 'RIfill_r_s2ij_auxe2') fintor = getattr(libri, intor) cintopt = _vhf.make_cintopt(c_atm, c_bas, c_env, intor) libri.RIr_3c2e_auxe2_drv(fintor, fill, eri.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(0), ctypes.c_int(mol.nbas), ctypes.c_int(mol.nbas), ctypes.c_int(auxmol.nbas), ctypes.c_int(1), cintopt, c_atm.ctypes.data_as(ctypes.c_void_p), natm, c_bas.ctypes.data_as(ctypes.c_void_p), nbas, c_env.ctypes.data_as(ctypes.c_void_p)) return eri
def ft_ao(mol, Gv, shls_slice=None, invh=None, gxyz=None, gs=None, verbose=None): ''' FT transform AO ''' if shls_slice is None: shls_slice = (0, mol.nbas) nGv = Gv.shape[0] if gxyz is None or invh is None or gs is None: GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_invh = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*gs) # Guess what type of eval_gz to use if isinstance(invh, numpy.ndarray) and invh.shape == (3,3): p_invh = invh.ctypes.data_as(ctypes.c_void_p) if numpy.allclose(invh-numpy.diag(invh.diagonal()), 0): eval_gz = 'GTO_Gv_uniform_orth' else: eval_gz = 'GTO_Gv_uniform_nonorth' else: invh = numpy.hstack(invh) p_invh = invh.ctypes.data_as(ctypes.c_void_p) eval_gz = 'GTO_Gv_nonuniform_orth' fn = libcgto.GTO_ft_ovlp_mat intor = getattr(libcgto, 'GTO_ft_ovlp_sph') eval_gz = getattr(libcgto, eval_gz) fill = getattr(libcgto, 'GTO_ft_fill_s1') ghost_atm = numpy.array([[0,0,0,0,0,0]], dtype=numpy.int32) ghost_bas = numpy.array([[0,0,1,1,0,0,3,0]], dtype=numpy.int32) ghost_env = numpy.zeros(4) ghost_env[3] = numpy.sqrt(4*numpy.pi) # s function spheric norm atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, ghost_atm, ghost_bas, ghost_env) ao_loc = mol.ao_loc_nr() nao = ao_loc[mol.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc, [nao+1])), dtype=numpy.int32) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] mat = numpy.zeros((nGv,ni), order='F', dtype=numpy.complex) shls_slice = shls_slice + (mol.nbas, mol.nbas+1) fn(intor, eval_gz, fill, mat.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), ctypes.c_double(0), GvT.ctypes.data_as(ctypes.c_void_p), p_invh, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(atm)), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(bas)), env.ctypes.data_as(ctypes.c_void_p)) return mat
def ft_ao(mol, Gv, shls_slice=None, b=numpy.eye(3), gxyz=None, Gvbase=None, verbose=None): ''' FT transform AO ''' if shls_slice is None: shls_slice = (0, mol.nbas) nGv = Gv.shape[0] if (gxyz is None or b is None or Gvbase is None # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_b = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: if abs(b-numpy.diag(b.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_orth' else: eval_gz = 'GTO_Gv_nonorth' GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), numpy.zeros(3)) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*[len(x) for x in Gvbase]) fn = libcgto.GTO_ft_fill_drv if mol.cart: intor = getattr(libcgto, 'GTO_ft_ovlp_cart') else: intor = getattr(libcgto, 'GTO_ft_ovlp_sph') eval_gz = getattr(libcgto, eval_gz) fill = getattr(libcgto, 'GTO_ft_fill_s1') ghost_atm = numpy.array([[0,0,0,0,0,0]], dtype=numpy.int32) ghost_bas = numpy.array([[0,0,1,1,0,0,3,0]], dtype=numpy.int32) ghost_env = numpy.zeros(4) ghost_env[3] = numpy.sqrt(4*numpy.pi) # s function spherical norm atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, ghost_atm, ghost_bas, ghost_env) ao_loc = mol.ao_loc_nr() nao = ao_loc[mol.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc, [nao+1])), dtype=numpy.int32) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] mat = numpy.zeros((nGv,ni), order='F', dtype=numpy.complex) shls_slice = shls_slice + (mol.nbas, mol.nbas+1) fn(intor, eval_gz, fill, mat.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(1), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), ctypes.c_double(0), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(atm)), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(bas)), env.ctypes.data_as(ctypes.c_void_p)) return mat
def _int_nuc_vloc(mydf, nuccell, kpts, intor='cint3c2e_sph'): '''Vnuc - Vloc''' cell = mydf.cell rcut = max(cell.rcut, nuccell.rcut) Ls = cell.get_lattice_Ls(rcut=rcut) expLk = numpy.asarray(numpy.exp(1j * numpy.dot(Ls, kpts.T)), order='C') nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) nao = cell.nao_nr() buf = [ numpy.zeros((nao, nao, fakenuc.natm), order='F', dtype=numpy.complex128) for k in range(nkpts) ] ints = incore._wrap_int3c(cell, fakenuc, intor, 1, Ls, buf) atm, bas, env = ints._envs[:3] c_shls_slice = (ctypes.c_int * 6)(0, cell.nbas, cell.nbas, cell.nbas * 2, cell.nbas * 2, cell.nbas * 2 + fakenuc.natm) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm, gto.PTR_COORD] ptr_coordL = numpy.vstack( (ptr_coordL, ptr_coordL + 1, ptr_coordL + 2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l + 1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) for k in range(nkpts): v = numpy.einsum('ijz,z->ij', buf[k], charge) buf[k] = lib.pack_tril(v + v.T.conj()) if cell.dimension == 3: nucbar = sum([ z / nuccell.bas_exp(i)[0] for i, z in enumerate(cell.atom_charges()) ]) nucbar *= numpy.pi / cell.vol ovlp = cell.pbc_intor('cint1e_ovlp_sph', 1, lib.HERMITIAN, kpts) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) buf[k] += nucbar * s return buf
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e', aosym='s2', comp=1): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3) buf = incore.aux_e2(cell, fakenuc, intor, aosym=aosym, comp=comp, kptij_lst=kptij_lst) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) if aosym == 's1': nao_pair = nao**2 else: nao_pair = nao * (nao + 1) // 2 if comp == 1: buf = buf.reshape(nkpts, nao_pair, nchg) mat = numpy.einsum('kxz,z->kx', buf, charge) else: buf = buf.reshape(nkpts, comp, nao_pair, nchg) mat = numpy.einsum('kcxz,z->kcx', buf, charge) # vbar is the interaction between the background charge # and the compensating function. 0D, 1D, 2D do not have vbar. if cell.dimension == 3 and intor in ('int3c2e', 'int3c2e_sph', 'int3c2e_cart'): assert (comp == 1) charge = -cell.atom_charges() nucbar = sum([z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)]) nucbar *= numpy.pi / cell.vol ovlp = cell.pbc_intor('int1e_ovlp', 1, lib.HERMITIAN, kpts) for k in range(nkpts): if aosym == 's1': mat[k] -= nucbar * ovlp[k].reshape(nao_pair) else: mat[k] -= nucbar * lib.pack_tril(ovlp[k]) return mat
def test_rinv_with_zeta(self): with mol.with_rinv_orig((.2,.3,.4)), mol.with_rinv_zeta(2.2): v1 = mol.intor('int1e_rinv_sph') pmol = gto.M(atom='Ghost .2 .3 .4', unit='b', basis={'Ghost':[[0,(2.2*.5, 1)]]}) pmol._atm, pmol._bas, pmol._env = \ gto.conc_env(mol._atm, mol._bas, mol._env, pmol._atm, pmol._bas, pmol._env) shls_slice = (pmol.nbas-1,pmol.nbas, pmol.nbas-1,pmol.nbas, 0, pmol.nbas, 0, pmol.nbas) v0 = pmol.intor('int2e_sph', shls_slice=shls_slice) nao = pmol.nao_nr() v0 = v0.reshape(nao,nao)[:-1,:-1] self.assertTrue(numpy.allclose(v0, v1))
def auxmol_set(self, auxbas="weigend"): print "GENERATING INTEGRALS" auxmol = gto.Mole() auxmol.atom = self.mol.atom auxmol.basis = auxbas auxmol.build() mol = self.mol nao = self.n_ao = mol.nao_nr() naux = self.n_aux = auxmol.nao_nr() #print nao #print naux atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env) eri3c = np.empty((nao, nao, naux)) pi = 0 for i in range(mol.nbas): pj = 0 for j in range(mol.nbas): pk = 0 for k in range(mol.nbas, mol.nbas + auxmol.nbas): shls = (i, j, k) buf = gto.getints_by_shell('cint3c2e_sph', shls, atm, bas, env) di, dj, dk = buf.shape eri3c[pi:pi + di, pj:pj + dj, pk:pk + dk] = buf pk += dk pj += dj pi += di print "ERI3C INTEGRALS GENERATED" eri2c = np.empty((naux, naux)) pk = 0 for k in range(mol.nbas, mol.nbas + auxmol.nbas): pl = 0 for l in range(mol.nbas, mol.nbas + auxmol.nbas): shls = (k, l) buf = gto.getints_by_shell('cint2c2e_sph', shls, atm, bas, env) dk, dl = buf.shape eri2c[pk:pk + dk, pl:pl + dl] = buf pl += dl pk += dk print "ERI2C INTEGRALS GENERATED" self.eri3c = eri3c self.eri2c = eri2c RSinv = MatrixPower(eri2c, -0.5) with sess.as_default(): self.B = tf.einsum( 'ijp,pq->ijq', self.toTF(eri3c), self.toTF(RSinv) ).eval( ) #self.B = np.einsum('ijp,pq->ijq', self.eri3c, RSinv) # (AO,AO,n_aux) return
def setUpModule(): global mol, auxmol, atm, bas, env mol = gto.Mole() mol.build( verbose = 0, atom = '''O 0 0. 0. 1 0 -0.757 0.587 1 0 0.757 0.587''', basis = 'cc-pvdz', ) auxmol = df.addons.make_auxmol(mol, 'weigend') atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env)
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e_sph'): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = aft._fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3) ishs = mpi.work_balanced_partition(numpy.arange(cell.nbas), costs=numpy.arange(1, cell.nbas + 1)) if len(ishs) > 0: ish0, ish1 = ishs[0], ishs[-1] + 1 buf = incore.aux_e2(cell, fakenuc, intor, aosym='s2', kptij_lst=kptij_lst, shls_slice=(ish0, ish1, 0, cell.nbas, 0, fakenuc.nbas)) else: buf = numpy.zeros(0) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) nao_pair = nao * (nao + 1) // 2 buf = buf.reshape(nkpts, -1, nchg) # scaled by 1./mpi.pool.size because nuc is mpi.reduced in get_nuc function buf = numpy.einsum('kxz,z->kx', buf, 1. / mpi.pool.size * charge) mat = numpy.empty((nkpts, nao_pair), dtype=numpy.complex128) for k in range(nkpts): mat[k] = mpi.allgather(buf[k]) if rank == 0 and cell.dimension == 3: nucbar = sum([ z / nuccell.bas_exp(i)[0] for i, z in enumerate(cell.atom_charges()) ]) nucbar *= numpy.pi / cell.vol ovlp = cell.pbc_intor('int1e_ovlp_sph', 1, lib.HERMITIAN, kpts) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) mat[k] += nucbar * s return mat
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e_sph', aosym='s2', comp=1): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = aft._fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts,kpts)).reshape(-1,2,3) ishs = mpi.work_balanced_partition(numpy.arange(cell.nbas), costs=numpy.arange(1, cell.nbas+1)) if len(ishs) > 0: ish0, ish1 = ishs[0], ishs[-1]+1 buf = incore.aux_e2(cell, fakenuc, intor, aosym='s2', kptij_lst=kptij_lst, shls_slice=(ish0,ish1,0,cell.nbas,0,fakenuc.nbas)) else: buf = numpy.zeros(0) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) nao_pair = nao*(nao+1)//2 buf = buf.reshape(nkpts,-1,nchg) # scaled by 1./mpi.pool.size because nuc is mpi.reduced in get_nuc function buf = numpy.einsum('kxz,z->kx', buf, 1./mpi.pool.size*charge) mat = numpy.empty((nkpts,nao_pair), dtype=numpy.complex128) for k in range(nkpts): mat[k] = mpi.allgather(buf[k]) if (rank == 0 and cell.dimension == 3 and intor in ('int3c2e', 'int3c2e_sph', 'int3c2e_cart')): assert(comp == 1) charges = cell.atom_charges() nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charges)]) nucbar *= numpy.pi/cell.vol ovlp = cell.pbc_intor('int1e_ovlp_sph', 1, lib.HERMITIAN, kpts) for k in range(nkpts): if aosym == 's1': mat[k] += nucbar * ovlp[k].reshape(nao_pair) else: mat[k] += nucbar * lib.pack_tril(ovlp[k]) return mat
def test_rinv_with_zeta(self): with mol.with_rinv_orig((.2, .3, .4)), mol.with_rinv_zeta(2.2): v1 = mol.intor('int1e_rinv_sph') pmol = gto.M(atom='Ghost .2 .3 .4', unit='b', basis={'Ghost': [[0, (2.2 * .5, 1)]]}) pmol._atm, pmol._bas, pmol._env = \ gto.conc_env(mol._atm, mol._bas, mol._env, pmol._atm, pmol._bas, pmol._env) shls_slice = (pmol.nbas - 1, pmol.nbas, pmol.nbas - 1, pmol.nbas, 0, pmol.nbas, 0, pmol.nbas) v0 = pmol.intor('int2e_sph', shls_slice=shls_slice) nao = pmol.nao_nr() v0 = v0.reshape(nao, nao)[:-1, :-1] self.assertTrue(numpy.allclose(v0, v1))
def test_rinv_with_zeta(self): mol.set_rinv_orig_((.2,.3,.4)) mol.set_rinv_zeta_(2.2) v1 = mol.intor('cint1e_rinv_sph') mol.set_rinv_zeta_(0) pmol = gto.M(atom='Ghost .2 .3 .4', unit='b', basis={'Ghost':[[0,(2.2*.5, 1)]]}) pmol._atm, pmol._bas, pmol._env = \ gto.conc_env(mol._atm, mol._bas, mol._env, pmol._atm, pmol._bas, pmol._env) pmol.natm = len(pmol._atm) pmol.nbas = len(pmol._bas) v0 = pmol.intor('cint2e_sph', bras=[pmol.nbas-1], kets=[pmol.nbas-1]) nao = pmol.nao_nr() v0 = v0.reshape(nao,nao)[:-1,:-1] self.assertTrue(numpy.allclose(v0, v1))
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e', aosym='s2', comp=1): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts,kpts)).reshape(-1,2,3) buf = incore.aux_e2(cell, fakenuc, intor, aosym=aosym, comp=comp, kptij_lst=kptij_lst) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) if aosym == 's1': nao_pair = nao**2 else: nao_pair = nao*(nao+1)//2 if comp == 1: buf = buf.reshape(nkpts,nao_pair,nchg) mat = numpy.einsum('kxz,z->kx', buf, charge) else: buf = buf.reshape(nkpts,comp,nao_pair,nchg) mat = numpy.einsum('kcxz,z->kcx', buf, charge) # vbar is the interaction between the background charge # and the compensating function. 0D, 1D, 2D do not have vbar. if cell.dimension == 3 and intor in ('int3c2e', 'int3c2e_sph', 'int3c2e_cart'): assert(comp == 1) charge = -cell.atom_charges() nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charge)]) nucbar *= numpy.pi/cell.vol ovlp = cell.pbc_intor('int1e_ovlp', 1, lib.HERMITIAN, kpts) for k in range(nkpts): if aosym == 's1': mat[k] -= nucbar * ovlp[k].reshape(nao_pair) else: mat[k] -= nucbar * lib.pack_tril(ovlp[k]) return mat
def _int_nuc_vloc(cell, nuccell, kpts): '''Vnuc - Vloc''' nimgs = numpy.max((cell.nimgs, nuccell.nimgs), axis=0) Ls = numpy.asarray(cell.get_lattice_Ls(nimgs), order='C') expLk = numpy.asarray(numpy.exp(1j * numpy.dot(Ls, kpts.T)), order='C') nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) nao = cell.nao_nr() buf = [ numpy.zeros((nao, nao, fakenuc.natm), order='F', dtype=numpy.complex128) for k in range(nkpts) ] ints = incore._wrap_int3c(cell, fakenuc, 'cint3c2e_sph', 1, Ls, buf) atm, bas, env = ints._envs[:3] c_shls_slice = (ctypes.c_int * 6)(0, cell.nbas, cell.nbas, cell.nbas * 2, cell.nbas * 2, cell.nbas * 2 + fakenuc.natm) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm, gto.PTR_COORD] ptr_coordL = numpy.vstack( (ptr_coordL, ptr_coordL + 1, ptr_coordL + 2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l + 1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) for k, kpt in enumerate(kpts): v = numpy.einsum('ijz,z->ij', buf[k], charge) if gamma_point(kpt): buf[k] = v.real + v.real.T else: buf[k] = v + v.T.conj() return buf
def build(self, j_only=False, with_j3c=True): log = logger.Logger(self.stdout, self.verbose) t1 = (time.clock(), time.time()) cell = self.cell if self.eta is None: self.eta = estimate_eta(cell) log.debug('Set smooth gaussian eta to %.9g', self.eta) self.dump_flags() auxcell = make_modrho_basis(cell, self.auxbasis, self.eta) chgcell = make_modchg_basis(auxcell, self.eta) self._j_only = j_only if j_only: kptij_lst = numpy.hstack((self.kpts,self.kpts)).reshape(-1,2,3) else: kptij_lst = [(ki, self.kpts[j]) for i, ki in enumerate(self.kpts) for j in range(i+1)] kptij_lst = numpy.asarray(kptij_lst) if not isinstance(self._cderi, str): if isinstance(self._cderi_file, str): self._cderi = self._cderi_file else: self._cderi = self._cderi_file.name if with_j3c: if self.approx_sr_level == 0: build_Lpq_pbc(self, auxcell, chgcell, kptij_lst) elif self.approx_sr_level == 1: build_Lpq_pbc(self, auxcell, chgcell, numpy.zeros((1,2,3))) elif self.approx_sr_level == 2: build_Lpq_nonpbc(self, auxcell, chgcell) elif self.approx_sr_level == 3: build_Lpq_1c_approx(self, auxcell, chgcell) t1 = log.timer_debug1('Lpq', *t1) _make_j3c(self, cell, auxcell, chgcell, kptij_lst) t1 = log.timer_debug1('j3c', *t1) # Merge chgcell into auxcell auxcell._atm, auxcell._bas, auxcell._env = \ gto.conc_env(auxcell._atm, auxcell._bas, auxcell._env, chgcell._atm, chgcell._bas, chgcell._env) self.auxcell = auxcell return self
def calc_eri2c(mol, auxmol, Ikl): nao = mol.nao_nr() naux = auxmol.nao_nr() # Merging M1 and M2 to compute the integrals. atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env) eri2c = np.empty((naux, naux)) pk = 0 for k in range(mol.nbas, mol.nbas + auxmol.nbas): pl = 0 for l in range(mol.nbas, mol.nbas + auxmol.nbas): shls = (k, l) buf = gto.getints_by_shell(Ikl, shls, atm, bas, env) dk, dl = buf.shape eri2c[pk:pk + dk, pl:pl + dl] = buf pl += dl pk += dk return eri2c
def auxmol_set(self, auxbas="weigend"): print "GENERATING INTEGRALS" auxmol = gto.Mole() auxmol.atom = self.mol.atom auxmol.basis = auxbas auxmol.build() mol = self.mol nao = self.n_ao = mol.nao_nr() naux = self.n_aux = auxmol.nao_nr() atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env) eri3c = df.incore.aux_e1(mol, auxmol, intor='cint3c2e_sph', aosym='s1', comp=1) eri3c = eri3c.reshape(naux, nao, nao).T print "ERI3C INTEGRALS GENERATED" eri2c = np.empty((naux, naux)) pk = 0 for k in range(mol.nbas, mol.nbas + auxmol.nbas): pl = 0 for l in range(mol.nbas, mol.nbas + auxmol.nbas): shls = (k, l) buf = gto.getints_by_shell('cint2c2e_sph', shls, atm, bas, env) dk, dl = buf.shape eri2c[pk:pk + dk, pl:pl + dl] = buf pl += dl pk += dk print "ERI2C INTEGRALS GENERATED" self.eri3c = eri3c self.eri2c = eri2c RSinv = MatrixPower(eri2c, -0.5) self.B = np.einsum('ijp,pq->ijq', self.eri3c, RSinv) # (AO,AO,n_aux) # change to (LAO,LAO,n_aux) BpqR self.S = self.the_scf.get_ovlp() # (ao X ao) self.X = MatrixPower(self.S, -1. / 2.) # AO, LAO print "BpqR GENERATED" return
def _int_nuc_vloc(cell, nuccell, kpts): '''Vnuc - Vloc''' nimgs = numpy.max((cell.nimgs, nuccell.nimgs), axis=0) Ls = numpy.asarray(cell.get_lattice_Ls(nimgs), order='C') expLk = numpy.asarray(numpy.exp(1j*numpy.dot(Ls, kpts.T)), order='C') nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) nao = cell.nao_nr() buf = [numpy.zeros((nao,nao,fakenuc.natm), order='F', dtype=numpy.complex128) for k in range(nkpts)] ints = incore._wrap_int3c(cell, fakenuc, 'cint3c2e_sph', 1, Ls, buf) atm, bas, env = ints._envs[:3] c_shls_slice = (ctypes.c_int*6)(0, cell.nbas, cell.nbas, cell.nbas*2, cell.nbas*2, cell.nbas*2+fakenuc.natm) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm,gto.PTR_COORD] ptr_coordL = numpy.vstack((ptr_coordL,ptr_coordL+1,ptr_coordL+2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l+1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) for k, kpt in enumerate(kpts): v = numpy.einsum('ijz,z->ij', buf[k], charge) if gamma_point(kpt): buf[k] = v.real + v.real.T else: buf[k] = v + v.T.conj() return buf
def int_ket(_bas, intor): if len(_bas) == 0: return [] atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = [ numpy.zeros((ni, nj), order='F', dtype=numpy.complex128) for k in range(nkpts) ] out_ptrs = (ctypes.c_void_p * nkpts)(*[x.ctypes.data_as(ctypes.c_void_p) for x in out]) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) ptr_coords = numpy.asarray(atm[:cell.natm, gto.PTR_COORD], dtype=numpy.int32, order='C') drv = libpbc.PBCnr2c_drv drv(fintor, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coords.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), expLk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), (ctypes.c_int * 4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p)) return out
def calc_eri3c(mol, auxmol, IklM): nao = mol.nao_nr() naux = auxmol.nao_nr() # Merging M1 and M2 to compute the integrals. atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env) eri3c = np.empty((nao, nao, naux)) pi = 0 for i in range(mol.nbas): pj = 0 for j in range(mol.nbas): pk = 0 for k in range(mol.nbas, mol.nbas + auxmol.nbas): shls = (i, j, k) buf = gto.getints_by_shell(IklM, shls, atm, bas, env) di, dj, dk = buf.shape eri3c[pi:pi + di, pj:pj + dj, pk:pk + dk] = buf pk += dk pj += dj pi += di return eri3c
def get_jk(mols, dms, scripts=['ijkl,ji->kl'], intor='cint2e_sph', aosym='s1', comp=1, hermi=0, shls_slice=None, verbose=logger.WARN): '''Compute J/K matrices for the given density matrix Args: mols : an instance of :class:`Mole` or a list of `Mole` objects dms : ndarray or list of ndarrays A density matrix or a list of density matrices Kwargs: hermi : int Whether J/K matrix is hermitian | 0 : no hermitian or symmetric | 1 : hermitian | 2 : anti-hermitian intor : str 2-electron integral name. See :func:`getints` for the complete list of available 2-electron integral names aosym : int or str Permutation symmetry for the AO integrals | 4 or '4' or 's4': 4-fold symmetry (default) | '2ij' or 's2ij' : symmetry between i, j in (ij|kl) | '2kl' or 's2kl' : symmetry between k, l in (ij|kl) | 1 or '1' or 's1': no symmetry | 'a4ij' : 4-fold symmetry with anti-symmetry between i, j in (ij|kl) | 'a4kl' : 4-fold symmetry with anti-symmetry between k, l in (ij|kl) | 'a2ij' : anti-symmetry between i, j in (ij|kl) | 'a2kl' : anti-symmetry between k, l in (ij|kl) comp : int Components of the integrals, e.g. cint2e_ip_sph has 3 components. scripts : a list of strings Contraction description (following numpy.einsum convention) based on letters [ijkl]. Each script will be one-to-one applied to each entry of dms. So it must have the same number of elements as the dms, len(scripts) == len(dms). shls_slice : 8-element list (ish_start, ish_end, jsh_start, jsh_end, ksh_start, ksh_end, lsh_start, lsh_end) Returns: Depending on the number of density matrices, the function returns one J/K matrix or a list of J/K matrices (the same number of entries as the input dms). Each JK matrices may be a 2D array or 3D array if the AO integral has multiple components. Examples: >>> from pyscf import gto >>> mol = gto.M(atom='H 0 -.5 0; H 0 .5 0', basis='cc-pvdz') >>> nao = mol.nao_nr() >>> dm = numpy.random.random((nao,nao)) >>> # Default, Coulomb matrix >>> vj = get_jk(mol, dm) >>> # Coulomb matrix with 8-fold permutation symmetry for AO integrals >>> vj = get_jk(mol, dm, 'ijkl,ji->kl', aosym='s8') >>> # Exchange matrix with 8-fold permutation symmetry for AO integrals >>> vk = get_jk(mol, dm, 'ijkl,jk->il', aosym='s8') >>> # Compute coulomb and exchange matrices together >>> vj, vk = get_jk(mol, (dm,dm), ('ijkl,ji->kl','ijkl,li->kj'), aosym='s8') >>> # Analytical gradients for coulomb matrix >>> j1 = get_jk(mol, dm, 'ijkl,lk->ij', intor='cint2e_ip1_sph', aosym='s2kl', comp=3) >>> # contraction across two molecules >>> mol1 = gto.M(atom='He 2 0 0', basis='6-31g') >>> nao1 = mol1.nao_nr() >>> dm1 = numpy.random.random((nao1,nao1)) >>> # Coulomb interaction between two molecules, note 4-fold symmetry can be applied >>> jcross = get_jk((mol1,mol1,mol,mol), dm, scripts='ijkl,lk->ij', aosym='s4') >>> ecoul = numpy.einsum('ij,ij', jcross, dm1) >>> # Exchange interaction between two molecules, no symmetry can be used >>> kcross = get_jk((mol1,mol,mol,mol1), dm, scripts='ijkl,jk->il') >>> ex = numpy.einsum('ij,ji', kcross, dm1) >>> # Analytical gradients for coulomb matrix between two molecules >>> jcros1 = get_jk((mol1,mol1,mol,mol), dm, scripts='ijkl,lk->ij', intor='cint2e_ip1_sph', comp=3) >>> # Analytical gradients for coulomb interaction between 1s density and the other molecule >>> jpart1 = get_jk((mol1,mol1,mol,mol), dm, scripts='ijkl,lk->ij', intor='cint2e_ip1_sph', comp=3, ... shls_slice=(0,1,0,1,0,mol.nbas,0,mol.nbas)) ''' if isinstance(mols, (tuple, list)): assert(len(mols) == 4) if shls_slice is None: shls_slice = numpy.array([(0, mol.nbas) for mol in mols]) else: shls_slice = numpy.asarray(shls_slice).reshape(4,2) # concatenate unique mols and build corresponding shls_slice mol_ids = [id(mol) for mol in mols] atm, bas, env = mols[0]._atm, mols[0]._bas, mols[0]._env bas_start = numpy.zeros(4, dtype=int) for m in range(1,4): first = mol_ids.index(mol_ids[m]) if first == m: # the unique mol bas_start[m] = bas.shape[0] atm, bas, env = gto.conc_env(atm, bas, env, mols[m]._atm, mols[m]._bas, mols[m]._env) else: bas_start[m] = bas_start[first] shls_slice[m] += bas_start[m] shls_slice = shls_slice.flatten() else: atm, bas, env = mols._atm, mols._bas, mols._env if shls_slice is None: shls_slice = (0, mols.nbas) * 4 if isinstance(scripts, str): scripts = [scripts] if isinstance(dms, numpy.ndarray) and dms.ndim == 2: dms = [dms] assert(len(scripts) == len(dms)) #format scripts descript = [] for script in scripts: dmsym, vsym = script.lower().split(',')[1].split('->') if hermi == 0: descript.append('->'.join((dmsym,'s1'+vsym))) else: descript.append('->'.join((dmsym,'s2'+vsym))) vs = _vhf.direct_bindm(intor, aosym, descript, dms, comp, atm, bas, env, shls_slice=shls_slice) if hermi != 0: for v in vs: if v.ndim == 3: for vi in v: pyscf.lib.hermi_triu(vi, hermi, inplace=True) else: pyscf.lib.hermi_triu(v, hermi, inplace=True) return vs
def auxmol_set(self,auxbas = "weigend"): print "====================" print "GENERATING INTEGRALS" print "====================" auxmol = gto.Mole() auxmol.atom = self.hf1.mol.atom auxmol.basis = auxbas auxmol.build() mol = self.hf1.mol nao = self.n_ao[0] = int(mol.nao_nr()) naux = self.n_aux[0] = auxmol.nao_nr() atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env) eri3c = np.empty((nao,nao,naux)) pi = 0 for i in range(mol.nbas): pj = 0 for j in range(mol.nbas): pk = 0 for k in range(mol.nbas, mol.nbas+auxmol.nbas): shls = (i, j, k) buf = gto.getints_by_shell('cint3c2e_sph', shls, atm, bas, env) di, dj, dk = buf.shape eri3c[pi:pi+di,pj:pj+dj,pk:pk+dk] = buf pk += dk pj += dj pi += di eri2c = np.empty((naux,naux)) pk = 0 for k in range(mol.nbas, mol.nbas+auxmol.nbas): pl = 0 for l in range(mol.nbas, mol.nbas+auxmol.nbas): shls = (k, l) buf = gto.getints_by_shell('cint2c2e_sph', shls, atm, bas, env) dk, dl = buf.shape eri2c[pk:pk+dk,pl:pl+dl] = buf pl += dl pk += dk self.eri3c.append(eri3c) self.eri2c.append(eri2c) print "\nAA INT GENERATED" self.eri3c.append(eri3c) self.eri2c.append(eri2c) RSinv = MatrixPower(eri2c,-0.5) self.B0 = np.einsum('ijp,pq->ijq', eri3c, RSinv) auxmol = mol = nao = naux = None auxmol = gto.Mole() auxmol.atom = self.hf3.mol.atom auxmol.basis = auxbas auxmol.build() mol = self.hf3.mol nao = self.n_ao[2] = int(mol.nao_nr()) naux = self.n_aux[2] = auxmol.nao_nr() atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env) eri3c = np.empty((nao,nao,naux)) pi = 0 for i in range(mol.nbas): pj = 0 for j in range(mol.nbas): pk = 0 for k in range(mol.nbas, mol.nbas+auxmol.nbas): shls = (i, j, k) buf = gto.getints_by_shell('cint3c2e_sph', shls, atm, bas, env) di, dj, dk = buf.shape eri3c[pi:pi+di,pj:pj+dj,pk:pk+dk] = buf pk += dk pj += dj pi += di eri2c = np.empty((naux,naux)) pk = 0 for k in range(mol.nbas, mol.nbas+auxmol.nbas): pl = 0 for l in range(mol.nbas, mol.nbas+auxmol.nbas): shls = (k, l) buf = gto.getints_by_shell('cint2c2e_sph', shls, atm, bas, env) dk, dl = buf.shape eri2c[pk:pk+dk,pl:pl+dl] = buf pl += dl pk += dk # if(self.hyb[0] > 0.01): # eri3cBO = np.zeros((nao,nao,naux)) # for i in range(naux): # eri3cBO[:,:,i] = TransMat(eri3c[:,:,i],self.U) # eri3c = eri3cBO.copy() print "\nWHOLE INT GENERATED" self.eri3c.append(eri3c) self.eri2c.append(eri2c) RSinv = MatrixPower(eri2c,-0.5) self.B1 = np.einsum('ijp,pq->ijq', eri3c, RSinv) auxmol = mol = nao = naux = None return
def get_jk(mols, dms, scripts=['ijkl,ji->kl'], intor='int2e_sph', aosym='s1', comp=1, hermi=0, shls_slice=None, verbose=logger.WARN): '''Compute J/K matrices for the given density matrix Args: mols : an instance of :class:`Mole` or a list of `Mole` objects dms : ndarray or list of ndarrays A density matrix or a list of density matrices Kwargs: hermi : int Whether J/K matrix is hermitian | 0 : no hermitian or symmetric | 1 : hermitian | 2 : anti-hermitian intor : str 2-electron integral name. See :func:`getints` for the complete list of available 2-electron integral names aosym : int or str Permutation symmetry for the AO integrals | 4 or '4' or 's4': 4-fold symmetry (default) | '2ij' or 's2ij' : symmetry between i, j in (ij|kl) | '2kl' or 's2kl' : symmetry between k, l in (ij|kl) | 1 or '1' or 's1': no symmetry | 'a4ij' : 4-fold symmetry with anti-symmetry between i, j in (ij|kl) | 'a4kl' : 4-fold symmetry with anti-symmetry between k, l in (ij|kl) | 'a2ij' : anti-symmetry between i, j in (ij|kl) | 'a2kl' : anti-symmetry between k, l in (ij|kl) comp : int Components of the integrals, e.g. cint2e_ip_sph has 3 components. scripts : a list of strings Contraction description (following numpy.einsum convention) based on letters [ijkl]. Each script will be one-to-one applied to each entry of dms. So it must have the same number of elements as the dms, len(scripts) == len(dms). shls_slice : 8-element list (ish_start, ish_end, jsh_start, jsh_end, ksh_start, ksh_end, lsh_start, lsh_end) Returns: Depending on the number of density matrices, the function returns one J/K matrix or a list of J/K matrices (the same number of entries as the input dms). Each JK matrices may be a 2D array or 3D array if the AO integral has multiple components. Examples: >>> from pyscf import gto >>> mol = gto.M(atom='H 0 -.5 0; H 0 .5 0', basis='cc-pvdz') >>> nao = mol.nao_nr() >>> dm = numpy.random.random((nao,nao)) >>> # Default, Coulomb matrix >>> vj = get_jk(mol, dm) >>> # Coulomb matrix with 8-fold permutation symmetry for AO integrals >>> vj = get_jk(mol, dm, 'ijkl,ji->kl', aosym='s8') >>> # Exchange matrix with 8-fold permutation symmetry for AO integrals >>> vk = get_jk(mol, dm, 'ijkl,jk->il', aosym='s8') >>> # Compute coulomb and exchange matrices together >>> vj, vk = get_jk(mol, (dm,dm), ('ijkl,ji->kl','ijkl,li->kj'), aosym='s8') >>> # Analytical gradients for coulomb matrix >>> j1 = get_jk(mol, dm, 'ijkl,lk->ij', intor='int2e_ip1_sph', aosym='s2kl', comp=3) >>> # contraction across two molecules >>> mol1 = gto.M(atom='He 2 0 0', basis='6-31g') >>> nao1 = mol1.nao_nr() >>> dm1 = numpy.random.random((nao1,nao1)) >>> # Coulomb interaction between two molecules, note 4-fold symmetry can be applied >>> jcross = get_jk((mol1,mol1,mol,mol), dm, scripts='ijkl,lk->ij', aosym='s4') >>> ecoul = numpy.einsum('ij,ij', jcross, dm1) >>> # Exchange interaction between two molecules, no symmetry can be used >>> kcross = get_jk((mol1,mol,mol,mol1), dm, scripts='ijkl,jk->il') >>> ex = numpy.einsum('ij,ji', kcross, dm1) >>> # Analytical gradients for coulomb matrix between two molecules >>> jcros1 = get_jk((mol1,mol1,mol,mol), dm, scripts='ijkl,lk->ij', intor='int2e_ip1_sph', comp=3) >>> # Analytical gradients for coulomb interaction between 1s density and the other molecule >>> jpart1 = get_jk((mol1,mol1,mol,mol), dm, scripts='ijkl,lk->ij', intor='int2e_ip1_sph', comp=3, ... shls_slice=(0,1,0,1,0,mol.nbas,0,mol.nbas)) ''' if isinstance(mols, (tuple, list)): assert(len(mols) == 4) assert(mols[0].cart == mols[1].cart == mols[2].cart == mols[3].cart) if shls_slice is None: shls_slice = numpy.array([(0, mol.nbas) for mol in mols]) else: shls_slice = numpy.asarray(shls_slice).reshape(4,2) # concatenate unique mols and build corresponding shls_slice mol_ids = [id(mol) for mol in mols] atm, bas, env = mols[0]._atm, mols[0]._bas, mols[0]._env bas_start = numpy.zeros(4, dtype=int) for m in range(1,4): first = mol_ids.index(mol_ids[m]) if first == m: # the unique mol bas_start[m] = bas.shape[0] atm, bas, env = gto.conc_env(atm, bas, env, mols[m]._atm, mols[m]._bas, mols[m]._env) else: bas_start[m] = bas_start[first] shls_slice[m] += bas_start[m] shls_slice = shls_slice.flatten() else: atm, bas, env = mols._atm, mols._bas, mols._env if shls_slice is None: shls_slice = (0, mols.nbas) * 4 if isinstance(scripts, str): scripts = [scripts] if isinstance(dms, numpy.ndarray) and dms.ndim == 2: dms = [dms] assert(len(scripts) == len(dms)) #format scripts descript = [] for script in scripts: dmsym, vsym = script.lower().split(',')[1].split('->') if hermi == 0: descript.append('->'.join((dmsym,'s1'+vsym))) else: descript.append('->'.join((dmsym,'s2'+vsym))) vs = _vhf.direct_bindm(intor, aosym, descript, dms, comp, atm, bas, env, shls_slice=shls_slice) if hermi != 0: for v in vs: if v.ndim == 3: for vi in v: pyscf.lib.hermi_triu(vi, hermi, inplace=True) else: pyscf.lib.hermi_triu(v, hermi, inplace=True) return vs
def _ft_aopair_kpts(cell, Gv, shls_slice=None, aosym='s1', invh=None, gxyz=None, gs=None, kpt=numpy.zeros(3), kptjs=numpy.zeros((2,3)), out=None): ''' FT transform AO pair \int i(r) j(r) exp(-ikr) dr^3 for all kpt = kptj - kpti. The return list holds the AO pair array corresponding to the kpoints given by kptjs ''' kpt = numpy.reshape(kpt, 3) kptjs = numpy.asarray(kptjs, order='C').reshape(-1,3) nGv = Gv.shape[0] Gv = Gv + kpt # kptis = kptjs - kpt if (gxyz is None or invh is None or gs is None or (abs(kpt).sum() > 1e-9)): GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_invh = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*gs) # Guess what type of eval_gz to use if isinstance(invh, numpy.ndarray) and invh.shape == (3,3): p_invh = invh.ctypes.data_as(ctypes.c_void_p) if abs(invh-numpy.diag(invh.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_uniform_orth' else: eval_gz = 'GTO_Gv_uniform_nonorth' else: invh = numpy.hstack(invh) p_invh = invh.ctypes.data_as(ctypes.c_void_p) eval_gz = 'GTO_Gv_nonuniform_orth' drv = libpbc.PBC_ft_latsum_kpts intor = getattr(libpbc, 'GTO_ft_ovlp_sph') eval_gz = getattr(libpbc, eval_gz) # make copy of atm,bas,env because they are modified in the lattice sum atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) ao_loc = cell.ao_loc_nr() nao = ao_loc[cell.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc[:-1], ao_loc+nao)), dtype=numpy.int32) if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas*2) else: shls_slice = (shls_slice[0], shls_slice[1], cell.nbas+shls_slice[2], cell.nbas+shls_slice[3]) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] shape = (nGv, ni, nj) fill = getattr(libpbc, 'PBC_ft_fill_'+aosym) if aosym == 's1hermi': # Symmetry for Gamma point assert(abs(kpt).sum() < 1e-9 and abs(kptjs).sum() < 1e-9) elif aosym == 's2': i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1*(i1+1)//2 - i0*(i0+1)//2 shape = (nGv, nij) if out is None: out = [numpy.zeros(shape, order='F', dtype=numpy.complex128) for k in range(len(kptjs))] else: out = [numpy.ndarray(shape, order='F', dtype=numpy.complex128, buffer=out[k]) for k in range(len(kptjs))] out_ptrs = (ctypes.c_void_p*len(out))( *[x.ctypes.data_as(ctypes.c_void_p) for x in out]) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coord = numpy.asarray(atm[cell.natm:,gto.PTR_COORD], dtype=numpy.int32, order='C') Ls = numpy.asarray(cell.get_lattice_Ls(cell.nimgs), order='C') exp_Lk = numpy.einsum('ik,jk->ij', Ls, kptjs) exp_Lk = numpy.exp(1j * numpy.asarray(exp_Lk, order='C')) drv(intor, eval_gz, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coord.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(xyz)), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), exp_Lk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(kptjs)), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), GvT.ctypes.data_as(ctypes.c_void_p), p_invh, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm*2), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas*2), env.ctypes.data_as(ctypes.c_void_p)) if aosym == 's1hermi': for mat in out: for i in range(1,ni): mat[:,:i,i] = mat[:,i,:i] return out
def __init__(self, mol, unrestricted=False): scf.hf.SCF.__init__(self, mol) if mol.elec.nhomo is not None: unrestricted = True self.unrestricted = unrestricted self.mf_elec = None # dm_elec will be the total density after SCF, but can be spin # densities during the SCF procedure self.dm_elec = None self.mf_nuc = [] self.dm_nuc = [] self._eri_ne = [] self._eri_nn = [] # The verbosity flag is passed now instead of when creating those mol # objects because users need time to change mol's verbose level after # the mol object is created. self.mol.elec.verbose = self.mol.verbose for i in range(mol.nuc_num): self.mol.nuc[i].verbose = self.mol.verbose # initialize sub mf objects for electrons and quantum nuclei # electronic part: if unrestricted: self.mf_elec = scf.UHF(mol.elec) else: self.mf_elec = scf.RHF(mol.elec) self.mf_elec.get_hcore = self.get_hcore_elec self.mf_elec.super_mf = self if mol.elec.nhomo is not None: self.mf_elec.get_occ = self.get_occ_elec(self.mf_elec) # nuclear part for i in range(mol.nuc_num): self.mf_nuc.append(scf.RHF(mol.nuc[i])) mf_nuc = self.mf_nuc[-1] mf_nuc.occ_state = 0 # for Delta-SCF mf_nuc.get_occ = self.get_occ_nuc(mf_nuc) mf_nuc.get_hcore = self.get_hcore_nuc mf_nuc.get_veff = self.get_veff_nuc_bare mf_nuc.energy_qmnuc = self.energy_qmnuc mf_nuc.super_mf = self self.dm_nuc.append(None) # build ne and nn ERIs if there is enough memory for i in range(mol.nuc_num): self._eri_ne.append(None) self._eri_nn.append([None] * mol.nuc_num) if mol.incore_anyway or self._is_mem_enough( mol.elec.nao_nr(), mol.nuc[i].nao_nr()): atm, bas, env = gto.conc_env(mol.nuc[i]._atm, mol.nuc[i]._bas, mol.nuc[i]._env, mol.elec._atm, mol.elec._bas, mol.elec._env) self._eri_ne[i] = \ gto.moleintor.getints('int2e_sph', atm, bas, env, shls_slice=(0, mol.nuc[i]._bas.shape[0], 0, mol.nuc[i]._bas.shape[0], mol.nuc[i]._bas.shape[0], mol.nuc[i]._bas.shape[0] + mol.elec._bas.shape[0], mol.nuc[i]._bas.shape[0], mol.nuc[i]._bas.shape[0] + mol.elec._bas.shape[0]), aosym='s4') for i in range(mol.nuc_num - 1): for j in range(i + 1, mol.nuc_num): if mol.incore_anyway or self._is_mem_enough( mol.nuc[i].nao_nr(), mol.nuc[j].nao_nr()): atm, bas, env = gto.conc_env( mol.nuc[i]._atm, mol.nuc[i]._bas, mol.nuc[i]._env, mol.nuc[j]._atm, mol.nuc[j]._bas, mol.nuc[j]._env) self._eri_nn[i][j] = \ gto.moleintor.getints('int2e_sph', atm, bas, env, shls_slice=(0, mol.nuc[i]._bas.shape[0], 0, mol.nuc[i]._bas.shape[0], mol.nuc[i]._bas.shape[0], mol.nuc[i]._bas.shape[0] + mol.nuc[j]._bas.shape[0], mol.nuc[i]._bas.shape[0], mol.nuc[i]._bas.shape[0] + mol.nuc[j]._bas.shape[0]), aosym='s4')
def wrap_int3c(cell, auxcell, intor='int3c2e', aosym='s1', comp=1, kptij_lst=numpy.zeros((1, 2, 3)), cintopt=None, pbcopt=None): intor = cell._add_suffix(intor) pcell = copy.copy(cell) pcell._atm, pcell._bas, pcell._env = \ atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) ao_loc = gto.moleintor.make_loc(bas, intor) aux_loc = auxcell.ao_loc_nr(auxcell.cart or 'ssc' in intor) ao_loc = numpy.asarray(numpy.hstack([ao_loc, ao_loc[-1] + aux_loc[1:]]), dtype=numpy.int32) atm, bas, env = gto.conc_env(atm, bas, env, auxcell._atm, auxcell._bas, auxcell._env) Ls = cell.get_lattice_Ls() nimgs = len(Ls) kpti = kptij_lst[:, 0] kptj = kptij_lst[:, 1] if gamma_point(kptij_lst): kk_type = 'g' dtype = numpy.double nkpts = nkptij = 1 kptij_idx = numpy.array([0], dtype=numpy.int32) expkL = numpy.ones(1) elif is_zero(kpti - kptj): # j_only kk_type = 'k' dtype = numpy.complex128 kpts = kptij_idx = numpy.asarray(kpti, order='C') expkL = numpy.exp(1j * numpy.dot(kpts, Ls.T)) nkpts = nkptij = len(kpts) else: kk_type = 'kk' dtype = numpy.complex128 kpts = unique(numpy.vstack([kpti, kptj]))[0] expkL = numpy.exp(1j * numpy.dot(kpts, Ls.T)) wherei = numpy.where( abs(kpti.reshape(-1, 1, 3) - kpts).sum(axis=2) < KPT_DIFF_TOL)[1] wherej = numpy.where( abs(kptj.reshape(-1, 1, 3) - kpts).sum(axis=2) < KPT_DIFF_TOL)[1] nkpts = len(kpts) kptij_idx = numpy.asarray(wherei * nkpts + wherej, dtype=numpy.int32) nkptij = len(kptij_lst) fill = 'PBCnr3c_fill_%s%s' % (kk_type, aosym[:2]) drv = libpbc.PBCnr3c_drv if cintopt is None: cintopt = _vhf.make_cintopt(atm, bas, env, intor) # Remove the precomputed pair data because the pair data corresponds to the # integral of cell #0 while the lattice sum moves shls to all repeated images. if intor[:3] != 'ECP': libpbc.CINTdel_pairdata_optimizer(cintopt) if pbcopt is None: pbcopt = _pbcintor.PBCOpt(pcell).init_rcut_cond(pcell) if isinstance(pbcopt, _pbcintor.PBCOpt): cpbcopt = pbcopt._this else: cpbcopt = lib.c_null_ptr() nbas = cell.nbas def int3c(shls_slice, out): shls_slice = (shls_slice[0], shls_slice[1], nbas + shls_slice[2], nbas + shls_slice[3], nbas * 2 + shls_slice[4], nbas * 2 + shls_slice[5]) drv( getattr(libpbc, intor), getattr(libpbc, fill), out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkptij), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(nimgs), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), kptij_idx.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 6)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, cpbcopt, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), # need to pass cell.nbas to libpbc.PBCnr3c_drv env.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(env.size)) return out return int3c
def _ft_aopair_kpts(cell, Gv, shls_slice=None, aosym='s1', b=None, gxyz=None, Gvbase=None, q=numpy.zeros(3), kptjs=numpy.zeros((1,3)), intor='GTO_ft_ovlp', comp=1, out=None): r''' FT transform AO pair \sum_T exp(-i k_j * T) \int exp(-i(G+q)r) i(r) j(r-T) dr^3 The return array holds the AO pair corresponding to the kpoints given by kptjs ''' intor = cell._add_suffix(intor) q = numpy.reshape(q, 3) kptjs = numpy.asarray(kptjs, order='C').reshape(-1,3) Gv = numpy.asarray(Gv, order='C').reshape(-1,3) nGv = Gv.shape[0] GvT = numpy.asarray(Gv.T, order='C') GvT += q.reshape(-1,1) if (gxyz is None or b is None or Gvbase is None or (abs(q).sum() > 1e-9) # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): p_gxyzT = lib.c_null_ptr() p_mesh = (ctypes.c_int*3)(0,0,0) p_b = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: if abs(b-numpy.diag(b.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_orth' else: eval_gz = 'GTO_Gv_nonorth' gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), q) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_mesh = (ctypes.c_int*3)(*[len(x) for x in Gvbase]) Ls = cell.get_lattice_Ls() expkL = numpy.exp(1j * numpy.dot(kptjs, Ls.T)) atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) ao_loc = gto.moleintor.make_loc(bas, intor) if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas*2) else: shls_slice = (shls_slice[0], shls_slice[1], cell.nbas+shls_slice[2], cell.nbas+shls_slice[3]) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] nkpts = len(kptjs) nimgs = len(Ls) shape = (nkpts, comp, ni, nj, nGv) # Theoretically, hermitian symmetry can be also found for kpti == kptj: # f_ji(G) = \int f_ji exp(-iGr) = \int f_ij^* exp(-iGr) = [f_ij(-G)]^* # hermi operation needs reordering the axis-0. It is inefficient. if aosym == 's1hermi': # Symmetry for Gamma point assert(is_zero(q) and is_zero(kptjs) and ni == nj) elif aosym == 's2': i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1*(i1+1)//2 - i0*(i0+1)//2 shape = (nkpts, comp, nij, nGv) drv = libpbc.PBC_ft_latsum_drv cintor = getattr(libpbc, intor) eval_gz = getattr(libpbc, eval_gz) if nkpts == 1: fill = getattr(libpbc, 'PBC_ft_fill_nk1'+aosym) else: fill = getattr(libpbc, 'PBC_ft_fill_k'+aosym) out = numpy.ndarray(shape, dtype=numpy.complex128, buffer=out) drv(cintor, eval_gz, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(nimgs), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_mesh, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas), env.ctypes.data_as(ctypes.c_void_p)) if aosym == 's1hermi': for i in range(1,ni): out[:,:,:i,i] = out[:,:,i,:i] out = numpy.rollaxis(out, -1, 2) if comp == 1: out = out[:,0] return out
def _ft_aopair_kpts(cell, Gv, shls_slice=None, aosym='s1', b=None, gxyz=None, Gvbase=None, kpt=numpy.zeros(3), kptjs=numpy.zeros((2,3)), out=None): ''' FT transform AO pair \int i(r) j(r) exp(-ikr) dr^3 for all kpt = kptj - kpti. The return list holds the AO pair array corresponding to the kpoints given by kptjs ''' kpt = numpy.reshape(kpt, 3) # kptis = kptjs - kpt kptjs = numpy.asarray(kptjs, order='C').reshape(-1,3) nGv = Gv.shape[0] GvT = numpy.asarray(Gv.T, order='C') GvT += kpt.reshape(-1,1) if (gxyz is None or b is None or Gvbase is None or (abs(kpt).sum() > 1e-9) # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_b = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), kpt) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*[len(x) for x in Gvbase]) eval_gz = 'GTO_Gv_cubic' drv = libpbc.PBC_ft_latsum_kpts intor = getattr(libpbc, 'GTO_ft_ovlp_sph') eval_gz = getattr(libpbc, eval_gz) # make copy of atm,bas,env because they are modified in the lattice sum atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) ao_loc = cell.ao_loc_nr() nao = ao_loc[cell.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc[:-1], ao_loc+nao)), dtype=numpy.int32) if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas*2) else: shls_slice = (shls_slice[0], shls_slice[1], cell.nbas+shls_slice[2], cell.nbas+shls_slice[3]) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] shape = (nGv, ni, nj) fill = getattr(libpbc, 'PBC_ft_fill_'+aosym) # Theoretically, hermitian symmetry can be also found for kpti == kptj: # f_ji(G) = \int f_ji exp(-iGr) = \int f_ij^* exp(-iGr) = [f_ij(-G)]^* # The hermi operation needs reordering the axis-0. It is inefficient. if aosym == 's1hermi': # Symmetry for Gamma point assert(abs(kpt).sum() < 1e-9 and abs(kptjs).sum() < 1e-9) elif aosym == 's2': i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1*(i1+1)//2 - i0*(i0+1)//2 shape = (nGv, nij) if out is None: out = [numpy.zeros(shape, order='F', dtype=numpy.complex128) for k in range(len(kptjs))] else: out = [numpy.ndarray(shape, order='F', dtype=numpy.complex128, buffer=out[k]) for k in range(len(kptjs))] out_ptrs = (ctypes.c_void_p*len(out))( *[x.ctypes.data_as(ctypes.c_void_p) for x in out]) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coord = numpy.asarray(atm[cell.natm:,gto.PTR_COORD], dtype=numpy.int32, order='C') Ls = cell.get_lattice_Ls() exp_Lk = numpy.einsum('ik,jk->ij', Ls, kptjs) exp_Lk = numpy.exp(1j * numpy.asarray(exp_Lk, order='C')) drv(intor, eval_gz, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coord.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(xyz)), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), exp_Lk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(kptjs)), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm*2), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas*2), env.ctypes.data_as(ctypes.c_void_p)) if aosym == 's1hermi': for mat in out: for i in range(1,ni): mat[:,:i,i] = mat[:,i,:i] return out
def conc_env(self): return gto.conc_env(self.mol._atm, self.mol._bas, self.mol._env, self.Vmol._atm, self.Vmol._bas, self.Vmol._env)
def _make_j3c(mydf, cell, auxcell, chgcell, kptij_lst): t1 = (time.clock(), time.time()) log = logger.Logger(mydf.stdout, mydf.verbose) max_memory = max(2000, mydf.max_memory-lib.current_memory()[0]) auxcell = copy.copy(auxcell) auxcell._atm, auxcell._bas, auxcell._env = \ gto.conc_env(auxcell._atm, auxcell._bas, auxcell._env, chgcell._atm, chgcell._bas, chgcell._env) outcore.aux_e2(cell, auxcell, mydf._cderi, 'cint3c2e_sph', kptij_lst=kptij_lst, dataname='j3c', max_memory=max_memory) t1 = log.timer_debug1('3c2e', *t1) nao = cell.nao_nr() naux = auxcell.nao_nr() gs = mydf.gs gxyz = lib.cartesian_prod((numpy.append(range(gs[0]+1), range(-gs[0],0)), numpy.append(range(gs[1]+1), range(-gs[1],0)), numpy.append(range(gs[2]+1), range(-gs[2],0)))) invh = numpy.linalg.inv(cell._h) Gv = 2*numpy.pi * numpy.dot(gxyz, invh) ngs = gxyz.shape[0] kptis = kptij_lst[:,0] kptjs = kptij_lst[:,1] kpt_ji = kptjs - kptis uniq_kpts, uniq_index, uniq_inverse = unique(kpt_ji) # j2c ~ (-kpt_ji | kpt_ji) j2c = auxcell.pbc_intor('cint2c2e_sph', hermi=1, kpts=uniq_kpts) kLRs = [] kLIs = [] for k, kpt in enumerate(uniq_kpts): aoaux = ft_ao.ft_ao(auxcell, Gv, None, invh, gxyz, gs, kpt) coulG = tools.get_coulG(cell, kpt, gs=gs) / cell.vol aoauxG = aoaux * coulG.reshape(-1,1) kLRs.append(numpy.asarray(aoauxG.real, order='C')) kLIs.append(numpy.asarray(aoauxG.imag, order='C')) if is_zero(kpt): # kpti == kptj j2c[k] -= lib.dot(kLRs[-1].T, numpy.asarray(aoaux.real,order='C')) j2c[k] -= lib.dot(kLIs[-1].T, numpy.asarray(aoaux.imag,order='C')) else: # aoaux ~ kpt_ij, aoaux.conj() ~ kpt_kl j2c[k] -= lib.dot(aoauxG.conj().T, aoaux) aoaux = coulG = None feri = h5py.File(mydf._cderi) # Expand approx Lpq for aosym='s1'. The approx Lpq are all in aosym='s2' mode if mydf.approx_sr_level > 0 and len(kptij_lst) > 1: Lpq_fake = _fake_Lpq_kpts(mydf, feri, naux, nao) def save(label, dat, col0, col1): feri[label][:,col0:col1] = dat def make_kpt(uniq_kptji_id): # kpt = kptj - kpti kpt = uniq_kpts[uniq_kptji_id] log.debug1('kpt = %s', kpt) adapted_ji_idx = numpy.where(uniq_inverse == uniq_kptji_id)[0] adapted_kptjs = kptjs[adapted_ji_idx] nkptj = len(adapted_kptjs) log.debug1('adapted_ji_idx = %s', adapted_ji_idx) kLR = kLRs[uniq_kptji_id] kLI = kLIs[uniq_kptji_id] if is_zero(kpt): # kpti == kptj aosym = 's2' nao_pair = nao*(nao+1)//2 vbar = mydf.auxbar(auxcell) ovlp = cell.pbc_intor('cint1e_ovlp_sph', hermi=1, kpts=adapted_kptjs) for k, ji in enumerate(adapted_ji_idx): ovlp[k] = lib.pack_tril(ovlp[k]) else: aosym = 's1' nao_pair = nao**2 max_memory = max(2000, mydf.max_memory-lib.current_memory()[0]) # nkptj for 3c-coulomb arrays plus 1 Lpq array buflen = min(max(int(max_memory*.6*1e6/16/naux/(nkptj+1)), 1), nao_pair) shranges = pyscf.df.outcore._guess_shell_ranges(cell, buflen, aosym) buflen = max([x[2] for x in shranges]) # +1 for a pqkbuf if aosym == 's2': Gblksize = max(16, int(max_memory*.2*1e6/16/buflen/(nkptj+1))) else: Gblksize = max(16, int(max_memory*.4*1e6/16/buflen/(nkptj+1))) Gblksize = min(Gblksize, ngs) pqkRbuf = numpy.empty(buflen*Gblksize) pqkIbuf = numpy.empty(buflen*Gblksize) # buf for ft_aopair buf = numpy.zeros((nkptj,buflen*Gblksize), dtype=numpy.complex128) col1 = 0 for istep, sh_range in enumerate(shranges): log.debug1('int3c2e [%d/%d], AO [%d:%d], ncol = %d', \ istep+1, len(shranges), *sh_range) bstart, bend, ncol = sh_range col0, col1 = col1, col1+ncol j3cR = [] j3cI = [] for k, idx in enumerate(adapted_ji_idx): v = numpy.asarray(feri['j3c/%d'%idx][:,col0:col1]) if mydf.approx_sr_level == 0: Lpq = numpy.asarray(feri['Lpq/%d'%idx][:,col0:col1]) elif aosym == 's2': Lpq = numpy.asarray(feri['Lpq/0'][:,col0:col1]) else: Lpq = numpy.asarray(Lpq_fake[:,col0:col1]) lib.dot(j2c[uniq_kptji_id], Lpq, -.5, v, 1) j3cR.append(numpy.asarray(v.real, order='C')) if is_zero(kpt) and gamma_point(adapted_kptjs[k]): j3cI.append(None) else: j3cI.append(numpy.asarray(v.imag, order='C')) v = Lpq = None if aosym == 's2': shls_slice = (bstart, bend, 0, bend) for p0, p1 in lib.prange(0, ngs, Gblksize): ft_ao._ft_aopair_kpts(cell, Gv[p0:p1], shls_slice, aosym, invh, gxyz[p0:p1], gs, kpt, adapted_kptjs, out=buf) nG = p1 - p0 for k, ji in enumerate(adapted_ji_idx): aoao = numpy.ndarray((nG,ncol), dtype=numpy.complex128, order='F', buffer=buf[k]) pqkR = numpy.ndarray((ncol,nG), buffer=pqkRbuf) pqkI = numpy.ndarray((ncol,nG), buffer=pqkIbuf) pqkR[:] = aoao.real.T pqkI[:] = aoao.imag.T aoao[:] = 0 lib.dot(kLR[p0:p1].T, pqkR.T, -1, j3cR[k], 1) lib.dot(kLI[p0:p1].T, pqkI.T, -1, j3cR[k], 1) if not (is_zero(kpt) and gamma_point(adapted_kptjs[k])): lib.dot(kLR[p0:p1].T, pqkI.T, -1, j3cI[k], 1) lib.dot(kLI[p0:p1].T, pqkR.T, 1, j3cI[k], 1) else: shls_slice = (bstart, bend, 0, cell.nbas) ni = ncol // nao for p0, p1 in lib.prange(0, ngs, Gblksize): ft_ao._ft_aopair_kpts(cell, Gv[p0:p1], shls_slice, aosym, invh, gxyz[p0:p1], gs, kpt, adapted_kptjs, out=buf) nG = p1 - p0 for k, ji in enumerate(adapted_ji_idx): aoao = numpy.ndarray((nG,ni,nao), dtype=numpy.complex128, order='F', buffer=buf[k]) pqkR = numpy.ndarray((ni,nao,nG), buffer=pqkRbuf) pqkI = numpy.ndarray((ni,nao,nG), buffer=pqkIbuf) pqkR[:] = aoao.real.transpose(1,2,0) pqkI[:] = aoao.imag.transpose(1,2,0) aoao[:] = 0 pqkR = pqkR.reshape(-1,nG) pqkI = pqkI.reshape(-1,nG) zdotCN(kLR[p0:p1].T, kLI[p0:p1].T, pqkR.T, pqkI.T, -1, j3cR[k], j3cI[k], 1) if is_zero(kpt): for k, ji in enumerate(adapted_ji_idx): if gamma_point(adapted_kptjs[k]): for i, c in enumerate(vbar): if c != 0: j3cR[k][i] -= c * ovlp[k][col0:col1].real else: for i, c in enumerate(vbar): if c != 0: j3cR[k][i] -= c * ovlp[k][col0:col1].real j3cI[k][i] -= c * ovlp[k][col0:col1].imag for k, ji in enumerate(adapted_ji_idx): if is_zero(kpt) and gamma_point(adapted_kptjs[k]): save('j3c/%d'%ji, j3cR[k], col0, col1) else: save('j3c/%d'%ji, j3cR[k]+j3cI[k]*1j, col0, col1) for k, kpt in enumerate(uniq_kpts): make_kpt(k) feri.close()
def _ft_aopair_kpts(cell, Gv, shls_slice=None, aosym='s1', b=None, gxyz=None, Gvbase=None, q=numpy.zeros(3), kptjs=numpy.zeros((1, 3)), out=None): ''' FT transform AO pair \int exp(-i(G+q)r) i(r) j(r) exp(-ikr) dr^3 The return list holds the AO pair array corresponding to the kpoints given by kptjs ''' q = numpy.reshape(q, 3) kptjs = numpy.asarray(kptjs, order='C').reshape(-1, 3) nGv = Gv.shape[0] GvT = numpy.asarray(Gv.T, order='C') GvT += q.reshape(-1, 1) if (gxyz is None or b is None or Gvbase is None or (abs(q).sum() > 1e-9) # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int * 3)(0, 0, 0) p_b = (ctypes.c_double * 1)(0) eval_gz = 'GTO_Gv_general' else: if abs(b - numpy.diag(b.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_orth' else: eval_gz = 'GTO_Gv_nonorth' gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) Gvx = lib.cartesian_prod(Gvbase) b = numpy.hstack((b.ravel(), q) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int * 3)(*[len(x) for x in Gvbase]) drv = libpbc.PBC_ft_latsum_kpts intor = getattr(libpbc, 'GTO_ft_ovlp_sph') eval_gz = getattr(libpbc, eval_gz) # make copy of atm,bas,env because they are modified in the lattice sum atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) ao_loc = cell.ao_loc_nr() nao = ao_loc[cell.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc[:-1], ao_loc + nao)), dtype=numpy.int32) if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas * 2) else: shls_slice = (shls_slice[0], shls_slice[1], cell.nbas + shls_slice[2], cell.nbas + shls_slice[3]) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] shape = (nGv, ni, nj) fill = getattr(libpbc, 'PBC_ft_fill_' + aosym) # Theoretically, hermitian symmetry can be also found for kpti == kptj: # f_ji(G) = \int f_ji exp(-iGr) = \int f_ij^* exp(-iGr) = [f_ij(-G)]^* # The hermi operation needs reordering the axis-0. It is inefficient. if aosym == 's1hermi': # Symmetry for Gamma point assert (abs(q).sum() < 1e-9 and abs(kptjs).sum() < 1e-9) elif aosym == 's2': i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1 * (i1 + 1) // 2 - i0 * (i0 + 1) // 2 shape = (nGv, nij) if out is None: out = [ numpy.zeros(shape, order='F', dtype=numpy.complex128) for k in range(len(kptjs)) ] else: out = [ numpy.ndarray(shape, order='F', dtype=numpy.complex128, buffer=out[k]) for k in range(len(kptjs)) ] out_ptrs = (ctypes.c_void_p * len(out))(*[x.ctypes.data_as(ctypes.c_void_p) for x in out]) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coord = numpy.asarray(atm[cell.natm:, gto.PTR_COORD], dtype=numpy.int32, order='C') Ls = cell.get_lattice_Ls() exp_Lk = numpy.einsum('ik,jk->ij', Ls, kptjs) exp_Lk = numpy.exp(1j * numpy.asarray(exp_Lk, order='C')) drv(intor, eval_gz, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coord.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(xyz)), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), exp_Lk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(kptjs)), (ctypes.c_int * 4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm * 2), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas * 2), env.ctypes.data_as(ctypes.c_void_p)) if aosym == 's1hermi': for mat in out: for i in range(1, ni): mat[:, :i, i] = mat[:, i, :i] return out
from pyscf import gto from pyscf import scf from pyscf import ao2mo from pyscf import df mol = gto.Mole() mol.build( verbose=0, atom='''O 0 0. 0. 1 0 -0.757 0.587 1 0 0.757 0.587''', basis='cc-pvdz', ) auxmol = df.addons.make_auxmol(mol, 'weigend') atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env) class KnowValues(unittest.TestCase): def test_aux_e2(self): nao = mol.nao_nr() naoaux = auxmol.nao_nr() eri0 = numpy.empty((nao, nao, naoaux)) pi = 0 for i in range(mol.nbas): pj = 0 for j in range(mol.nbas): pk = 0 for k in range(mol.nbas, mol.nbas + auxmol.nbas): shls = (i, j, k) buf = gto.moleintor.getints_by_shell(
from pyscf import ao2mo from pyscf import df mol = gto.Mole() mol.build( verbose = 0, atom = '''O 0 0. 0. 1 0 -0.757 0.587 1 0 0.757 0.587''', basis = 'cc-pvdz', ) libri = df.incore.libri auxmol = df.incore.format_aux_basis(mol) atm, bas, env = \ gto.conc_env(mol._atm, mol._bas, mol._env, auxmol._atm, auxmol._bas, auxmol._env) class KnowValues(unittest.TestCase): def test_aux_e2(self): j3c = df.incore.aux_e2(mol, auxmol, intor='cint3c2e_sph', aosym='s1') nao = mol.nao_nr() naoaux = auxmol.nao_nr() j3c = j3c.reshape(nao,nao,naoaux) eri0 = numpy.empty((nao,nao,naoaux)) pi = 0 for i in range(mol.nbas): pj = 0 for j in range(mol.nbas): pk = 0 for k in range(mol.nbas, mol.nbas+auxmol.nbas):
from pyscf import gto, scf ''' Concatenate two molecule enviroments We need the integrals from different bra and ket space, eg to prepare initial guess from different geometry or basis, or compute the transition properties between two states. To access These integrals, we need concatenate the enviroments of two Mole object. This method can be used to generate the 3-center integrals for RI integrals. ''' mol1 = gto.M(verbose=0, atom='C 0 0 0; O 0 0 1.5', basis='ccpvdz') mol2 = gto.M(verbose=0, atom='H 0 1 0; H 1 0 0', basis='ccpvdz') atm3, bas3, env3 = gto.conc_env(mol1._atm, mol1._bas, mol1._env, mol2._atm, mol2._bas, mol2._env) nao1 = mol1.nao_nr() nao2 = mol2.nao_nr() s12 = numpy.empty((nao1, nao2)) pi = 0 for i in range(mol1.nbas): pj = 0 for j in range(mol1.nbas, mol1.nbas + mol2.nbas): shls = (i, j) buf = gto.moleintor.getints_by_shell('cint1e_ovlp_sph', shls, atm3, bas3, env3) di, dj = buf.shape s12[pi:pi + di, pj:pj + dj] = buf pj += dj pi += di print('<mol1|mol2> overlap shape %s' % str(s12.shape))
def fuse_auxcell(mydf, auxcell): chgcell = make_modchg_basis(auxcell, mydf.eta) fused_cell = copy.copy(auxcell) fused_cell._atm, fused_cell._bas, fused_cell._env = \ gto.conc_env(auxcell._atm, auxcell._bas, auxcell._env, chgcell._atm, chgcell._bas, chgcell._env) fused_cell.rcut = max(auxcell.rcut, chgcell.rcut) aux_loc = auxcell.ao_loc_nr() naux = aux_loc[-1] modchg_offset = -numpy.ones((chgcell.natm,8), dtype=int) smooth_loc = chgcell.ao_loc_nr() for i in range(chgcell.nbas): ia = chgcell.bas_atom(i) l = chgcell.bas_angular(i) modchg_offset[ia,l] = smooth_loc[i] if auxcell.cart: # Normalization coefficients are different in the same shell for cartesian # basis. E.g. the d-type functions, the 5 d-type orbitals are normalized wrt # the integral \int r^2 * r^2 e^{-a r^2} dr. The s-type 3s orbital should be # normalized wrt the integral \int r^0 * r^2 e^{-a r^2} dr. The different # normalization was not built in the basis. There two ways to surmount this # problem. First is to transform the cartesian basis and scale the 3s (for # d functions), 4p (for f functions) ... then transform back. The second is to # remove the 3s, 4p functions. The function below is the second solution import ctypes c2s_fn = gto.moleintor.libcgto.CINTc2s_ket_sph aux_loc_sph = auxcell.ao_loc_nr(cart=False) naux_sph = aux_loc_sph[-1] def fuse(Lpq): Lpq, chgLpq = Lpq[:naux], Lpq[naux:] if Lpq.ndim == 1: npq = 1 Lpq_sph = numpy.empty(naux_sph, dtype=Lpq.dtype) else: npq = Lpq.shape[1] Lpq_sph = numpy.empty((naux_sph,npq), dtype=Lpq.dtype) if Lpq.dtype == numpy.complex: npq *= 2 # c2s_fn supports double only, *2 to handle complex for i in range(auxcell.nbas): l = auxcell.bas_angular(i) ia = auxcell.bas_atom(i) p0 = modchg_offset[ia,l] if p0 >= 0: nd = (l+1) * (l+2) // 2 c0, c1 = aux_loc[i], aux_loc[i+1] s0, s1 = aux_loc_sph[i], aux_loc_sph[i+1] for i0, i1 in lib.prange(c0, c1, nd): Lpq[i0:i1] -= chgLpq[p0:p0+nd] if l < 2: Lpq_sph[s0:s1] = Lpq[c0:c1] else: Lpq_cart = numpy.asarray(Lpq[c0:c1], order='C') c2s_fn(Lpq_sph[s0:s1].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(npq * auxcell.bas_nctr(i)), Lpq_cart.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(l)) return Lpq_sph else: def fuse(Lpq): Lpq, chgLpq = Lpq[:naux], Lpq[naux:] for i in range(auxcell.nbas): l = auxcell.bas_angular(i) ia = auxcell.bas_atom(i) p0 = modchg_offset[ia,l] if p0 >= 0: nd = l * 2 + 1 for i0, i1 in lib.prange(aux_loc[i], aux_loc[i+1], nd): Lpq[i0:i1] -= chgLpq[p0:p0+nd] return Lpq return fused_cell, fuse
def fuse_auxcell(mydf, auxcell): chgcell = make_modchg_basis(auxcell, mydf.eta) fused_cell = copy.copy(auxcell) fused_cell._atm, fused_cell._bas, fused_cell._env = \ gto.conc_env(auxcell._atm, auxcell._bas, auxcell._env, chgcell._atm, chgcell._bas, chgcell._env) fused_cell.rcut = max(auxcell.rcut, chgcell.rcut) aux_loc = auxcell.ao_loc_nr() naux = aux_loc[-1] modchg_offset = -numpy.ones((chgcell.natm, 8), dtype=int) smooth_loc = chgcell.ao_loc_nr() for i in range(chgcell.nbas): ia = chgcell.bas_atom(i) l = chgcell.bas_angular(i) modchg_offset[ia, l] = smooth_loc[i] if auxcell.cart: # Normalization coefficients are different in the same shell for cartesian # basis. E.g. the d-type functions, the 5 d-type orbitals are normalized wrt # the integral \int r^2 * r^2 e^{-a r^2} dr. The s-type 3s orbital should be # normalized wrt the integral \int r^0 * r^2 e^{-a r^2} dr. The different # normalization was not built in the basis. There two ways to surmount this # problem. First is to transform the cartesian basis and scale the 3s (for # d functions), 4p (for f functions) ... then transform back. The second is to # remove the 3s, 4p functions. The function below is the second solution c2s_fn = gto.moleintor.libcgto.CINTc2s_ket_sph aux_loc_sph = auxcell.ao_loc_nr(cart=False) naux_sph = aux_loc_sph[-1] def fuse(Lpq): Lpq, chgLpq = Lpq[:naux], Lpq[naux:] if Lpq.ndim == 1: npq = 1 Lpq_sph = numpy.empty(naux_sph, dtype=Lpq.dtype) else: npq = Lpq.shape[1] Lpq_sph = numpy.empty((naux_sph, npq), dtype=Lpq.dtype) if Lpq.dtype == numpy.complex: npq *= 2 # c2s_fn supports double only, *2 to handle complex for i in range(auxcell.nbas): l = auxcell.bas_angular(i) ia = auxcell.bas_atom(i) p0 = modchg_offset[ia, l] if p0 >= 0: nd = (l + 1) * (l + 2) // 2 c0, c1 = aux_loc[i], aux_loc[i + 1] s0, s1 = aux_loc_sph[i], aux_loc_sph[i + 1] for i0, i1 in lib.prange(c0, c1, nd): Lpq[i0:i1] -= chgLpq[p0:p0 + nd] if l < 2: Lpq_sph[s0:s1] = Lpq[c0:c1] else: Lpq_cart = numpy.asarray(Lpq[c0:c1], order='C') c2s_fn(Lpq_sph[s0:s1].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(npq * auxcell.bas_nctr(i)), Lpq_cart.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(l)) return Lpq_sph else: def fuse(Lpq): Lpq, chgLpq = Lpq[:naux], Lpq[naux:] for i in range(auxcell.nbas): l = auxcell.bas_angular(i) ia = auxcell.bas_atom(i) p0 = modchg_offset[ia, l] if p0 >= 0: nd = l * 2 + 1 for i0, i1 in lib.prange(aux_loc[i], aux_loc[i + 1], nd): Lpq[i0:i1] -= chgLpq[p0:p0 + nd] return Lpq return fused_cell, fuse
def get_nuc(mydf, kpts=None): cell = mydf.cell if kpts is None: kpts_lst = numpy.zeros((1,3)) else: kpts_lst = numpy.reshape(kpts, (-1,3)) if mydf._cderi is None: mydf.build() log = logger.Logger(mydf.stdout, mydf.verbose) t1 = t0 = (time.clock(), time.time()) auxcell = mydf.auxcell nuccell = make_modchg_basis(cell, mydf.eta, 0) nuccell._bas = numpy.asarray(nuccell._bas[nuccell._bas[:,gto.ANG_OF]==0], dtype=numpy.int32, order='C') charge = -cell.atom_charges() nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charge)]) nucbar *= numpy.pi/cell.vol vj = [v.ravel() for v in _int_nuc_vloc(cell, nuccell, kpts_lst)] t1 = log.timer_debug1('vnuc pass1: analytic int', *t1) j2c = pgto.intor_cross('cint2c2e_sph', auxcell, nuccell) jaux = j2c.dot(charge) kpt_allow = numpy.zeros(3) coulG = tools.get_coulG(cell, kpt_allow, gs=mydf.gs) / cell.vol Gv = cell.get_Gv(mydf.gs) aoaux = ft_ao.ft_ao(nuccell, Gv) vGR = numpy.einsum('i,xi->x', charge, aoaux.real) * coulG vGI = numpy.einsum('i,xi->x', charge, aoaux.imag) * coulG max_memory = mydf.max_memory - lib.current_memory()[0] for k, pqkR, pqkI, p0, p1 \ in mydf.ft_loop(cell, mydf.gs, kpt_allow, kpts_lst, max_memory=max_memory): # rho_ij(G) nuc(-G) / G^2 # = [Re(rho_ij(G)) + Im(rho_ij(G))*1j] [Re(nuc(G)) - Im(nuc(G))*1j] / G^2 if not gamma_point(kpts_lst[k]): vj[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkI) * 1j vj[k] += numpy.einsum('k,xk->x', vGI[p0:p1], pqkR) *-1j vj[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkR) vj[k] += numpy.einsum('k,xk->x', vGI[p0:p1], pqkI) t1 = log.timer_debug1('contracting Vnuc', *t1) # Append nuccell to auxcell, so that they can be FT together in pw_loop # the first [:naux] of ft_ao are aux fitting functions. nuccell._atm, nuccell._bas, nuccell._env = \ gto.conc_env(auxcell._atm, auxcell._bas, auxcell._env, nuccell._atm, nuccell._bas, nuccell._env) naux = auxcell.nao_nr() aoaux = ft_ao.ft_ao(nuccell, Gv) vG = numpy.einsum('i,xi,x->x', charge, aoaux[:,naux:], coulG) jaux -= numpy.einsum('x,xj->j', vG.real, aoaux[:,:naux].real) jaux -= numpy.einsum('x,xj->j', vG.imag, aoaux[:,:naux].imag) jaux -= charge.sum() * mydf.auxbar(auxcell) ovlp = cell.pbc_intor('cint1e_ovlp_sph', 1, lib.HERMITIAN, kpts_lst) nao = cell.nao_nr() nao_pair = nao * (nao+1) // 2 max_memory = max(2000, mydf.max_memory-lib.current_memory()[0]) blksize = max(16, min(int(max_memory*1e6/16/nao_pair), mydf.blockdim)) for k, kpt in enumerate(kpts_lst): with mydf.load_Lpq((kpt,kpt)) as Lpq: v = 0 for p0, p1 in lib.prange(0, jaux.size, blksize): v += numpy.dot(jaux[p0:p1], numpy.asarray(Lpq[p0:p1])) vj[k] = vj[k].reshape(nao,nao) - nucbar * ovlp[k] if gamma_point(kpt): vj[k] += lib.unpack_tril(numpy.asarray(v.real,order='C')) else: vj[k] += lib.unpack_tril(v) if kpts is None or numpy.shape(kpts) == (3,): vj = vj[0] return vj