def derK(D, d2Ints_dXa, d2Ints_dYa, d2Ints_dZa): #modified from Ints.py -> getK "Form the exchange operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D, (nbf * nbf, )) #1D version of Dens dKx = zeros((nbf, nbf), 'd') dKy = zeros((nbf, nbf), 'd') dKz = zeros((nbf, nbf), 'd') for i in xrange(nbf): for j in xrange(i + 1): xtemp = zeros(nbf * nbf, 'd') ytemp = zeros(nbf * nbf, 'd') ztemp = zeros(nbf * nbf, 'd') kl = 0 for k in xrange(nbf): for l in xrange(nbf): index_k1 = ijkl2intindex(i, k, j, l) index_k2 = ijkl2intindex(i, l, k, j) xtemp[kl] = 0.5 * (d2Ints_dXa[index_k1] + d2Ints_dXa[index_k2]) ytemp[kl] = 0.5 * (d2Ints_dYa[index_k1] + d2Ints_dYa[index_k2]) ztemp[kl] = 0.5 * (d2Ints_dZa[index_k1] + d2Ints_dZa[index_k2]) kl += 1 dKx[i, j] = dot(xtemp, D1d) dKx[j, i] = dKx[i, j] dKy[i, j] = dot(ytemp, D1d) dKy[j, i] = dKy[i, j] dKz[i, j] = dot(ztemp, D1d) dKz[j, i] = dKz[i, j] return dKx, dKy, dKz
def derJ(D,d2Ints_dXa,d2Ints_dYa,d2Ints_dZa): #modified from Ints.py -> getJ "Form the Coulomb operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D,(nbf*nbf,)) #1D version of Dens dJx = zeros((nbf,nbf),'d') dJy = zeros((nbf,nbf),'d') dJz = zeros((nbf,nbf),'d') for i in xrange(nbf): for j in xrange(i+1): xtemp = zeros(nbf*nbf,'d') ytemp = zeros(nbf*nbf,'d') ztemp = zeros(nbf*nbf,'d') kl = 0 for k in xrange(nbf): for l in xrange(nbf): index = ijkl2intindex(i,j,k,l) xtemp[kl] = d2Ints_dXa[index] ytemp[kl] = d2Ints_dYa[index] ztemp[kl] = d2Ints_dZa[index] kl += 1 dJx[i,j] = dot(xtemp,D1d) dJx[j,i] = dJx[i,j] dJy[i,j] = dot(ytemp,D1d) dJy[j,i] = dJy[i,j] dJz[i,j] = dot(ztemp,D1d) dJz[j,i] = dJz[i,j] return dJx,dJy,dJz
def derJ(D, d2Ints_dXa, d2Ints_dYa, d2Ints_dZa): #modified from Ints.py -> getJ "Form the Coulomb operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D, (nbf * nbf, )) #1D version of Dens dJx = zeros((nbf, nbf), 'd') dJy = zeros((nbf, nbf), 'd') dJz = zeros((nbf, nbf), 'd') for i in xrange(nbf): for j in xrange(i + 1): xtemp = zeros(nbf * nbf, 'd') ytemp = zeros(nbf * nbf, 'd') ztemp = zeros(nbf * nbf, 'd') kl = 0 for k in xrange(nbf): for l in xrange(nbf): index = ijkl2intindex(i, j, k, l) xtemp[kl] = d2Ints_dXa[index] ytemp[kl] = d2Ints_dYa[index] ztemp[kl] = d2Ints_dZa[index] kl += 1 dJx[i, j] = dot(xtemp, D1d) dJx[j, i] = dJx[i, j] dJy[i, j] = dot(ytemp, D1d) dJy[j, i] = dJy[i, j] dJz[i, j] = dot(ztemp, D1d) dJz[j, i] = dJz[i, j] return dJx, dJy, dJz
def derK(D,d2Ints_dXa,d2Ints_dYa,d2Ints_dZa): #modified from Ints.py -> getK "Form the exchange operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D,(nbf*nbf,)) #1D version of Dens dKx = zeros((nbf,nbf),'d') dKy = zeros((nbf,nbf),'d') dKz = zeros((nbf,nbf),'d') for i in xrange(nbf): for j in xrange(i+1): xtemp = zeros(nbf*nbf,'d') ytemp = zeros(nbf*nbf,'d') ztemp = zeros(nbf*nbf,'d') kl = 0 for k in xrange(nbf): for l in xrange(nbf): index_k1 = ijkl2intindex(i,k,j,l) index_k2 = ijkl2intindex(i,l,k,j) xtemp[kl] = 0.5*(d2Ints_dXa[index_k1]+d2Ints_dXa[index_k2]) ytemp[kl] = 0.5*(d2Ints_dYa[index_k1]+d2Ints_dYa[index_k2]) ztemp[kl] = 0.5*(d2Ints_dZa[index_k1]+d2Ints_dZa[index_k2]) kl += 1 dKx[i,j] = dot(xtemp,D1d) dKx[j,i] = dKx[i,j] dKy[i,j] = dot(ytemp,D1d) dKy[j,i] = dKy[i,j] dKz[i,j] = dot(ztemp,D1d) dKz[j,i] = dKz[i,j] return dKx,dKy,dKz
def TransformInts(Ints,orbs): """O(N^5) 4-index transformation of the two-electron integrals. Not as efficient as it could be, since it inflates to the full rectangular matrices rather than keeping them compressed. But at least it gets the correct result.""" from time import time t0 = time() nbf,nmo = orbs.shape totlen = nmo*(nmo+1)*(nmo*nmo+nmo+2)/8 temp = zeros((nbf,nbf,nbf,nmo),'d') tempvec = zeros(nbf,'d') temp2 = zeros((nbf,nbf,nmo,nmo),'d') mos = range(nmo) # preform so we don't form inside loops bfs = range(nbf) # Start with (mu,nu|sigma,eta) # Unpack aoints and transform eta -> l for mu in bfs: for nu in bfs: for sigma in bfs: for l in mos: for eta in bfs: tempvec[eta] = Ints[ijkl2intindex(mu,nu,sigma,eta)] temp[mu,nu,sigma,l] = dot(orbs[:,l],tempvec) # Transform sigma -> k for mu in bfs: for nu in bfs: for l in mos: for k in mos: temp2[mu,nu,k,l] = dot(orbs[:,k],temp[mu,nu,:,l]) # Transform nu -> j for mu in bfs: for k in mos: for l in mos: for j in mos: temp[mu,j,k,l] = dot(orbs[:,j],temp2[mu,:,k,l]) # Transform mu -> i and repack integrals: MOInts = zeros(totlen,'d') for i in mos: for j in xrange(i+1): ij = i*(i+1)/2+j for k in mos: for l in xrange(k+1): kl = k*(k+1)/2+l if ij >= kl: ijkl = ijkl2intindex(i,j,k,l) MOInts[ijkl] = dot(orbs[:,i],temp[:,j,k,l]) del temp,temp2,tempvec #force garbage collection now return MOInts
def TransformInts(Ints, orbs): """O(N^5) 4-index transformation of the two-electron integrals. Not as efficient as it could be, since it inflates to the full rectangular matrices rather than keeping them compressed. But at least it gets the correct result.""" from time import time t0 = time() nbf, nmo = orbs.shape totlen = nmo * (nmo + 1) * (nmo * nmo + nmo + 2) / 8 temp = zeros((nbf, nbf, nbf, nmo), 'd') tempvec = zeros(nbf, 'd') temp2 = zeros((nbf, nbf, nmo, nmo), 'd') mos = range(nmo) # preform so we don't form inside loops bfs = range(nbf) # Start with (mu,nu|sigma,eta) # Unpack aoints and transform eta -> l for mu in bfs: for nu in bfs: for sigma in bfs: for l in mos: for eta in bfs: tempvec[eta] = Ints[ijkl2intindex(mu, nu, sigma, eta)] temp[mu, nu, sigma, l] = dot(orbs[:, l], tempvec) # Transform sigma -> k for mu in bfs: for nu in bfs: for l in mos: for k in mos: temp2[mu, nu, k, l] = dot(orbs[:, k], temp[mu, nu, :, l]) # Transform nu -> j for mu in bfs: for k in mos: for l in mos: for j in mos: temp[mu, j, k, l] = dot(orbs[:, j], temp2[mu, :, k, l]) # Transform mu -> i and repack integrals: MOInts = zeros(totlen, 'd') for i in mos: for j in xrange(i + 1): ij = i * (i + 1) / 2 + j for k in mos: for l in xrange(k + 1): kl = k * (k + 1) / 2 + l if ij >= kl: ijkl = ijkl2intindex(i, j, k, l) MOInts[ijkl] = dot(orbs[:, i], temp[:, j, k, l]) del temp, temp2, tempvec #force garbage collection now return MOInts
def TransformIntsMP2(Ints, orbs, nclosed): """\ O(N^5) 4-index transformation of the two-electron integrals. Only transform the ones needed for MP2, which reduces the scaling to O(nN^4), where n are the occs (<<N). """ from time import time t0 = time() nbf, nmo = orbs.shape totlen = nmo * (nmo + 1) * (nmo * nmo + nmo + 2) / 8 occs = range(nclosed) mos = range(nmo) bfs = range(nbf) # Start with (mu,nu|sigma,eta) # Unpack aoints and transform sigma -> b temp = zeros((nbf, nbf, nclosed, nbf), 'd') tempvec = zeros(nbf, 'd') for mu in bfs: for nu in bfs: for eta in bfs: for b in occs: for sigma in bfs: tempvec[sigma] = Ints[ijkl2intindex( mu, nu, sigma, eta)] temp[mu, nu, b, eta] = dot(orbs[:, b], tempvec) temp2 = zeros((nclosed, nbf, nclosed, nbf), 'd') for nu in bfs: for eta in bfs: for b in occs: for a in occs: temp2[a, nu, b, eta] = dot(orbs[:, a], temp[:, nu, b, eta]) temp = zeros((nclosed, nbf, nclosed, nmo), 'd') for a in occs: for nu in bfs: for b in occs: for j in mos: temp[a, nu, b, j] = dot(orbs[:, j], temp2[a, nu, b, :]) # Transform mu -> i and repack integrals: MOInts = zeros(totlen, 'd') for a in occs: for j in mos: for b in occs: for i in mos: aibj = ijkl2intindex(a, i, b, j) MOInts[aibj] = dot(orbs[:, i], temp[a, :, b, j]) #print "Integral transform time = ",time()-t0 del temp, temp2, tempvec #force garbage collection now return MOInts
def TransformIntsMP2(Ints,orbs,nclosed): """\ O(N^5) 4-index transformation of the two-electron integrals. Only transform the ones needed for MP2, which reduces the scaling to O(nN^4), where n are the occs (<<N). """ from time import time t0 = time() nbf,nmo = orbs.shape totlen = nmo*(nmo+1)*(nmo*nmo+nmo+2)/8 occs = range(nclosed) mos = range(nmo) bfs = range(nbf) # Start with (mu,nu|sigma,eta) # Unpack aoints and transform sigma -> b temp = zeros((nbf,nbf,nclosed,nbf),'d') tempvec = zeros(nbf,'d') for mu in bfs: for nu in bfs: for eta in bfs: for b in occs: for sigma in bfs: tempvec[sigma] = Ints[ijkl2intindex(mu,nu,sigma,eta)] temp[mu,nu,b,eta] = dot(orbs[:,b],tempvec) temp2 = zeros((nclosed,nbf,nclosed,nbf),'d') for nu in bfs: for eta in bfs: for b in occs: for a in occs: temp2[a,nu,b,eta] = dot(orbs[:,a],temp[:,nu,b,eta]) temp = zeros((nclosed,nbf,nclosed,nmo),'d') for a in occs: for nu in bfs: for b in occs: for j in mos: temp[a,nu,b,j] = dot(orbs[:,j],temp2[a,nu,b,:]) # Transform mu -> i and repack integrals: MOInts = zeros(totlen,'d') for a in occs: for j in mos: for b in occs: for i in mos: aibj = ijkl2intindex(a,i,b,j) MOInts[aibj] = dot(orbs[:,i],temp[a,:,b,j]) #print "Integral transform time = ",time()-t0 del temp,temp2,tempvec #force garbage collection now return MOInts
def setdens(self, D): self._dens = 2 * dot(self.bfs, matrixmultiply(D, self.bfs)) # This *if* statement is potentially slow. If it becomes # a factor, pull it up to AtomicGrids and have two # explicit cases here. if self.do_grad_dens: self._grad = 2*dot(self.bfs.T,matrixmultiply(D,self.bfgrads)) +\ 2*dot(self.bfgrads.T,matrixmultiply(D,self.bfs)) self._gamma = dot(self._grad, self._grad) return
def setdens(self,D): self._dens = 2*dot(self.bfs,matrixmultiply(D,self.bfs)) # This *if* statement is potentially slow. If it becomes # a factor, pull it up to AtomicGrids and have two # explicit cases here. if self.do_grad_dens: self._grad = 2*dot(self.bfs.T,matrixmultiply(D,self.bfgrads)) +\ 2*dot(self.bfgrads.T,matrixmultiply(D,self.bfs)) self._gamma = dot(self._grad,self._grad) return
def TransformInts(Ints, orbs1, orbs2, nocc): nbf, nmo = orbs1.shape totlen = nmo * nmo * nmo * nmo occs = range(nocc) mos = range(nmo) bfs = range(nbf) # Start with (mu,nu|sigma,eta) # Unpack aoints and transform sigma -> b # Here sigma, b, nu, j are of first same spin group, # others of second same spin group temp = zeros((nbf, nbf, nbf, nbf), 'd') tempvec = zeros(nbf, 'd') for mu in bfs: for nu in bfs: for eta in bfs: for b in bfs: for sigma in bfs: tempvec[sigma] = Ints[ijkl2intindex( mu, nu, sigma, eta)] temp[mu, nu, b, eta] = dot(orbs1[b, :], tempvec) temp2 = zeros((nbf, nbf, nbf, nbf), 'd') for nu in bfs: for eta in bfs: for b in bfs: for a in bfs: temp2[a, nu, b, eta] = dot(orbs2[a, :], temp[:, nu, b, eta]) temp = zeros((nbf, nbf, nbf, nbf), 'd') for a in bfs: for nu in bfs: for b in bfs: for j in bfs: temp[a, nu, b, j] = dot(orbs1[j, :], temp2[a, nu, b, :]) # Transform mu -> i and repack integrals: MOInts = zeros(totlen, 'd') for a in bfs: for j in bfs: for b in bfs: for i in bfs: aibj = ijkl2intindex(a, i, b, j) MOInts[aibj] = dot(orbs2[i, :], temp[a, :, b, j]) del temp, temp2, tempvec #force garbage collection now return MOInts, nbf
def TransformInts(Ints,orbs1,orbs2, nocc): nbf,nmo = orbs1.shape totlen = nmo*nmo*nmo*nmo occs = range(nocc) mos = range(nmo) bfs = range(nbf) # Start with (mu,nu|sigma,eta) # Unpack aoints and transform sigma -> b # Here sigma, b, nu, j are of first same spin group, # others of second same spin group temp = zeros((nbf,nbf,nbf,nbf),'d') tempvec = zeros(nbf,'d') for mu in bfs: for nu in bfs: for eta in bfs: for b in bfs: for sigma in bfs: tempvec[sigma] = Ints[ijkl2intindex(mu,nu,sigma,eta)] temp[mu,nu,b,eta] = dot(orbs1[b,:],tempvec) temp2 = zeros((nbf,nbf,nbf,nbf),'d') for nu in bfs: for eta in bfs: for b in bfs: for a in bfs: temp2[a,nu,b,eta] = dot(orbs2[a,:],temp[:,nu,b,eta]) temp = zeros((nbf,nbf,nbf,nbf),'d') for a in bfs: for nu in bfs: for b in bfs: for j in bfs: temp[a,nu,b,j] = dot(orbs1[j,:],temp2[a,nu,b,:]) # Transform mu -> i and repack integrals: MOInts = zeros(totlen,'d') for a in bfs: for j in bfs: for b in bfs: for i in bfs: aibj = ijkl2intindex(a,i,b,j) MOInts[aibj] = dot(orbs2[i,:],temp[a,:,b,j]) del temp,temp2,tempvec #force garbage collection now return MOInts, nbf
def setdens(self,D): self._dens = 2*dot(self.bfs,matrixmultiply(D,self.bfs)) # This *if* statement is potentially slow. If it becomes # a factor, pull it up to AtomicGrids and have two # explicit cases here. if self.do_grad_dens: #gx = 2*dot(self.bfs,matrixmultiply(D,self.bfgrads[:,0])) + \ # 2*dot(self.bfgrads[:,0],matrixmultiply(D,self.bfs)) #gy = 2*dot(self.bfs,matrixmultiply(D,self.bfgrads[:,1])) + \ # 2*dot(self.bfgrads[:,1],matrixmultiply(D,self.bfs)) #gz = 2*dot(self.bfs,matrixmultiply(D,self.bfgrads[:,2])) + \ # 2*dot(self.bfgrads[:,2],matrixmultiply(D,self.bfs)) #self._grad = array((gx,gy,gz)) self._grad = 2*dot(self.bfs.T,matrixmultiply(D,self.bfgrads)) +\ 2*dot(self.bfgrads.T,matrixmultiply(D,self.bfs)) self._gamma = dot(self._grad,self._grad) return
def bdg(b,d,g): """Basis x Density x Gradient matrix multiply.""" n,m = b.shape _bdg = zeros((n,3),'d') db = dot(b,d) for j in xrange(3): _bdg[:,j] = abdot(db,g[:,:,j]) return _bdg
def mk_auger_dens(c, occ): "Forms a density matrix from a coef matrix c and occupations in occ" #count how many states we were given nstates = occ.shape[0] D = 0.0 for i in xrange(nstates): D += occ[i] * dot(c[:, i:i + 1], transpose(c[:, i:i + 1])) #pad_out(D) return D
def mk_auger_dens(c, occ): "Forms a density matrix from a coef matrix c and occupations in occ" #count how many states we were given nstates = occ.shape[0] D = 0.0 for i in xrange(nstates): D += occ[i]*dot( c[:,i:i+1], transpose(c[:,i:i+1])) #pad_out(D) return D
def mk_auger_dens(self): "Forms a density matrix from a coef matrix c and occupations in occ" if self.restricted: nstates = self.occs.shape[0] D = 0.0 for i in xrange(nstates): D += self.occs[i]*dot( self.orbs[:,i:i+1], transpose(self.orbs[:,i:i+1])) #pad_out(D) return D if self.fixedocc: nastates = self.occs_a.shape[0] nbstates = self.occs_b.shape[0] Da,Db = 0.0,0.0 for i in xrange(nastates): Da += self.occs_a[i]*dot( self.orbs_a[:,i:i+1], transpose(self.orbs_a[:,i:i+1])) for i in xrange(nbstates): Db += self.occs_b[i]*dot( self.orbs_b[:,i:i+1], transpose(self.orbs_b[:,i:i+1])) return Da,Db
def mk_auger_Qmatrix(self): #computes Q matrix using occ arrays, which is basically density matrix weighted by the orbital eigenvalues if self.restricted: nstates = self.occs.shape[0] Qmat = 0.0 for i in xrange(nstates): Qmat += self.orbe[i]*self.occs[i]*dot( self.orbs[:,i:i+1], transpose(self.orbs[:,i:i+1])) return Qmat if self.fixedocc: nastates = self.occs_a.shape[0] nbstates = self.occs_b.shape[0] Qa,Qb = 0.0,0.0 for i in xrange(nastates): Qa += self.orbe_a[i]*self.occs_a[i]*dot( self.orbs_a[:,i:i+1], transpose(self.orbs_a[:,i:i+1])) for i in xrange(nbstates): Qb += self.orbe_a[i]*self.occs_b[i]*dot( self.orbs_b[:,i:i+1], transpose(self.orbs_b[:,i:i+1])) return Qa,Qb
def renormalize(self,nel): factor = nel/dot(self.xyzw[:,3],self.density.sum(1)) if abs(factor-1) > 1e-2: print "Warning: large renormalization factor found in grid renormalization" print factor # Don't know whether it makes more sense to rescale the weights or the dens. # The density seems to make more sense, I guess #self.scale_weights(factor) self.scale_density(factor) return
def mk_auger_Qmatrix(self): #computes Q matrix using occ arrays, which is basically density matrix weighted by the orbital eigenvalues if self.restricted: nstates = self.occs.shape[0] Qmat = 0.0 for i in range(nstates): Qmat += self.orbe[i]*self.occs[i]*dot( self.orbs[:,i:i+1], transpose(self.orbs[:,i:i+1])) return Qmat if self.fixedocc: nastates = self.occs_a.shape[0] nbstates = self.occs_b.shape[0] Qa,Qb = 0.0,0.0 for i in range(nastates): Qa += self.orbe_a[i]*self.occs_a[i]*dot( self.orbs_a[:,i:i+1], transpose(self.orbs_a[:,i:i+1])) for i in range(nbstates): Qb += self.orbe_a[i]*self.occs_b[i]*dot( self.orbs_b[:,i:i+1], transpose(self.orbs_b[:,i:i+1])) return Qa,Qb
def mk_auger_dens(self): "Forms a density matrix from a coef matrix c and occupations in occ" if self.restricted: nstates = self.occs.shape[0] D = 0.0 for i in range(nstates): D += self.occs[i]*dot( self.orbs[:,i:i+1], transpose(self.orbs[:,i:i+1])) #pad_out(D) return D if self.fixedocc: nastates = self.occs_a.shape[0] nbstates = self.occs_b.shape[0] Da,Db = 0.0,0.0 for i in range(nastates): Da += self.occs_a[i]*dot( self.orbs_a[:,i:i+1], transpose(self.orbs_a[:,i:i+1])) for i in range(nbstates): Db += self.occs_b[i]*dot( self.orbs_b[:,i:i+1], transpose(self.orbs_b[:,i:i+1])) return Da,Db
def renormalize(self,nel): "Renormalize the density to sum to the proper number of electrons" factor = nel/dot(self.weights(),self.dens()) if abs(factor-1) > 1e-2: print "Warning: large renormalization factor found in grid renormalization" print factor # Don't know whether it makes more sense to rescale the weights or the dens. # The density seems to make more sense, I guess #self.scale_weights(factor) self.scale_density(factor) return
def renormalize(self, nel): "Renormalize the density to sum to the proper number of electrons" factor = nel / dot(self.weights(), self.dens()) if abs(factor - 1) > 1e-2: print "Warning: large renormalization factor found in grid renormalization" print factor # Don't know whether it makes more sense to rescale the weights or the dens. # The density seems to make more sense, I guess #self.scale_weights(factor) self.scale_density(factor) return
def der2JmK(D,d2Ints_dXa,d2Ints_dYa,d2Ints_dZa): #modified from Ints.py -> get2Jmk "Form the 2J-K integrals corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D,(nbf*nbf,)) #1D version of Dens Gx = zeros((nbf,nbf),'d') Gy = zeros((nbf,nbf),'d') Gz = zeros((nbf,nbf),'d') for i in xrange(nbf): for j in xrange(i+1): xtemp = zeros(nbf*nbf,'d') ytemp = zeros(nbf*nbf,'d') ztemp = zeros(nbf*nbf,'d') kl = 0 for k in xrange(nbf): for l in xrange(nbf): index_j = ijkl2intindex(i,j,k,l) index_k1 = ijkl2intindex(i,k,j,l) index_k2 = ijkl2intindex(i,l,k,j) xtemp[kl] = 2.*d2Ints_dXa[index_j]-0.5*d2Ints_dXa[index_k1]\ -0.5*d2Ints_dXa[index_k2] ytemp[kl] = 2.*d2Ints_dYa[index_j]-0.5*d2Ints_dYa[index_k1]\ -0.5*d2Ints_dYa[index_k2] ztemp[kl] = 2.*d2Ints_dZa[index_j]-0.5*d2Ints_dZa[index_k1]\ -0.5*d2Ints_dZa[index_k2] kl += 1 Gx[i,j] = dot(xtemp,D1d) Gx[j,i] = Gx[i,j] Gy[i,j] = dot(ytemp,D1d) Gy[j,i] = Gy[i,j] Gz[i,j] = dot(ztemp,D1d) Gz[j,i] = Gz[i,j] return Gx,Gy,Gz
def der2JmK(D, d2Ints_dXa, d2Ints_dYa, d2Ints_dZa): #modified from Ints.py -> get2Jmk "Form the 2J-K integrals corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D, (nbf * nbf, )) #1D version of Dens Gx = zeros((nbf, nbf), 'd') Gy = zeros((nbf, nbf), 'd') Gz = zeros((nbf, nbf), 'd') for i in xrange(nbf): for j in xrange(i + 1): xtemp = zeros(nbf * nbf, 'd') ytemp = zeros(nbf * nbf, 'd') ztemp = zeros(nbf * nbf, 'd') kl = 0 for k in xrange(nbf): for l in xrange(nbf): index_j = ijkl2intindex(i, j, k, l) index_k1 = ijkl2intindex(i, k, j, l) index_k2 = ijkl2intindex(i, l, k, j) xtemp[kl] = 2.*d2Ints_dXa[index_j]-0.5*d2Ints_dXa[index_k1]\ -0.5*d2Ints_dXa[index_k2] ytemp[kl] = 2.*d2Ints_dYa[index_j]-0.5*d2Ints_dYa[index_k1]\ -0.5*d2Ints_dYa[index_k2] ztemp[kl] = 2.*d2Ints_dZa[index_j]-0.5*d2Ints_dZa[index_k1]\ -0.5*d2Ints_dZa[index_k2] kl += 1 Gx[i, j] = dot(xtemp, D1d) Gx[j, i] = Gx[i, j] Gy[i, j] = dot(ytemp, D1d) Gy[j, i] = Gy[i, j] Gz[i, j] = dot(ztemp, D1d) Gz[j, i] = Gz[i, j] return Gx, Gy, Gz
def getJ(Ints, D): "Form the Coulomb operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D, (nbf * nbf, )) #1D version of Dens J = zeros((nbf, nbf), 'd') for i in xrange(nbf): for j in xrange(i + 1): if sorted: temp = jints[i, j] else: temp = fetch_jints(Ints, i, j, nbf) J[i, j] = dot(temp, D1d) J[j, i] = J[i, j] return J
def getK(Ints,D): "Form the exchange operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D,(nbf*nbf,)) #1D version of Dens K = zeros((nbf,nbf),'d') for i in xrange(nbf): for j in xrange(i+1): if sorted: temp = kints[i,j] else: temp = fetch_kints(Ints,i,j,nbf) K[i,j] = dot(temp,D1d) K[j,i] = K[i,j] return K
def get2JmK(Ints,D): "Form the 2J-K integrals corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D,(nbf*nbf,)) #1D version of Dens G = zeros((nbf,nbf),'d') for i in xrange(nbf): for j in xrange(i+1): if sorted: temp = 2*jints[i,j]-kints[i,j] else: temp = 2*fetch_jints(Ints,i,j,nbf)-fetch_kints(Ints,i,j,nbf) G[i,j] = dot(temp,D1d) G[j,i] = G[i,j] return G
def getK(Ints, D): "Form the exchange operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D, (nbf * nbf, )) #1D version of Dens K = zeros((nbf, nbf), 'd') for i in xrange(nbf): for j in xrange(i + 1): if sorted: temp = kints[i, j] else: temp = fetch_kints(Ints, i, j, nbf) K[i, j] = dot(temp, D1d) K[j, i] = K[i, j] return K
def getJ(Ints,D): "Form the Coulomb operator corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D,(nbf*nbf,)) #1D version of Dens J = zeros((nbf,nbf),'d') for i in xrange(nbf): for j in xrange(i+1): if sorted: temp = jints[i,j] else: temp = fetch_jints(Ints,i,j,nbf) J[i,j] = dot(temp,D1d) J[j,i] = J[i,j] return J
def getK_BTF(Ints, D, nbf1, nbf2, frag_number): if frag_number == 1: D1d = reshape(D, (nbf2 * nbf2, )) #1D version of Dens K = zeros((nbf1, nbf1), 'd') for i in xrange(nbf1): for j in xrange(i + 1): if sorted: temp = kintsBTF_12[i, j] else: temp = fetch_kintsBTF_12(Ints, i, j, nbf1, nbf2) K[i, j] = dot(temp, D1d) K[j, i] = K[i, j] elif frag_number == 2: D1d = reshape(D, (nbf1 * nbf1, )) #1D version of Dens K = zeros((nbf2, nbf2), 'd') for i in xrange(nbf2): for j in xrange(i + 1): if sorted: temp = kintsBTF_21[i, j] else: temp = fetch_kintsBTF_21(Ints, i, j, nbf1, nbf2) K[i, j] = dot(temp, D1d) K[j, i] = K[i, j] return K
def get2JmK(Ints, D): "Form the 2J-K integrals corresponding to a density matrix D" nbf = D.shape[0] D1d = reshape(D, (nbf * nbf, )) #1D version of Dens G = zeros((nbf, nbf), 'd') for i in xrange(nbf): for j in xrange(i + 1): if sorted: temp = 2 * jints[i, j] - kints[i, j] else: temp = 2 * fetch_jints(Ints, i, j, nbf) - fetch_kints( Ints, i, j, nbf) G[i, j] = dot(temp, D1d) G[j, i] = G[i, j] return G
def getK_BTF(Ints,D,nbf1,nbf2,frag_number): if frag_number == 1: D1d = reshape(D,(nbf2*nbf2,)) #1D version of Dens K = zeros((nbf1,nbf1),'d') for i in xrange(nbf1): for j in xrange(i+1): if sorted: temp = kintsBTF_12[i,j] else: temp = fetch_kintsBTF_12(Ints,i,j,nbf1,nbf2) K[i,j] = dot(temp,D1d) K[j,i] = K[i,j] elif frag_number == 2: D1d = reshape(D,(nbf1*nbf1,)) #1D version of Dens K = zeros((nbf2,nbf2),'d') for i in xrange(nbf2): for j in xrange(i+1): if sorted: temp = kintsBTF_21[i,j] else: temp = fetch_kintsBTF_21(Ints,i,j,nbf1,nbf2) K[i,j] = dot(temp,D1d) K[j,i] = K[i,j] return K
def norm(vec): "val = norm(vec) : Return the 2-norm of a vector" return sqrt(dot(vec, vec))
def distance(self, other): from NumWrap import dot from math import sqrt d = self.xyz - other.xyz return sqrt(dot(d, d))
def getXC(gr,nel,**kwargs): "Form the exchange-correlation matrix" functional = kwargs.get('functional','SVWN') do_grad_dens = need_gradients[functional] do_spin_polarized = kwargs.get('do_spin_polarized') gr.floor_density() # Insure that the values of the density don't underflow gr.renormalize(nel) # Renormalize to the proper # electrons dens = gr.dens() weight = gr.weights() gamma = gr.get_gamma() npts = len(dens) if gr.version == 1: amdens = zeros((2,npts),'d') amgamma = zeros((3,npts),'d') amdens[0,:] = amdens[1,:] = 0.5*dens if gamma is not None: amgamma[0,:] = amgamma[1,:] = amgamma[2,:] = 0.25*gamma elif gr.version == 2: amdens = gr.density.T amgamma = gr.gamma.T fxc,dfxcdna,dfxcdnb,dfxcdgaa,dfxcdgab,dfxcdgbb = XC(amdens,amgamma,**kwargs) Exc = dot(weight,fxc) wva = weight*dfxcdna # Combine w*v in a vector for multiplication by bfs # First do the part that doesn't depend upon gamma nbf = gr.get_nbf() Fxca = zeros((nbf,nbf),'d') for i in xrange(nbf): wva_i = wva*gr.bfgrid[:,i] for j in xrange(nbf): Fxca[i,j] = dot(wva_i,gr.bfgrid[:,j]) # Now do the gamma-dependent part. # Fxc_a += dot(2 dfxcdgaa*graddensa + dfxcdgab*graddensb,grad(chia*chib)) # We can do the dot product as # sum_grid sum_xyz A[grid,xyz]*B[grid,xyz] # or a 2d trace product # Here A contains the dfxcdgaa stuff # B contains the grad(chia*chib) # Possible errors: gr.grad() here should be the grad of the b part? if do_grad_dens: # A,B are dimensioned (npts,3) A = transpose(0.5*transpose(gr.grad())*(weight*(2*dfxcdgaa+dfxcdgab))) for a in xrange(nbf): for b in xrange(a+1): B = gr.grad_bf_prod(a,b) Fxca[a,b] += sum(ravel(A*B)) Fxca[b,a] = Fxca[a,b] if not do_spin_polarized: return Exc,Fxca wvb = weight*dfxcdnb # Combine w*v in a vector for multiplication by bfs # First do the part that doesn't depend upon gamma Fxcb = zeros((nbf,nbf),'d') for i in xrange(nbf): wvb_i = wvb*gr.bfgrid[:,i] for j in xrange(nbf): Fxcb[i,j] = dot(wvb_i,gr.bfgrid[:,j]) # Now do the gamma-dependent part. # Fxc_b += dot(2 dfxcdgbb*graddensb + dfxcdgab*graddensa,grad(chia*chib)) # We can do the dot product as # sum_grid sum_xyz A[grid,xyz]*B[grid,xyz] # or a 2d trace product # Here A contains the dfxcdgaa stuff # B contains the grad(chia*chib) # Possible errors: gr.grad() here should be the grad of the b part? if do_grad_dens: # A,B are dimensioned (npts,3) A = transpose(0.5*transpose(gr.grad())*(weight*(2*dfxcdgbb+dfxcdgab))) for a in xrange(nbf): for b in xrange(a+1): B = gr.grad_bf_prod(a,b) Fxcb[a,b] += sum(ravel(A*B)) Fxcb[b,a] = Fxcb[a,b] return Exc,Fxca,Fxcb
def bdb(b,d): """Basis x Density x Basis matrix multiply.""" db = dot(b,d) return abdot(db,b)
def getXC(gr, nel, **kwargs): "Form the exchange-correlation matrix" functional = kwargs.get('functional', 'SVWN') do_grad_dens = need_gradients[functional] do_spin_polarized = kwargs.get('do_spin_polarized') gr.floor_density() # Insure that the values of the density don't underflow gr.renormalize(nel) # Renormalize to the proper # electrons dens = gr.dens() weight = gr.weights() gamma = gr.get_gamma() npts = len(dens) if gr.version == 1: amdens = zeros((2, npts), 'd') amgamma = zeros((3, npts), 'd') amdens[0, :] = amdens[1, :] = 0.5 * dens if gamma is not None: amgamma[0, :] = amgamma[1, :] = amgamma[2, :] = 0.25 * gamma elif gr.version == 2: amdens = gr.density.T amgamma = gr.gamma.T fxc, dfxcdna, dfxcdnb, dfxcdgaa, dfxcdgab, dfxcdgbb = XC( amdens, amgamma, **kwargs) Exc = dot(weight, fxc) wva = weight * dfxcdna # Combine w*v in a vector for multiplication by bfs # First do the part that doesn't depend upon gamma nbf = gr.get_nbf() Fxca = zeros((nbf, nbf), 'd') for i in xrange(nbf): wva_i = wva * gr.bfgrid[:, i] for j in xrange(nbf): Fxca[i, j] = dot(wva_i, gr.bfgrid[:, j]) # Now do the gamma-dependent part. # Fxc_a += dot(2 dfxcdgaa*graddensa + dfxcdgab*graddensb,grad(chia*chib)) # We can do the dot product as # sum_grid sum_xyz A[grid,xyz]*B[grid,xyz] # or a 2d trace product # Here A contains the dfxcdgaa stuff # B contains the grad(chia*chib) # Possible errors: gr.grad() here should be the grad of the b part? if do_grad_dens: # A,B are dimensioned (npts,3) A = transpose(0.5 * transpose(gr.grad()) * (weight * (2 * dfxcdgaa + dfxcdgab))) for a in xrange(nbf): for b in xrange(a + 1): B = gr.grad_bf_prod(a, b) Fxca[a, b] += sum(ravel(A * B)) Fxca[b, a] = Fxca[a, b] if not do_spin_polarized: return Exc, Fxca wvb = weight * dfxcdnb # Combine w*v in a vector for multiplication by bfs # First do the part that doesn't depend upon gamma Fxcb = zeros((nbf, nbf), 'd') for i in xrange(nbf): wvb_i = wvb * gr.bfgrid[:, i] for j in xrange(nbf): Fxcb[i, j] = dot(wvb_i, gr.bfgrid[:, j]) # Now do the gamma-dependent part. # Fxc_b += dot(2 dfxcdgbb*graddensb + dfxcdgab*graddensa,grad(chia*chib)) # We can do the dot product as # sum_grid sum_xyz A[grid,xyz]*B[grid,xyz] # or a 2d trace product # Here A contains the dfxcdgaa stuff # B contains the grad(chia*chib) # Possible errors: gr.grad() here should be the grad of the b part? if do_grad_dens: # A,B are dimensioned (npts,3) A = transpose(0.5 * transpose(gr.grad()) * (weight * (2 * dfxcdgbb + dfxcdgab))) for a in xrange(nbf): for b in xrange(a + 1): B = gr.grad_bf_prod(a, b) Fxcb[a, b] += sum(ravel(A * B)) Fxcb[b, a] = Fxcb[a, b] return Exc, Fxca, Fxcb
def stable_solve(A,b): Ainv = pinv(A) return dot(Ainv,b)
def stable_solve(A, b): Ainv = pinv(A) return dot(Ainv, b)
def norm(vec): "val = norm(vec) : Return the 2-norm of a vector" return sqrt(dot(vec,vec))