def amp(self, x, y, z): "Compute the amplitude of the PGBF at point x,y,z" i, j, k = self.powers x0, y0, z0 = self.origin return self.norm*self.coef*\ pow(x-x0,i)*pow(y-y0,j)*pow(z-z0,k)*\ exp(-self.exp*dist2((x,y,z),(x0,y0,z0)))
def amp(self,x,y,z): "Compute the amplitude of the PGBF at point x,y,z" i,j,k = self.powers x0,y0,z0 = self.origin return self.norm*self.coef*\ pow(x-x0,i)*pow(y-y0,j)*pow(z-z0,k)*\ exp(-self.exp*dist2((x,y,z),(x0,y0,z0)))
def amp(self,x,y,z): "Compute the amplitude of the PGBF at point x,y,z" i,j,k = self._powers x0,y0,z0 = self._origin return self._normalization*self._coefficient*\ pow(x-x0,i)*pow(y-y0,j)*pow(z-z0,k)*\ exp(-self._exponent*dist2((x,y,z),(x0,y0,z0)))
def test_distance(old,new): from PyQuante.cints import dist2 points = old.points() s = 0 for i in xrange(new.ng): x1,y1,z1,w1 = points[i].xyzw() x2,y2,z2,w2 = new[i] s += dist2((x1,y1,z1),(x2,y2,z2)) return s<1e-5
def patch_atoms_naive(self,**opts): """\ This was the original PyQuante patching scheme. It simply cuts off the grid at the voronai polyhedra. That is, if a grid point is closer to another nucleus than it is to its parent nucleus, its weight is set to zero. """ nat = len(self.atoms) for iat in range(nat): ati = self.atoms[iat] npts = len(self.atomgrids[iat]) for i in range(npts): point = self.atomgrids[iat].points[i] xp,yp,zp,wp = point.xyzw() rip2 = dist2(ati.pos(),(xp,yp,zp)) for jat in range(nat): if jat == iat: continue atj = self.atoms[jat] rjp2 = dist2(atj.pos(),(xp,yp,zp)) if rjp2 < rip2: point._w = 0 return
def patch_atoms_naive(self, **kwargs): """\ This was the original PyQuante patching scheme. It simply cuts off the grid at the voronai polyhedra. That is, if a grid point is closer to another nucleus than it is to its parent nucleus, its weight is set to zero. """ nat = len(self.atoms) for iat in xrange(nat): ati = self.atoms[iat] npts = len(self.atomgrids[iat]) for i in xrange(npts): point = self.atomgrids[iat].points[i] xp, yp, zp, wp = point.xyzw() rip2 = dist2(ati.pos(), (xp, yp, zp)) for jat in xrange(nat): if jat == iat: continue atj = self.atoms[jat] rjp2 = dist2(atj.pos(), (xp, yp, zp)) if rjp2 < rip2: point._w = 0 return
def patch_atoms(self,**opts): """\ This is Becke's patching algorithm. Attempting to implement the normalization that is in eq 22 of that reference. """ nat = len(self.atoms) for iat in range(nat): ati = self.atoms[iat] npts = len(self.atomgrids[iat]) for i in xrange(npts): point = self.atomgrids[iat].points[i] xp,yp,zp,wp = point.xyzw() rip2 = dist2(ati.pos(),(xp,yp,zp)) rip = sqrt(rip2) Pnum = 1 Pdenom = 0 for jat in xrange(nat): bap = becke_atomic_grid_p(jat,(xp,yp,zp),self.atoms,**opts) Pdenom += bap if iat == jat: P_iat = bap Ptot = P_iat/Pdenom point._w *= Ptot return
def patch_atoms(self,**opts): """\ This is Becke's patching algorithm. Attempting to implement the normalization that is in eq 22 of that reference. """ nat = len(self.atoms) for iat in xrange(nat): ati = self.atoms[iat] npts = len(self.atomgrids[iat]) for i in xrange(npts): point = self.atomgrids[iat].points[i] xp,yp,zp,wp = point.xyzw() rip2 = dist2(ati.pos(),(xp,yp,zp)) rip = sqrt(rip2) Pnum = 1 Pdenom = 0 for jat in xrange(nat): bap = becke_atomic_grid_p(jat,(xp,yp,zp),self.atoms,**opts) Pdenom += bap if iat == jat: P_iat = bap Ptot = P_iat/Pdenom point._w *= Ptot return
bfs = reshape(bfs,(npts,nbf)) return bfs # These are the functions for the becke projection operator def fbecke(x,n=3): for i in range(n): x = pbecke(x) return x def pbecke(x): return 1.5*x-0.5*pow(x,3) def sbecke(x,n=3): return 0.5*(1-fbecke(x,n)) def becke_atomic_grid_p(iat,(xp,yp,zp),atoms,**opts): do_becke_hetero = opts.get('do_becke_hetero',True) nat = len(atoms) sprod = 1 ati = atoms[iat] rip2 = dist2(ati.pos(),(xp,yp,zp)) rip = sqrt(rip2) for jat in range(nat): if jat == iat: continue atj = atoms[jat] rjp2 = dist2(atj.pos(),(xp,yp,zp)) rjp = sqrt(rjp2) rij2 = dist2(ati.pos(),atj.pos()) rij = sqrt(rij2) mu = (rip-rjp)/rij # Modify mu based on Becke hetero formulas (App A) if do_becke_hetero and ati.atno != atj.atno: chi = Bragg[ati.atno]/Bragg[atj.atno] u = (chi-1.)/(chi+1.) a = u/(u*u-1) a = min(a,0.5)
def dist2(self, atom): return dist2(self.pos(), atom.pos())
def dist2(self,atom): return dist2(self.pos(),atom.pos()) def dist(self,atom): return dist(self.pos(),atom.pos())
def pbecke(x): return 1.5 * x - 0.5 * pow(x, 3) def sbecke(x, n=3): return 0.5 * (1 - fbecke(x, n)) def becke_atomic_grid_p(iat, (xp, yp, zp), atoms, **kwargs): do_becke_hetero = kwargs.get('do_becke_hetero', settings.DFTBeckeHetero) nat = len(atoms) sprod = 1 ati = atoms[iat] rip2 = dist2(ati.pos(), (xp, yp, zp)) rip = sqrt(rip2) for jat in xrange(nat): if jat == iat: continue atj = atoms[jat] rjp2 = dist2(atj.pos(), (xp, yp, zp)) rjp = sqrt(rjp2) rij2 = dist2(ati.pos(), atj.pos()) rij = sqrt(rij2) mu = (rip - rjp) / rij # Modify mu based on Becke hetero formulas (App A) if do_becke_hetero and ati.atno != atj.atno: chi = Bragg[ati.atno] / Bragg[atj.atno] u = (chi - 1.) / (chi + 1.) a = u / (u * u - 1) a = min(a, 0.5)