def make_result(self, coords, energy): from pygmin.optimize import Result res = Result() res.coords = coords res.energy = energy res.eigenval = 1. res.eigenvec = coords.copy() return res
def run(self): """The main loop of the algorithm""" coords = np.copy(self.coords) res = Result() # return object res.message = [] for i in xrange(self.nsteps): #get the lowest eigenvalue and eigenvector self.overlap = self._getLowestEigenVector(coords, i) overlap = self.overlap #check to make sure the eigenvector is ok if i == 0 or self.eigenval <= 0: self._saveState(coords) self.reduce_step = 0 else: self.nnegative += 1 if self.nnegative > self.nnegative_max: print "warning: negative eigenvalue found too many times. ending", self.nnegative res.message.append( "negative eigenvalue found too many times %d" % self.nnegative ) break if self.verbosity > 2: print "the eigenvalue turned positive.", self.eigenval, "Resetting last good values and taking smaller steps" coords = self._resetState(coords) self.reduce_step += 1 #step uphill along the direction of the lowest eigenvector coords = self._stepUphill(coords) if False: #maybe we want to update the lowest eigenvector now that we've moved? #david thinks this is a bad idea overlap = self._getLowestEigenVector(coords, i) #minimize the coordinates in the space perpendicular to the lowest eigenvector coords, tangentrms = self._minimizeTangentSpace(coords) #check if we are done and print some stuff E, grad = self.pot.getEnergyGradient(coords) rms = np.linalg.norm(grad) * self.rmsnorm gradpar = np.dot(grad, self.eigenvec) / np.linalg.norm(self.eigenvec) if self.iprint > 0: if (i+1) % self.iprint == 0: ostring = "findTransitionState: %3d E %g rms %g eigenvalue %g rms perp %g grad par %g overlap %g" % ( i, E, rms, self.eigenval, tangentrms, gradpar, overlap) extra = " Evec search: %d rms %g" % (self.leig_result.nfev, self.leig_result.rms) extra += " Tverse search: %d step %g" % (self.tangent_result.nfev, self.tangent_move_step) extra += " Uphill step:%g" % (self.uphill_step_size,) print ostring, extra if callable(self.event): self.event(E, coords, rms) if rms < self.tol: break if self.nfail >= self.nfail_max: print "stopping findTransitionState. too many failures in eigenvector search", self.nfail res.message.append( "too many failures in eigenvector search %d" % self.nfail ) break if i == 0 and self.eigenval > 0.: print "WARNING *** initial eigenvalue is positive - increase NEB spring constant?" if self.demand_initial_negative_vec: print " aborting transition state search" res.message.append( "initial eigenvalue is positive %f" % self.eigenval ) break #done. do one last eigenvector search because coords may have changed self._getLowestEigenVector(coords, i) #done, print some data print "findTransitionState done:", i, E, rms, "eigenvalue", self.eigenval success = True #check if results make sense if self.eigenval >= 0.: if self.verbosity > 2: print "warning: transition state is ending with positive eigenvalue", self.eigenval success = False if rms > self.tol: if self.verbosity > 2: print "warning: transition state search appears to have failed: rms", rms success = False if i >= self.nsteps: res.message.append( "maximum iterations reached %d" % i ) #return results res.coords = coords res.energy = E res.eigenval = self.eigenval res.eigenvec = self.eigenvec res.grad = grad res.rms = rms res.nsteps = i res.success = success return res
def run(self): """The main loop of the algorithm""" coords = np.copy(self.coords) res = Result() # return object res.message = [] for i in xrange(self.nsteps): # get the lowest eigenvalue and eigenvector self.overlap = self._getLowestEigenVector(coords, i) overlap = self.overlap # check to make sure the eigenvector is ok if i == 0 or self.eigenval <= 0: self._saveState(coords) self.reduce_step = 0 else: self.npositive += 1 if self.npositive > self.npositive_max: logger.warning( "positive eigenvalue found too many times. ending %s", self.npositive) res.message.append( "positive eigenvalue found too many times %d" % self.npositive) break if self.verbosity > 2: logger.info( "the eigenvalue turned positive.", self.eigenval, "Resetting last good values and taking smaller steps") coords = self._resetState(coords) self.reduce_step += 1 # step uphill along the direction of the lowest eigenvector coords = self._stepUphill(coords) if False: # maybe we want to update the lowest eigenvector now that we've moved? # david thinks this is a bad idea overlap = self._getLowestEigenVector(coords, i) # minimize the coordinates in the space perpendicular to the lowest eigenvector coords, tangentrms = self._minimizeTangentSpace(coords) # check if we are done and print some stuff E, grad = self.pot.getEnergyGradient(coords) rms = np.linalg.norm(grad) * self.rmsnorm gradpar = np.dot(grad, self.eigenvec) / np.linalg.norm( self.eigenvec) if self.iprint > 0: if (i + 1) % self.iprint == 0: ostring = "findTS: %3d E %9g rms %8g eigenvalue %9g rms perp %8g grad par %9g overlap %g" % ( i, E, rms, self.eigenval, tangentrms, gradpar, overlap) extra = " Evec search: %d rms %g" % ( self.leig_result.nfev, self.leig_result.rms) extra += " Tverse search: %d step %g" % ( self.tangent_result.nfev, self.tangent_move_step) extra += " Uphill step:%g" % (self.uphill_step_size, ) logger.info("%s %s", ostring, extra) if callable(self.event): self.event(energy=E, coords=coords, rms=rms, eigenval=self.eigenval, stepnum=i) if rms < self.tol: break if self.nfail >= self.nfail_max: logger.warning( "stopping findTransitionState. too many failures in eigenvector search %s", self.nfail) res.message.append( "too many failures in eigenvector search %d" % self.nfail) break if i == 0 and self.eigenval > 0.: logger.warning( "initial eigenvalue is positive - increase NEB spring constant?" ) if self.demand_initial_negative_vec: logger.warning( " aborting transition state search") res.message.append("initial eigenvalue is positive %f" % self.eigenval) break # done. do one last eigenvector search because coords may have changed self._getLowestEigenVector(coords, i) # print some data logger.info("findTransitionState done: %s %s %s %s %s", i, E, rms, "eigenvalue", self.eigenval) success = True # check if results make sense if self.eigenval >= 0.: if self.verbosity > 2: logger.info( "warning: transition state is ending with positive eigenvalue %s", self.eigenval) success = False if rms > self.tol: if self.verbosity > 2: logger.info( "warning: transition state search appears to have failed: rms %s", rms) success = False if i >= self.nsteps: res.message.append("maximum iterations reached %d" % i) #return results res.coords = coords res.energy = E res.eigenval = self.eigenval res.eigenvec = self.eigenvec res.grad = grad res.rms = rms res.nsteps = i res.success = success return res