def get_gamma(self, a=None): """ Return the gamma correlation matrix, i.e. phi(i) = gamma(i, j)*q(j) """ if a is not None: self.update(a) self.timer.start('get_gamma') nat = len(self.a) il, jl, dl, nl = get_neighbors(self.a, self.cutoff) if il is None: G = None else: G = np.zeros([nat, nat], dtype=float) if self.cutoff is None: for i, j, d in zip(il, jl, dl): G[i, j] += 1.0/d else: for i, j, d in zip(il, jl, dl): G[i, j] += 1.0*erfc(d/self.cutoff)/d self.timer.stop('get_gamma') return G
def get_gamma(self, a=None): """ Return the gamma correlation matrix, i.e. phi(i) = gamma(i, j)*q(j) """ if a is not None: self.update(a) self.timer.start('get_gamma') nat = len(self.a) il, jl, dl, nl = get_neighbors(self.a, self.cutoff) if il is None: G = None else: G = np.zeros([nat, nat], dtype=float) if self.cutoff is None: for i, j, d in zip(il, jl, dl): G[i, j] += 1.0 / d else: for i, j, d in zip(il, jl, dl): G[i, j] += 1.0 * erfc(d / self.cutoff) / d self.timer.stop('get_gamma') return G
def _update(self, a, q): """ Compute the electrostatic potential and field on each atom in a. Parameters: ----------- a: Hotbit Atoms object, or atoms object that implements the transform and rotation interface. q: Charges """ self.timer.start('direct_coulomb') self.a = a self.r_av = a.get_positions().copy() self.q_a = q.copy() nat = len(a) il, jl, dl, nl = get_neighbors(a, self.cutoff) if il is not None: if self.cutoff is None: phi = q[jl] / dl dl **= 2 E = q[jl].reshape(-1, 1) * nl / dl.reshape(-1, 1) else: f = erfc(dl / self.cutoff) df = 2 / sqrt(pi) * np.exp(-(dl / self.cutoff)**2) / self.cutoff phi = q[jl] * f / dl E = q[jl] * (df + f / dl) / dl E = E.reshape(-1, 1) * nl self.phi_a = np.zeros(nat, dtype=float) self.E_av = np.zeros([nat, 3], dtype=float) if il is not None: # FIXME!!! Is there some fast numpy magic to compute this? for i in xrange(nat): self.phi_a[i] = phi[il == i].sum() self.E_av[i, :] = E[il == i].sum(axis=0) self.timer.stop('direct_coulomb')
def _update(self, a, q): """ Compute the electrostatic potential and field on each atom in a. Parameters: ----------- a: Hotbit Atoms object, or atoms object that implements the transform and rotation interface. q: Charges """ self.timer.start('direct_coulomb') self.a = a self.r_av = a.get_positions().copy() self.q_a = q.copy() nat = len(a) il, jl, dl, nl = get_neighbors(a, self.cutoff) if il is not None: if self.cutoff is None: phi = q[jl]/dl dl **= 2 E = q[jl].reshape(-1, 1)*nl/dl.reshape(-1, 1) else: f = erfc(dl/self.cutoff) df = 2/sqrt(pi)*np.exp(-(dl/self.cutoff)**2)/self.cutoff phi = q[jl]*f/dl E = q[jl]*(df + f/dl)/dl E = E.reshape(-1, 1)*nl self.phi_a = np.zeros(nat, dtype=float) self.E_av = np.zeros([nat, 3], dtype=float) if il is not None: # FIXME!!! Is there some fast numpy magic to compute this? for i in xrange(nat): self.phi_a[i] = phi[il == i].sum() self.E_av[i, :] = E[il == i].sum(axis=0) self.timer.stop('direct_coulomb')