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 |