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