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
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