The main algorithm for global optimization is basin hopping. The core object for a basin hopping run is a BasinHopping object. The step taking and various other customization routines (e.g. storage, acceptance criterion, ...) can be attached to this object to customize the behaviour of the basin hopping procedure.
| BasinHopping(coords, potential, takeStep[, ...]) | A class to run the basin hopping algorithm |
import numpy as np
import pele.potentials.lj as lj
import pele.basinhopping as bh
from pele.takestep import displace
natoms = 12
# random initial coordinates
coords=np.random.random(3*natoms)
potential = lj.LJ()
step = displace.RandomDisplacement(stepsize=0.5)
opt = bh.BasinHopping(coords, potential, takeStep=step)
opt.run(100)
The performance of the basin hopping critically depends on the step taking algorithm. pele comes with a set of basic takestep routines. For anything non-standard, the user is encouraged to implement a custom takestep routine.
| RandomDisplacement([stepsize]) | Random displacement on each individual coordinate |
| UniformDisplacement([srange, stepsize]) | Displace each atom be a uniform random vector |
| RotationalDisplacement([srange, stepsize]) | Random rotation for angle axis vector |
| ParticleExchange(Alist, Blist[, verbose]) | Implement a takestep move which swaps two un-like atoms |
| AdaptiveStepsize(stepclass[, acc_ratio, ...]) | Adaptive stepsize adjustment |
| AdaptiveStepsizeTemperature(stepclass[, ...]) | adjust both the stepsize and the temperature adaptively |
| GroupSteps(steptakers) | group several takestep objects |
| BlockMoves() | block based step taking |
| Reseeding(takestep, reseed[, maxnoimprove, ...]) | Reseeding if energy did not improve |
pele makes it very simple to design custom takestep routines. Any takestep class should have TakestepInterface as a parent class (directly derived from that or a child class of TakestepInterface).
from pele.takestep import TakestepInterface
from pele.takestep import buildingblocks as bb
class MyStep(TakestepInterface):
def takeStep(self, coords, **kwargs):
# create an rigid body coordinate interface for coordinates array
ca = CoordsAdapter(nrigid=GMIN.getNRigidBody(), nlattice=6, coords=coords)
# rotate one random rigid body
select = [np.random.randint(0,nrigid)]
bb.rotate(1.6, ca.rotRigid, indices = select)
Building blocks to design custom takestep routines
| uniform_displace(stepsize, coords[, indices]) | uniform random displacement |
| rotate(stepsize, coords[, indices]) | uniform random rotation of angle axis vector |
| reduced_coordinates_displace(stepsize, ...) | uniform random displacement of reduced coordinates |
The takestep interface
| TakestepInterface | Interface for step taking classes .. |
| Takestep([stepsize]) | basic takestep interface which stores the stepsize |
| TakestepSlice([srange, stepsize]) | basic takestep interface on slice of coordinates array |