import numpy as np import oxdnagmin_ as GMIN from pele.potentials.gminpotential import GMINPotential import pele.basinhopping as bh from pele.takestep import displace from pele.storage.database import Database # initialize GMIN GMIN.initialize() # create a potential which calls GMIN potential = GMINPotential(GMIN) # get the initial coorinates coords = potential.getCoords() coords = np.random.random(coords.shape) # create takestep routine step = displace.RandomDisplacement(stepsize=1.) # store all minima in a database db = Database(db="storage.sqlite", accuracy=1e-2) # create Basinhopping object opt = bh.BasinHopping(coords, potential, step, db.minimum_adder()) # run for 100 steps opt.run(1000) # now dump all the minima i = 0 for m in db.minima(): i += 1 GMIN.userpot_dump("lowest_%03d.dat" % (i), m.coords)
rotate=0.), frequency=50) step2 = takestep.AdaptiveStepsize(OXDNATakestep(displace=0., rotate=parameters.rotate), frequency=50) group.addBlock(100, step1) group.addBlock(100, step2) # with a generate random configuration genrandom = OXDNAReseed() # in a reseeding takestep procedure reseed = takestep.Reseeding(group, genrandom, maxnoimprove=parameters.reseed) # store all minima in a database db = Database(db="storage.sqlite", accuracy=1e-2) # create Basinhopping object opt = BasinHopping(coords, potential, reseed, db.minimum_adder(), temperature=parameters.temperature) # run for 100 steps opt.run(parameters.nsteps) # now dump all the minima i = 0 for m in db.minima(): i += 1 GMIN.userpot_dump("lowest_%03d.dat" % (i), m.coords)
class BatchGeneticAlgorithm(object): '''The Birmingham Cluster Genetic Algorithm. A new parallel version of the BCGA. The population is stored in a pele database and can be accessed by several processes simultaneously. Parameters: natoms- Number of atoms in cluster minimiser- See bcga.gpaw_interface Optional parameters: composition- A list containing the number of atoms of each type labels- A tuple orblist containing the names of each atom type (e.g. ["Au","Ag"] pop_size- Number of clusters in population max_generation- Number of generations to run GA selector- Selection method for choosing parents (see bcga.selector) offspring- Number of crossover operations in each generation mutant_rate- Probability of any cluster producing a mutant remove_duplicates- Remove identical clusters from population to prevent stagnation restart- Read population from restart.xyz and continue a search ''' def __init__(self, natoms, minimiser, composition="default", labels=("X", ), pop_size=10, max_generation=10, selector=TournamentSelector(3), offspring=8, mutant_rate=0.1, remove_duplicates=False, mutator=MutateReplace(), crossover=DeavenHo()): #Parameters self.max_generation = max_generation self.mutant_rate = mutant_rate self.offspring = offspring self.pop_size = pop_size self.remove_duplicates = remove_duplicates self.selector = selector self.mutator = mutator self.crossover = crossover #Factory self.factory = ClusterFactory(natoms, minimiser, composition, labels) #PopulationList self.population = PopulationList(natoms, self.factory, pop_size) #Evolutionary progress self.mean_energy_series = [] self.min_energy_series = [] self.db = Database(db="mydatabase.sqlite") self.storage = self.db.minimum_adder() def write_xyz(self, file_name="cluster.xyz"): '''Open an xyz file and write the current population to it (non-blocking).''' try: with open(file_name, 'w') as xyz_file: self.population.write_xyz(xyz_file) except IOError as err: print("File error: " + str(err)) def read_xyz(self, file_name="restart.xyz"): '''Read population from an xyz file (non-blocking for now).''' self.population.mass_extinction(0) try: with open(file_name) as xyz_file: self.population.read_xyz(xyz_file) except: print("No restart file available.") def run(self): '''Run the GA.''' for generation in range(1, self.max_generation + 1): print("Generation " + str(generation)) if self.db.number_of_minima() < self.population.max_size: cluster = self.factory.get_random_cluster() print("Filling population with random structure.") else: self.population.read_db(self.db) if np.random < self.mutant_rate: index = np.random.randint(0, len(self.population)) cluster = self.mutator.get_mutant(self.population[index]) print("Generating mutant of cluster " + str(index)) else: indices = self.selector.select(self.population) cluster = self.crossover.get_offspring( self.population[indices[0]], self.population[indices[1]]) print("Generating offpsring of clusters " + str(indices[0]) + " and " + str(indices[1])) cluster.minimise() #self.read_xyz("restart.xyz") #self.population.append(cluster) self.storage(cluster.energy, cluster._coords.flatten())
class BatchGeneticAlgorithm(object): '''The Birmingham Cluster Genetic Algorithm. A new parallel version of the BCGA. The population is stored in a pele database and can be accessed by several processes simultaneously. Parameters: natoms- Number of atoms in cluster minimiser- See bcga.gpaw_interface Optional parameters: composition- A list containing the number of atoms of each type labels- A tuple orblist containing the names of each atom type (e.g. ["Au","Ag"] pop_size- Number of clusters in population max_generation- Number of generations to run GA selector- Selection method for choosing parents (see bcga.selector) offspring- Number of crossover operations in each generation mutant_rate- Probability of any cluster producing a mutant remove_duplicates- Remove identical clusters from population to prevent stagnation restart- Read population from restart.xyz and continue a search ''' def __init__(self,natoms,minimiser, composition="default",labels=("X",), pop_size=10,max_generation=10, selector=TournamentSelector(3), offspring=8,mutant_rate=0.1,remove_duplicates=False, mutator=MutateReplace(), crossover=DeavenHo()): #Parameters self.max_generation = max_generation self.mutant_rate = mutant_rate self.offspring=offspring self.pop_size=pop_size self.remove_duplicates=remove_duplicates self.selector=selector self.mutator = mutator self.crossover = crossover #Factory self.factory=ClusterFactory(natoms,minimiser,composition,labels) #PopulationList self.population = PopulationList(natoms,self.factory,pop_size) #Evolutionary progress self.mean_energy_series=[] self.min_energy_series=[] self.db = Database(db="mydatabase.sqlite") self.storage = self.db.minimum_adder() def write_xyz(self,file_name="cluster.xyz"): '''Open an xyz file and write the current population to it (non-blocking).''' try: with open(file_name,'w') as xyz_file: self.population.write_xyz(xyz_file) except IOError as err: print("File error: "+str(err)) def read_xyz(self,file_name="restart.xyz"): '''Read population from an xyz file (non-blocking for now).''' self.population.mass_extinction(0) try: with open(file_name) as xyz_file: self.population.read_xyz(xyz_file) except: print("No restart file available.") def run(self): '''Run the GA.''' for generation in range(1,self.max_generation+1): print ("Generation "+str(generation)) if self.db.number_of_minima() < self.population.max_size: cluster=self.factory.get_random_cluster() print("Filling population with random structure.") else: self.population.read_db(self.db) if np.random < self.mutant_rate: index=np.random.randint(0,len(self.population)) cluster=self.mutator.get_mutant(self.population[index]) print("Generating mutant of cluster "+str(index)) else: indices = self.selector.select(self.population) cluster=self.crossover.get_offspring(self.population[indices[0]], self.population[indices[1]]) print("Generating offpsring of clusters "+str(indices[0])+" and "+str(indices[1])) cluster.minimise() #self.read_xyz("restart.xyz") #self.population.append(cluster) self.storage(cluster.energy,cluster._coords.flatten())
coords=potential.getCoords() coords=np.random.random(coords.shape) # create takestep routine # we combine a normal step taking group = takestep.BlockMoves() step1 = takestep.AdaptiveStepsize(OXDNATakestep(displace=parameters.displace, rotate=0.), frequency=50) step2 = takestep.AdaptiveStepsize(OXDNATakestep(displace=0., rotate=parameters.rotate), frequency=50) group.addBlock(100, step1) group.addBlock(100, step2) # with a generate random configuration genrandom = OXDNAReseed() # in a reseeding takestep procedure reseed = takestep.Reseeding(group, genrandom, maxnoimprove=parameters.reseed) # store all minima in a database db = Database(db="storage.sqlite", accuracy=1e-2) # create Basinhopping object opt = BasinHopping(coords, potential, reseed, db.minimum_adder(), temperature=parameters.temperature) # run for 100 steps opt.run(parameters.nsteps) # now dump all the minima i=0 for m in db.minima(): i+=1 GMIN.userpot_dump("lowest_%03d.dat"%(i), m.coords)