Exemple #1
0
    def optimize(self, quenchRoutine=None,
                 **kwargs):
        """
        Optimize the band

        Notes
        -----
        the potential for the NEB optimization is not Hamiltonian.  This
        means that there is no meaningful energy associated with the
        potential.  Therefore, during the optimization, we can do gradient
        following, but we can't rely on the energy for, e.g. determining
        step size, which is the default behavior for many optimizers.  This
        can be worked around by choosing a small step size and a large
        maxErise, or by using an optimizer that uses only gradients.

        scipy.lbfgs_b seems to work with NEB pretty well, but lbfgs_py and
        mylbfgs tend to fail.  If you must use one of those try, e.g.
        maxErise = 1., maxstep=0.01, tol=1e-2

        :quenchRoutine: quench algorithm to use for optimization.

        :quenchParams: parameters for the quench """ 
        if quenchRoutine is None:
            if self.quenchRoutine is None:
                quenchRoutine = mylbfgs
            else:
                quenchRoutine = self.quenchRoutine  
        #combine default and passed params.  passed params will overwrite default 
        quenchParams = dict([("nsteps", 300)] +
                            self.quenchParams.items() +
                            kwargs.items())

        if quenchParams.has_key("iprint"):
            self.iprint = quenchParams["iprint"]
        if not quenchParams.has_key("logger"):
            quenchParams["logger"] = logging.getLogger("pygmin.connect.neb.quench")

        if self.use_minimizer_callback:
            quenchParams["events"]=[self._step]
            
        self.step = 0
        qres = quenchRoutine(
                    self.active.reshape(self.active.size), self,
                    **quenchParams)
#        if isinstance(qres, tuple): # for compatability with old and new quenchers
#            qres = qres[4]
        
        self.active[:,:] = qres.coords.reshape(self.active.shape)
        if self.copy_potential:
            for i in xrange(0,self.nimages):
                pot = self.potential_list[i]
                self.energies[i] = pot.getEnergy(self.coords[i,:])
        else:
            for i in xrange(0,self.nimages):
                self.energies[i] = self.potential.getEnergy(self.coords[i,:])
        
        res = Result()
        res.path = self.coords 
        res.nsteps = qres.nsteps
        res.energy = self.energies
        res.rms = qres.rms
        res.success = False
        if qres.rms < quenchParams["tol"]:
            res.success = True
            
        return res
Exemple #2
0
    def optimize(self, quenchRoutine=None, **kwargs):
        """
        Optimize the band

        Notes
        -----
        the potential for the NEB optimization is not Hamiltonian.  This
        means that there is no meaningful energy associated with the
        potential.  Therefore, during the optimization, we can do gradient
        following, but we can't rely on the energy for, e.g. determining
        step size, which is the default behavior for many optimizers.  This
        can be worked around by choosing a small step size and a large
        maxErise, or by using an optimizer that uses only gradients.

        scipy.lbfgs_b seems to work with NEB pretty well, but lbfgs_py and
        mylbfgs tend to fail.  If you must use one of those try, e.g.
        maxErise = 1., maxstep=0.01, tol=1e-2

        :quenchRoutine: quench algorithm to use for optimization.

        :quenchParams: parameters for the quench """
        if quenchRoutine is None:
            if self.quenchRoutine is None:
                quenchRoutine = mylbfgs
            else:
                quenchRoutine = self.quenchRoutine
        #combine default and passed params.  passed params will overwrite default
        quenchParams = dict([("nsteps", 300)] + self.quenchParams.items() +
                            kwargs.items())

        if quenchParams.has_key("iprint"):
            self.iprint = quenchParams["iprint"]
        if not quenchParams.has_key("logger"):
            quenchParams["logger"] = logging.getLogger(
                "pygmin.connect.neb.quench")

        if self.use_minimizer_callback:
            quenchParams["events"] = [self._step]

        self.step = 0
        qres = quenchRoutine(self.active.reshape(self.active.size), self,
                             **quenchParams)
        #        if isinstance(qres, tuple): # for compatability with old and new quenchers
        #            qres = qres[4]

        self.active[:, :] = qres.coords.reshape(self.active.shape)
        if self.copy_potential:
            for i in xrange(0, self.nimages):
                pot = self.potential_list[i]
                self.energies[i] = pot.getEnergy(self.coords[i, :])
        else:
            for i in xrange(0, self.nimages):
                self.energies[i] = self.potential.getEnergy(self.coords[i, :])

        res = Result()
        res.path = self.coords
        res.nsteps = qres.nsteps
        res.energy = self.energies
        res.rms = qres.rms
        res.success = False
        if qres.rms < quenchParams["tol"]:
            res.success = True

        return res