def density(mol, outfile, dm, nx=80, ny=80, nz=80): coord = [mol.atom_coord(ia) for ia in range(mol.natm)] box = numpy.max(coord,axis=0) - numpy.min(coord,axis=0) + 4 boxorig = numpy.min(coord,axis=0) - 2 xs = numpy.arange(nx) * (box[0]/nx) ys = numpy.arange(ny) * (box[1]/ny) zs = numpy.arange(nz) * (box[2]/nz) coords = numpy.vstack(numpy.meshgrid(xs,ys,zs)).reshape(3,-1).T coords = numpy.asarray(coords, order='C') - (-boxorig) nao = mol.nao_nr() ngrids = nx * ny * nz blksize = min(200, ngrids) rho = numpy.empty(ngrids) for ip0, ip1 in numint.prange(0, ngrids, blksize): ao = numint.eval_ao(mol, coords[ip0:ip1]) rho[ip0:ip1] = numint.eval_rho(mol, ao, dm) rho = rho.reshape(nx,ny,nz) with open(outfile, 'w') as f: f.write('Density in real space\n') f.write('Comment line\n') f.write('%5d' % mol.natm) f.write(' %14.8f %14.8f %14.8f\n' % tuple(boxorig.tolist())) f.write('%5d %14.8f %14.8f %14.8f\n' % (nx, xs[1], 0, 0)) f.write('%5d %14.8f %14.8f %14.8f\n' % (ny, 0, ys[1], 0)) f.write('%5d %14.8f %14.8f %14.8f\n' % (nz, 0, 0, zs[1])) for ia in range(mol.natm): chg = mol.atom_charge(ia) f.write('%5d %f' % (chg, chg)) f.write(' %14.8f %14.8f %14.8f\n' % tuple(mol.atom_coord(ia).tolist())) fmt = ' %14.8f' * nz + '\n' for ix in range(nx): for iy in range(ny): f.write(fmt % tuple(rho[ix,iy].tolist()))
def _get_vxc(ni, mol, grids, x_id, c_id, dms, relativity=0, hermi=1, max_memory=2000, verbose=None): natocc = [] natorb = [] if isinstance(dms, numpy.ndarray) and dms.ndim == 2: e, c = scipy.linalg.eigh(dms) natocc.append(e) natorb.append(c) nao = dms.shape[0] else: for dm in dms: e, c = scipy.linalg.eigh(dm) natocc.append(e) natorb.append(c) nao = dms[0].shape[0] xctype = numint._xc_type(x_id, c_id) ngrids = len(grids.weights) BLKSIZE = numint.BLKSIZE blksize = min(int(max_memory/6*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids) nset = len(natocc) nelec = numpy.zeros(nset) excsum = numpy.zeros(nset) vmat = numpy.zeros((nset,3,nao,nao)) if xctype == 'LDA': buf = numpy.empty((4,blksize,nao)) for ip0, ip1 in numint.prange(0, ngrids, blksize): coords = grids.coords[ip0:ip1] weight = grids.weights[ip0:ip1] non0tab = ni.non0tab[ip0//BLKSIZE:] ao = ni.eval_ao(mol, coords, deriv=1, non0tab=non0tab, out=buf) for idm in range(nset): rho = ni.eval_rho2(mol, ao[0], natorb[idm], natocc[idm], non0tab, xctype) exc, vxc = ni.eval_xc(x_id, c_id, rho, 0, relativity, 1, verbose)[:2] vrho = vxc[0] den = rho * weight nelec[idm] += den.sum() excsum[idm] += (den * exc).sum() aow = numpy.einsum('pi,p->pi', ao[0], weight*vrho) vmat[idm,0] += numint._dot_ao_ao(mol, ao[1], aow, nao, ip1-ip0, non0tab) vmat[idm,1] += numint._dot_ao_ao(mol, ao[2], aow, nao, ip1-ip0, non0tab) vmat[idm,2] += numint._dot_ao_ao(mol, ao[3], aow, nao, ip1-ip0, non0tab) rho = exc = vxc = vrho = aow = None elif xctype == 'GGA': buf = numpy.empty((10,blksize,nao)) XX, XY, XZ = 4, 5, 6 YX, YY, YZ = 5, 7, 8 ZX, ZY, ZZ = 6, 8, 9 for ip0, ip1 in numint.prange(0, ngrids, blksize): coords = grids.coords[ip0:ip1] weight = grids.weights[ip0:ip1] non0tab = ni.non0tab[ip0//BLKSIZE:] ao = ni.eval_ao(mol, coords, deriv=2, non0tab=non0tab, out=buf) for idm in range(nset): rho = ni.eval_rho2(mol, ao, natorb[idm], natocc[idm], non0tab, xctype) exc, vxc = ni.eval_xc(x_id, c_id, rho, 0, relativity, 1, verbose)[:2] vrho, vsigma = vxc[:2] den = rho[0] * weight nelec[idm] += den.sum() excsum[idm] += (den * exc).sum() wv = numpy.empty_like(rho) # *.5 because vmat + vmat.T implicitly wv[0] = weight * vrho * .5 wv[1:] = rho[1:] * (weight * vsigma * 2) aow = numpy.einsum('npi,np->pi', ao[:4], wv) vmat[idm,0] += numint._dot_ao_ao(mol, ao[1], aow, nao, ip1-ip0, non0tab) vmat[idm,1] += numint._dot_ao_ao(mol, ao[2], aow, nao, ip1-ip0, non0tab) vmat[idm,2] += numint._dot_ao_ao(mol, ao[3], aow, nao, ip1-ip0, non0tab) aow = numpy.einsum('pi,p->pi', ao[1] , wv[0]) aow+= numpy.einsum('pi,p->pi', ao[XX], wv[1]) aow+= numpy.einsum('pi,p->pi', ao[XY], wv[2]) aow+= numpy.einsum('pi,p->pi', ao[XZ], wv[3]) vmat[idm,0] += numint._dot_ao_ao(mol, aow, ao[0], nao, ip1-ip0, non0tab) aow = numpy.einsum('pi,p->pi', ao[2] , wv[0]) aow+= numpy.einsum('pi,p->pi', ao[YX], wv[1]) aow+= numpy.einsum('pi,p->pi', ao[YY], wv[2]) aow+= numpy.einsum('pi,p->pi', ao[YZ], wv[3]) vmat[idm,1] += numint._dot_ao_ao(mol, aow, ao[0], nao, ip1-ip0, non0tab) aow = numpy.einsum('pi,p->pi', ao[3] , wv[0]) aow+= numpy.einsum('pi,p->pi', ao[ZX], wv[1]) aow+= numpy.einsum('pi,p->pi', ao[ZY], wv[2]) aow+= numpy.einsum('pi,p->pi', ao[ZZ], wv[3]) vmat[idm,2] += numint._dot_ao_ao(mol, aow, ao[0], nao, ip1-ip0, non0tab) rho = exc = vxc = vrho = vsigma = wv = aow = None else: raise NotImplementedError('meta-GGA') if nset == 1: vmat = vmat.reshape(3,nao,nao) return vmat
def _contract_xc_kernel(td, x_id, c_id, dmvo, singlet=True, max_memory=2000): mf = td._scf mol = td.mol ni = mf._numint grids = mf.grids mo_coeff = mf.mo_coeff mo_occ = mf.mo_occ nao, nmo = mo_coeff.shape ndm = len(dmvo) dmvo = numpy.asarray(dmvo) dmvo = (dmvo + dmvo.transpose(0,2,1)) * .5 xctype = numint._xc_type(x_id, c_id) ngrids = len(grids.weights) BLKSIZE = numint.BLKSIZE blksize = min(int(max_memory*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids) v1ao = numpy.zeros((ndm,nao,nao)) if xctype == 'LDA': buf = numpy.empty((blksize,nao)) if singlet: for ip0, ip1 in numint.prange(0, ngrids, blksize): coords = grids.coords[ip0:ip1] weight = grids.weights[ip0:ip1] non0tab = ni.non0tab[ip0//BLKSIZE:] ao = ni.eval_ao(mol, coords, deriv=0, non0tab=non0tab, out=buf) rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, non0tab, 'LDA') rho *= .5 # alpha density fxc = ni.eval_xc(x_id, c_id, (rho,rho), 1, deriv=2)[2] u_u, u_d, d_d = v2rho2 = fxc[0].T frho = u_u + u_d for i, dm in enumerate(dmvo): rho1 = ni.eval_rho(mol, ao, dm, non0tab, xctype) aow = numpy.einsum('pi,p->pi', ao, weight*frho*rho1) v1ao[i] += numint._dot_ao_ao(mol, aow, ao, nao, ip1-ip0, non0tab) rho1 = aow = None for i in range(ndm): v1ao[i] = (v1ao[i] + v1ao[i].T) * .5 else: # because frho = u_u - u_d = 0 pass elif xctype == 'GGA': buf = numpy.empty((4,blksize,nao)) for ip0, ip1 in numint.prange(0, ngrids, blksize): coords = grids.coords[ip0:ip1] weight = grids.weights[ip0:ip1] non0tab = ni.non0tab[ip0//BLKSIZE:] ao = ni.eval_ao(mol, coords, deriv=1, non0tab=non0tab, out=buf) rho = ni.eval_rho2(mol, ao, mo_coeff, mo_occ, non0tab, 'GGA') rho *= .5 # alpha density vxc, fxc = ni.eval_xc(x_id, c_id, (rho,rho), 1, deriv=2)[1:3] vsigma = vxc[1].T u_u, u_d, d_d = fxc[0].T # v2rho2 u_uu, u_ud, u_dd, d_uu, d_ud, d_dd = fxc[1].T # v2rhosigma uu_uu, uu_ud, uu_dd, ud_ud, ud_dd, dd_dd = fxc[2].T # v2sigma2 if singlet: fgamma = 2*vsigma[0] + vsigma[1] frho = u_u + u_d fgg = uu_uu + .5*ud_ud + 2*uu_ud + uu_dd frhogamma = u_uu + u_dd + u_ud else: fgamma = 2*vsigma[0] - vsigma[1] frho = u_u - u_d fgg = uu_uu - uu_dd frhogamma = u_uu - u_dd for i, dm in enumerate(dmvo): # rho1[0 ] = |b><j| z_{bj} # rho1[1:] = \nabla(|b><j|) z_{bj} rho1 = ni.eval_rho(mol, ao, dm, non0tab, 'GGA') # sigma1 = \nabla(\rho_\alpha+\rho_\beta) dot \nabla(|b><j|) z_{bj} # *2 for alpha + beta sigma1 = numpy.einsum('xi,xi->i', rho[1:], rho1[1:]) * 2 wv = frho * rho1[0] wv += frhogamma * sigma1 wv *= weight if c_id == 131 or x_id in (402, 404, 411, 416, 419): # second derivative of LYP functional in libxc library diverge wv[rho[0] < 4.57e-11] = 0 aow = numpy.einsum('pi,p->pi', ao[0], wv) v1ao[i] += numint._dot_ao_ao(mol, aow, ao[0], nao, ip1-ip0, non0tab) for k in range(3): wv = fgg * sigma1 * rho[1+k] wv += frhogamma * rho1[0] * rho[1+k] wv *= 2 # *2 because \nabla\rho = \nabla(\rho_\alpha+\rho_\beta) wv += fgamma * rho1[1+k] wv *= weight if c_id == 131 or x_id in (402, 404, 411, 416, 419): # second derivative of LYP functional in libxc library diverge wv[rho[0] < 4.57e-11] = 0 aow = numpy.einsum('ip,i->ip', ao[0], wv) #v1ao += numint._dot_ao_ao(mol, aow, ao[1+k], nao, ip1-ip0, non0tab) #v1ao += numint._dot_ao_ao(mol, ao[1+k], aow, nao, ip1-ip0, non0tab) # v1ao+v1ao.T at the end v1ao[i] += 2*numint._dot_ao_ao(mol, aow, ao[1+k], nao, ip1-ip0, non0tab) aow = None for i in range(ndm): v1ao[i] = (v1ao[i] + v1ao[i].T) * .5 else: raise NotImplementedError('meta-GGA') return v1ao
def _contract_xc_kernel(td_grad, x_id, c_id, xai, oovv=None, with_vxc=True, with_kxc=True, singlet=True, max_memory=4000): mol = td_grad.mol mf = td_grad._scf ni = mf._numint grids = mf.grids mo_coeff = mf.mo_coeff mo_energy = mf.mo_energy mo_occ = mf.mo_occ nao, nmo = mo_coeff.shape nocc = (mo_occ>0).sum() orbv = mo_coeff[:,nocc:] orbo = mo_coeff[:,:nocc] # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T)) dmvo = (xai + xai.T) * .5 # because K_{ai,bj} == K_{ai,bj} f1vo = numpy.zeros((4,nao,nao)) deriv = 2 if oovv is not None: f1oo = numpy.zeros((4,nao,nao)) else: f1oo = None if with_vxc: v1ao = numpy.zeros((4,nao,nao)) else: v1ao = None if with_kxc: k1ao = numpy.zeros((4,nao,nao)) deriv = 3 else: k1ao = None xctype = numint._xc_type(x_id, c_id) ngrids = len(grids.weights) BLKSIZE = numint.BLKSIZE max_memory = max_memory - 4*nao**2*8/1e6 blksize = min(int(max_memory/6*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids) if xctype == 'LDA': buf = numpy.empty((4,blksize,nao)) for ip0, ip1 in numint.prange(0, ngrids, blksize): coords = grids.coords[ip0:ip1] weight = grids.weights[ip0:ip1] non0tab = ni.non0tab[ip0//BLKSIZE:] ao = ni.eval_ao(mol, coords, deriv=1, non0tab=non0tab, out=buf) rho = ni.eval_rho2(mol, ao[0], mo_coeff, mo_occ, non0tab, 'LDA') vxc, fxc, kxc = ni.eval_xc(x_id, c_id, rho, 0, deriv=deriv)[1:] wfxc = fxc[0] * weight * 2 # *2 for alpha+beta if singlet: rho1 = ni.eval_rho(mol, ao[0], dmvo, non0tab, 'LDA') aow = numpy.einsum('pi,p->pi', ao[0], wfxc*rho1) for k in range(4): f1vo[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, ip1-ip0, non0tab) if oovv is not None: rho2 = ni.eval_rho(mol, ao[0], oovv, non0tab, 'LDA') aow = numpy.einsum('pi,p->pi', ao[0], wfxc*rho2) for k in range(4): f1oo[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, ip1-ip0, non0tab) if with_vxc: aow = numpy.einsum('pi,p->pi', ao[0], vxc[0]*weight) for k in range(4): v1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, ip1-ip0, non0tab) if singlet and with_kxc: aow = numpy.einsum('pi,p->pi', ao[0], kxc[0]*weight*rho1**2) for k in range(4): k1ao[k] += numint._dot_ao_ao(mol, ao[k], aow, nao, ip1-ip0, non0tab) vxc = fxc = kxc = aow = rho = rho1 = rho2 = None if singlet and with_kxc: k1ao *= 4 elif xctype == 'GGA': raise NotImplementedError('GGA') else: raise NotImplementedError('meta-GGA') f1vo[1:] *= -1 if f1oo is not None: f1oo[1:] *= -1 if v1ao is not None: v1ao[1:] *= -1 if k1ao is not None: k1ao[1:] *= -1 return f1vo, f1oo, v1ao, k1ao
def _get_vxc_giao(ni, mol, grids, x_id, c_id, dm, max_memory=2000, verbose=None): natocc, natorb = scipy.linalg.eigh(dm) nao = dm.shape[0] xctype = numint._xc_type(x_id, c_id) ngrids = len(grids.weights) BLKSIZE = numint.BLKSIZE blksize = min(int(max_memory/6*1e6/12/nao/BLKSIZE)*BLKSIZE, ngrids) vmat = numpy.zeros((3,nao,nao)) if xctype == 'LDA': buf = numpy.empty((4,blksize,nao)) for ip0, ip1 in numint.prange(0, ngrids, blksize): coords = grids.coords[ip0:ip1] weight = grids.weights[ip0:ip1] non0tab = ni.non0tab[ip0//BLKSIZE:] ao = ni.eval_ao(mol, coords, deriv=0, non0tab=non0tab, out=buf) rho = ni.eval_rho2(mol, ao, natorb, natocc, non0tab, xctype) vxc = ni.eval_xc(x_id, c_id, rho, 0, deriv=1)[1] vrho = vxc[0] aow = numpy.einsum('pi,p->pi', ao, weight*vrho) giao = mol.eval_gto('GTOval_ig_sph', coords, comp=3, non0tab=non0tab, out=buf[1:]) vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], nao, ip1-ip0, non0tab) vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], nao, ip1-ip0, non0tab) vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], nao, ip1-ip0, non0tab) rho = vxc = vrho = aow = giao = None elif xctype == 'GGA': buf = numpy.empty((10,blksize,nao)) XX, XY, XZ = 0, 1, 2 YX, YY, YZ = 3, 4, 5 ZX, ZY, ZZ = 6, 7, 8 for ip0, ip1 in numint.prange(0, ngrids, blksize): coords = grids.coords[ip0:ip1] weight = grids.weights[ip0:ip1] non0tab = ni.non0tab[ip0//BLKSIZE:] ao = ni.eval_ao(mol, coords, deriv=1, non0tab=non0tab, out=buf) rho = ni.eval_rho2(mol, ao, natorb, natocc, non0tab, xctype) vxc = ni.eval_xc(x_id, c_id, rho, 0, deriv=1)[1] vrho, vsigma = vxc[:2] wv = numpy.empty_like(rho) wv[0] = weight * vrho wv[1:] = rho[1:] * (weight * vsigma * 2) aow = numpy.einsum('npi,np->pi', ao[:4], wv) giao = mol.eval_gto('GTOval_ig_sph', coords, 3, non0tab=non0tab, out=buf[4:]) vmat[0] += numint._dot_ao_ao(mol, aow, giao[0], nao, ip1-ip0, non0tab) vmat[1] += numint._dot_ao_ao(mol, aow, giao[1], nao, ip1-ip0, non0tab) vmat[2] += numint._dot_ao_ao(mol, aow, giao[2], nao, ip1-ip0, non0tab) giao = mol.eval_gto('GTOval_ipig_sph', coords, 9, non0tab=non0tab, out=buf[1:]) aow = numpy.einsum('pi,p->pi', giao[XX], wv[1]) aow+= numpy.einsum('pi,p->pi', giao[YX], wv[2]) aow+= numpy.einsum('pi,p->pi', giao[ZX], wv[3]) vmat[0] += numint._dot_ao_ao(mol, ao[0], aow, nao, ip1-ip0, non0tab) aow = numpy.einsum('pi,p->pi', giao[XY], wv[1]) aow+= numpy.einsum('pi,p->pi', giao[YY], wv[2]) aow+= numpy.einsum('pi,p->pi', giao[ZY], wv[3]) vmat[1] += numint._dot_ao_ao(mol, ao[0], aow, nao, ip1-ip0, non0tab) aow = numpy.einsum('pi,p->pi', giao[XZ], wv[1]) aow+= numpy.einsum('pi,p->pi', giao[YZ], wv[2]) aow+= numpy.einsum('pi,p->pi', giao[ZZ], wv[3]) vmat[2] += numint._dot_ao_ao(mol, ao[0], aow, nao, ip1-ip0, non0tab) rho = vxc = vrho = vsigma = wv = aow = giao = None else: raise NotImplementedError('meta-GGA') return vmat - vmat.transpose(0,2,1)