Example #1
0
    def NEBForce(self, isclimbing, image, left, right, greal, icenter):
        """
        Calculate NEB force for 1 image. That contains projected real force and spring force.

        The current implementation is the DNEB (doubly nudged elastic band) as described in

        "A doubly nudged elastic band method for finding transition states"
        S***n A. Trygubenko and David J. Wales
        J. Chem. Phys. 120, 2082 (2004); doi: 10.1063/1.1636455

        """

        # construct tangent vector
        d_left, g_left = self.distance(image[1], left[1], distance=True)#self.with_springenergy)
        d_right, g_right = self.distance(image[1], right[1], distance=True)#self.with_springenergy)
        self.distances[icenter-1] = np.sqrt(d_left)
        self.distances[icenter] = np.sqrt(d_right)
        #print g_left, g_right
        
        t = self.tangent(image[0],left[0],right[0], g_left, g_right)
        if(isclimbing):
            return greal - 2.*np.dot(greal, t) * t

        if self.dneb:
            g_spring = self.k*(g_left + g_right)
        else:
            g_spring = self.k*(norm(g_left) - norm(g_right))*t

        #print "spring", np.dot(g_spring, t)
        if True:
            import _NEB_utils
            E, g_tot = _NEB_utils.neb_force(t,greal, g_spring, self.k, self.dneb)
            if self.with_springenergy:
                return E, g_tot
            else:
                return 0., g_tot
        else:
    
            # project out parallel part
            gperp = greal - np.dot(greal, t) * t
            # calculate parallel spring force and energy
            #gspring = -self.k * (np.linalg.norm(d2) - np.linalg.norm(d1)) * t
            # this is the spring
            # the parallel part
            gs_par = np.dot(g_spring,t)*t
                                    
            g_tot = gperp + gs_par
    
            if(self.dneb):
                # perpendicular part of spring
                gs_perp = g_spring - gs_par            
                # double nudging
                g_tot += gs_perp - np.dot(gs_perp,gperp)*gperp/np.dot(gperp,gperp)
            
            if(self.with_springenergy):
                E = 0.5 / self.k * (d_left **2 + d_right**2)
            else:
                E = 0.
            #print np.linalg.norm(gperp), np.linalg.norm(gs_par)
            return E, g_tot
Example #2
0
    def NEBForce(self, isclimbing, image, left, right, greal, icenter):
        """
        Calculate NEB force for 1 image. That contains projected real force and spring force.

        The current implementation is the DNEB (doubly nudged elastic band) as described in

        "A doubly nudged elastic band method for finding transition states"
        S***n A. Trygubenko and David J. Wales
        J. Chem. Phys. 120, 2082 (2004); doi: 10.1063/1.1636455

        """

        # construct tangent vector
        d_left, g_left = self.distance(image[1], left[1],
                                       distance=True)  #self.with_springenergy)
        d_right, g_right = self.distance(
            image[1], right[1], distance=True)  #self.with_springenergy)
        self.distances[icenter - 1] = np.sqrt(d_left)
        self.distances[icenter] = np.sqrt(d_right)
        #print g_left, g_right

        t = self.tangent(image[0], left[0], right[0], g_left, g_right)
        if (isclimbing):
            return greal - 2. * np.dot(greal, t) * t

        #print "spring", np.dot(g_spring, t)
        if True:
            import _NEB_utils
            E, g_tot = _NEB_utils.neb_force(t, greal, d_left, g_left, d_right,
                                            g_right, self.k, self.dneb)
            if self.with_springenergy:
                return E, g_tot
            else:
                return 0., g_tot
        else:

            # project out parallel part
            gperp = greal - np.dot(greal, t) * t

            # parallel part of spring force
            gs_par = self.k * (d_left - d_right) * t

            g_tot = gperp + gs_par

            if (self.dneb):
                g_spring = self.k * (g_left + g_right)

                # perpendicular part of spring
                gs_perp = g_spring - np.dot(g_spring, t) * t
                # double nudging
                g_tot += gs_perp - np.dot(gs_perp, gperp) * gperp / np.dot(
                    gperp, gperp)

            if (self.with_springenergy):
                E = 0.5 / self.k * (d_left**2 + d_right**2)
            else:
                E = 0.
            #print np.linalg.norm(gperp), np.linalg.norm(gs_par)
            return E, g_tot