Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
    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')
Пример #4
0
    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')