def quench(indiv, Optimizer): """Move function to perform a molecular dynamics NVT quenching of structure Inputs: indiv = Individual class object to be altered Optimizer = Optimizer class object with needed parameters Outputs: indiv = Altered Individual class object """ if 'MU' in Optimizer.debug: debug = True else: debug = False olammps_min = Optimizer.lammps_min ocalc = Optimizer.calc mincomd = '1.0e-8 1.0e-8 1000 100000\nunfix fix_nve\nfix fix_nvt all nvt temp '+repr(Optimizer.quench_max_temp)+' '+repr(Optimizer.quench_min_temp)+' '+repr(Optimizer.quench_step_size) mincomd += '\nrun '+repr(Optimizer.quench_n_steps_1)+'\nunfix fix_nvt\nfix fix_nve all nve\nminimize 1.0e-8 1.0e-8 1000 100000' mincomd += '\nunfix fix_nve\nfix fix_nvt all nvt temp '+repr(Optimizer.quench_max_temp)+' '+repr(Optimizer.quench_min_temp)+' '+repr(Optimizer.quench_step_size) mincomd += '\nrun '+repr(Optimizer.quench_n_steps_2)+'\nunfix fix_nvt\nfix fix_nve all nve\nminimize 1.0e-8 1.0e-8 1000 100000' Optimizer.lammps_min = mincomd Optimizer.calc = setup_calculator(Optimizer) outs = fitness_switch([Optimizer,indiv]) indiv = outs[0] Optimizer.output.write('Quench NVT Mutation performed on individual\n') Optimizer.output.write('Index = '+repr(indiv.index)+'\n') Optimizer.output.write(outs[1]) Optimizer.output.write('New fitness : '+repr(indiv.fitness)+'\n') muttype='Q' Optimizer.lammps_min = olammps_min Optimizer.calc = setup_calculator(Optimizer) if indiv.energy==0: indiv.history_index=indiv.history_index+'m'+muttype else: indiv.history_index=repr(indiv.index)+'m'+muttype return indiv
def algorithm_par_mp(self): """Subprogram for running parallel version of GA Requires MPI4PY""" global logger comm = MPI.COMM_WORLD rank = MPI.COMM_WORLD.Get_rank() if rank==0: if 'MA' in self.debug: debug = True else: debug = False self.algorithm_initialize() self.convergence = False convergence = False while not convergence: if rank==0: pop = self.population offspring = self.generation_set(self,pop) # Identify the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if ind.energy==0] #Evaluate the individuals with invalid fitness self.output.write('\n--Evaluate Structures--\n') else: invalid_ind=[] for i in range(len(invalid_ind)): if self.fitness_scheme=='STEM_Cost': if self.stem_coeff==None: ind = invalid_ind.pop() from MAST.structopt_stem.tools.StemCalc import find_stem_coeff outs = find_stem_coeff(self,ind) ind = outs[1] self.stem_coeff = outs[0] self.output.write('stem_coeff Calculated to be: '+repr(self.stem_coeff)+'\n') pop.append(ind) ind=invalid_ind[i] if 'MA' in self.debug: write_xyz(self.debugfile,ind[0],'Individual to fitness_switch') outs = switches.fitness_switch([self,ind]) self.output.write(outs[1]) invalid_ind[i]=outs[0] self.output.flush() if rank==0: pop.extend(invalid_ind) pop = self.generation_eval(pop) self.write() convergence = comm.bcast(self.convergence, root=0) if rank==0: end_signal = self.algorithm_stats(self.population) else: end_signal = None end_signal = comm.bcast(end_signal, root=0) return end_signal
def algorithm_serial(self): """Subprogram to run the optimizer in serial""" global logger self.algorithm_initialize() logger.info('Beginning main algorithm loop') #Begin main algorithm loop while not self.convergence: logger.info('Setup calculator for generation {0}'.format(self.generation)) pop = self.population logger.info('Setup population') offspring = self.generation_set(pop) # Identify the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if ind.energy==0] #DEBUG: Write first invalid ind if 'MA' in self.debug: logger.info('Identified {0} structures with energy=0'.format(len(invalid_ind))) inp_out.write_xyz(self.debugfile,invalid_ind[0][0],\ 'First from Invalid_ind list '+repr(invalid_ind[0].energy)) #DEBUG: Write first invalid ind in solid if self.structure=='Defect' or self.structure=='Surface': sols = invalid_ind[0][0].copy() sols.extend(invalid_ind[0].bulki) inp_out.write_xyz(self.debugfile,sols,'First from Invalid-ind + Bulki') sols = invalid_ind[0][0].copy() sols.extend(invalid_ind[0].bulko) inp_out.write_xyz(self.debugfile,sols,'First from Invalid-ind + Bulko') self.output.write('\n--Evaluate Structures--\n') logger.info('Evaluating fitness of structures') for i in range(len(invalid_ind)): ind = invalid_ind[i] if 'MA' in self.debug: write_xyz(self.debugfile,ind[0],'Individual to fitness_switch') outs = switches.fitness_switch([self,ind]) self.output.write(outs[1]) invalid_ind[i] = outs[0] pop.extend(invalid_ind) logger.info('Eval Population') pop = self.generation_eval(pop) self.write() logger.info('Run algorithm stats') end_signal = self.algorithm_stats(self.population) return end_signal
def quench(indiv, Optimizer): """Move function to perform a molecular dynamics NVT quenching of structure Inputs: indiv = Individual class object to be altered Optimizer = Optimizer class object with needed parameters Outputs: indiv = Altered Individual class object """ if 'MU' in Optimizer.debug: debug = True else: debug = False try: omin = copy.deepcopy(Optimizer.calc.parameters['minimize']) mincomd = omin+'\nunfix fix_nve\nfix fix_nvt all nvt temp '+repr(Optimizer.quench_max_temp)+' '+repr(Optimizer.quench_min_temp)+' '+repr(Optimizer.quench_step_size) mincomd += '\nrun '+repr(Optimizer.quench_n_steps_1)+'\nunfix fix_nvt\nfix fix_nve all nve\nminimize '+omin mincomd += '\nunfix fix_nve\nfix fix_nvt all nvt temp '+repr(Optimizer.quench_max_temp)+' '+repr(Optimizer.quench_min_temp)+' '+repr(Optimizer.quench_step_size) mincomd += '\nrun '+repr(Optimizer.quench_n_steps_2)+'\nunfix fix_nvt\nfix fix_nve all nve\nminimize '+omin except: omin = None pms = copy.deepcopy(Optimizer.calc.parameters) mincomd = '1.0e-8 1.0e-8 1000 100000\nunfix fix_nve\nfix fix_nvt all nvt temp '+repr(Optimizer.quench_max_temp)+' '+repr(Optimizer.quench_min_temp)+' '+repr(Optimizer.quench_step_size) mincomd += '\nrun '+repr(Optimizer.quench_n_steps_1)+'\nunfix fix_nvt\nfix fix_nve all nve\nminimize 1.0e-8 1.0e-8 1000 100000' mincomd += '\nunfix fix_nve\nfix fix_nvt all nvt temp '+repr(Optimizer.quench_max_temp)+' '+repr(Optimizer.quench_min_temp)+' '+repr(Optimizer.quench_step_size) mincomd += '\nrun '+repr(Optimizer.quench_n_steps_2)+'\nunfix fix_nvt\nfix fix_nve all nve\nminimize 1.0e-8 1.0e-8 1000 100000' Optimizer.calc.parameters['minimize'] = mincomd Optimizer.calc.parameters['thermosteps'] = Optimizer.lammps_thermo_steps outs = fitness_switch([Optimizer,indiv]) indiv = outs[0] Optimizer.output.write('Quench1 NVT Mutation performed on individual\n') Optimizer.output.write('Index = '+repr(indiv.index)+'\n') Optimizer.output.write(outs[1]) Optimizer.output.write('New fitness : '+repr(indiv.fitness)+'\n') muttype='Q' if omin == None: Optimizer.calc.parameters = pms else: Optimizer.calc.parameters['minimize'] = omin if indiv.energy==0: indiv.history_index=indiv.history_index+'m'+muttype else: indiv.history_index=repr(indiv.index)+'m'+muttype return indiv
def algorithm_par_mp1(self): """Subprogram for running parallel version of GA Requires MPI4PY""" comm = MPI.COMM_WORLD rank = MPI.COMM_WORLD.Get_rank() if rank==0: if 'MA' in self.debug: debug = True else: debug = False self.algorithm_initialize() self.convergence = False convergence = False while not convergence: if rank==0: self.calc = tools.setup_calculator(self) #Set up calculator for atomic structures #Set up calculator for fixed region calculations if self.fixed_region: self.static_calc = self.calc #May need to copy this self.calc = tools.setup_fixed_region_calculator(self) pop = self.population offspring = self.generation_set(self,pop) # Identify the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if ind.energy==0] #Evaluate the individuals with invalid fitness self.output.write('\n--Evaluate Structures--\n') proc_dist = int(comm.Get_size()/self.n_proc_eval) ntimes=int(math.ceil(float(len(invalid_ind))/float(proc_dist))) nadd=int(ntimes*proc_dist-len(invalid_ind)) maplist=[[] for n in range(ntimes)] strt=0 for i in range(len(maplist)): maplist[i]=[[self,indi] for indi in invalid_ind[strt:proc_dist+strt]] strt+=proc_dist for i in range(nadd): maplist[len(maplist)-1].append([None,None]) masterlist = [i*self.n_proc_eval for i in range(proc_dist)] else: ntimes=None masterlist = None ntimes = comm.bcast(ntimes,root=0) outs=[] for i in range(ntimes): if rank==0: one=maplist[i] for j in range(len(one)): comm.send(ind, dest=1, tag=11) elif rank == 1: ind = comm.recv(source=0, tag=11) else: one=None ind =comm.scatter(one,root=0) out = switches.fitness_switch(ind) else: invalid_ind=[] poorlist = [] for i in range(len(invalid_ind)): if self.fitness_scheme=='STEM_Cost': if self.stem_coeff==None: ind = invalid_ind.pop() from MAST.structopt_stem.tools.StemCalc import find_stem_coeff outs = find_stem_coeff(self,ind) ind = outs[1] self.stem_coeff = outs[0] self.output.write('stem_coeff Calculated to be: '+repr(self.stem_coeff)+'\n') pop.append(ind) ind=invalid_ind[i] if 'MA' in self.debug: write_xyz(self.debugfile,ind[0],'Individual to fitness_switch') outs = switches.fitness_switch([self,ind]) self.output.write(outs[1]) invalid_ind[i]=outs[0] if invalid_ind[i].energy == float('inf'): poorlist.append(i) self.output.write('Removing infinite energy individual '+repr(ind.history_index)+'\n') elif invalid_ind[i].energy == float('nan'): poorlist.append(i) self.output.write('Removing nan energy individual '+repr(ind.history_index)+'\n') self.output.flush() if len(poorlist) != 0: poorlist.sort(reverse=True) for one in poorlist: del invalid_ind[one] if rank==0: pop.extend(invalid_ind) pop = self.generation_eval(pop) convergence = comm.bcast(self.convergence, root=0) if rank==0: end_signal = self.algorithm_stats(self.population) else: end_signal = None end_signal = comm.bcast(end_signal, root=0) return end_signal
def algorithm_parallel(self): """Subprogram for running parallel version of GA Requires MPI4PY""" global logger comm = MPI.COMM_WORLD rank = MPI.COMM_WORLD.Get_rank() if 'MA' in self.debug: debug = True else: debug = False if rank==0: self.algorithm_initialize() logger.info('Beginning main algorithm loop') #Begin main algorithm loop self.convergence = False convergence=False while not convergence: if rank==0: pop = self.population offspring = self.generation_set(pop) # Identify the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if ind.fitness==0] #Evaluate the individuals with invalid fitness self.output.write('\n--Evaluate Structures--\n') ntimes=int(math.ceil(float(len(invalid_ind))/float(comm.Get_size()))) nadd=int(ntimes*comm.Get_size()-len(invalid_ind)) maplist=[[] for n in range(ntimes)] strt=0 for i in range(len(maplist)): maplist[i]=[indi for indi in invalid_ind[strt:comm.Get_size()+strt]] # maplist[i]=[[self,indi] for indi in invalid_ind[strt:comm.Get_size()+strt]] strt+=comm.Get_size() for i in range(nadd): maplist[len(maplist)-1].append(None) else: ntimes=None ntimes = comm.bcast(ntimes,root=0) outs=[] for i in range(ntimes): if rank==0: one=maplist[i] else: one=None one = comm.scatter(one,root=0) logger.info('M:geometry scattering') out = switches.fitness_switch(self,one) logger.info('M:fitness evaluation done') out = comm.gather(out,root=0) logger.info('M:gethering done') if rank==0: outs.extend(out) if rank==0: for i in range(len(invalid_ind)): invalid_ind[i] = outs[i][0] for i in range(len(outs)): self.output.write(outs[i][1]) pop.extend(invalid_ind) pop = self.generation_eval(pop) self.write() convergence =comm.bcast(self.convergence, root=0) if rank==0: logger.info('Run algorithm stats, generation:{0}'.format(self.generation)) end_signal = self.algorithm_stats(self.population) else: end_signal = None end_signal = comm.bcast(end_signal, root=0) return end_signal
def algorithm_parallel1(self): """Subprogram for running parallel version of GA Requires MPI4PY""" global logger comm = MPI.COMM_WORLD rank = MPI.COMM_WORLD.Get_rank() if 'MA' in self.debug: debug = True else: debug = False if rank==0: self.algorithm_initialize() logger.info('Beginning main algorithm loop') #Begin main algorithm loop self.convergence = False convergence=False while not convergence: if rank==0: pop = self.population offspring = self.generation_set(pop) # Identify the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if ind.fitness==0] #Evaluate the individuals with invalid fitness self.output.write('\n--Evaluate Structures--\n') ntimes=int(math.ceil(float(len(invalid_ind))/float(comm.Get_size()))) nadd=int(ntimes*comm.Get_size()-len(invalid_ind)) maplist=[[] for n in range(ntimes)] strt=0 for i in range(len(maplist)): maplist[i]=[[self,indi] for indi in invalid_ind[strt:comm.Get_size()+strt]] strt+=comm.Get_size() for i in range(nadd): maplist[len(maplist)-1].append([None,None]) # for i in range(ntimes): # for j in range( else: ntimes=None # worker = MPI.COMM_SELF.Spawn(cmd, None, 5) # # n = array('i', [100]) # worker.Bcast([n,MPI.INT], root=MPI.ROOT) # # pi = array('d', [0.0]) # worker.Reduce(sendbuf=None, # recvbuf=[pi, MPI.DOUBLE], # op=MPI.SUM, root=MPI.ROOT) # pi = pi[0] # # worker.Disconnect() # ntimes = comm.bcast(ntimes,root=0) outs=[] for i in range(ntimes): if rank==0: one=maplist[i] else: one=None ind =comm.scatter(one,root=0) out = switches.fitness_switch(ind) outt = comm.gather(out,root=0) if rank==0: outs.extend(outt) if rank==0: for i in range(len(invalid_ind)): invalid_ind[i] = outs[i][0] for i in range(len(outs)): self.output.write(outs[i][1]) pop.extend(invalid_ind) pop = self.generation_eval(pop) self.write() convergence =comm.bcast(self.convergence, root=0) if rank==0: logger.info('Run algorithm stats') end_signal = self.algorithm_stats(self.population) else: end_signal = None end_signal = comm.bcast(end_signal, root=0) return end_signal
def algorithm_island(self): """Subprogram to run the GA in a Island Model Parallel Scheme""" global logger comm = MPI.COMM_WORLD rank = MPI.COMM_WORLD.Get_rank() if 'MA' in self.debug: debug = True else: debug = False if rank==0: #Initialize Random - Ensure each population has different random seed seeds=[] while len(seeds) < comm.Get_size(): a=random.randint(0,100) if a not in seeds: seeds.append(a) else: seeds=None self = comm.bcast(self,root=0) seed = comm.scatter(seeds,root=0) self.seed=seed random.seed(self.seed) self.algorithm_initialize() logger.info('Beginning main algorithm loop') logger.info('Random seed = {0}'.format(seed)) MIGEVENT=0 while True: pop = self.population #Migration if self.generation != 0: if float(self.generation)/float(self.migration_intervals)%1==0: orcs=comm.allgather(self.overrideconvergence) if True in orcs: break logger.info('Migrating structures') self.output.write('-----Migration in generation '+repr(self.generation)+'-----\n') nmig=int(self.nindiv*self.migration_percent) migrantsind=[] for i in range(nmig): migrantsind.append(pop[i].duplicate()) self.output.write('Migrating '+repr(len(migrantsind))+' individuals\n') migrantsind=[migrantsind] migrants = comm.gather(migrantsind,root=0) if rank==0: self.output.write('Master recieved '+repr(len(migrants))+' sets of migrants\n') MIGEVENT+=1 if MIGEVENT>len(migrants): MIGEVENT-=len(migrants) nmigrants=migrants[MIGEVENT:]+migrants[:MIGEVENT] else: nmigrants=None nmigrants = comm.scatter(nmigrants,root=0) for one in nmigrants[0]: pop.append(one) offspring = self.generation_set(pop) # Identify the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if ind.fitness==0] #Evaluate the individuals with invalid fitness self.output.write('\n--Evaluate Structures--\n') poorlist=[] logger.info('Evaluating fitness of structures') for i in range(len(invalid_ind)): ind = invalid_ind[i] outs = switches.fitness_switch([self,ind]) self.output.write(outs[1]) invalid_ind[i] = outs[0] pop.extend(invalid_ind) pop = self.generation_eval(pop) if self.convergence: self.overrideconvergence=True self.write() logger.info('Run algorithm stats') end_signal = self.algorithm_stats(self.population) return end_signal
def basin_hop_permute(indiv, Optimizer): """Move function to perform mini-basin hopping run to permute atoms Inputs: indiv = Individual class object to be altered Optimizer = Optimizer class object with needed parameters Outputs: indiv = Altered Individual class object *** needs work *** """ if 'MU' in Optimizer.debug: debug = True else: debug = False Optimizer.output.write('Performing Basin Hopping Mutation on Bulk for indiv '+repr(indiv.index)+'\n') #Save copy of starting positions startindiv=indiv[0].copy() startbulk=indiv.bulki indivmark=len(startindiv) alloysetting=Optimizer.alloy fingerprintsetting=Optimizer.fingerprinting if Optimizer.structure=='Defect': finddefectsetting=Optimizer.finddefects startindiv = indiv.duplicate() mutation_options = copy.deepcopy(Optimizer.mutation_options) #Get starting fitness fitmin=indiv.fitness if indiv.fitness==0: out=fitness_switch([Optimizer,indiv]) fitmin=out[0].fitness #Allow individual to be evaluated with its bulk setting Optimizer.alloy=True Optimizer.fingerprinting=False Optimizer.finddefects=False options = ['permutation'] totalsteps=Optimizer.bh_steps kt=Optimizer.bh_temp flag=False for step in range(totalsteps): prevind = indiv.duplicate() scheme = random.choice(options) indiv = eval(scheme+'(indiv, Optimizer)') out = fitness_switch([Optimizer,indiv]) fitnew=out[0].fitness if fitnew < fitmin: flag=True break else: accept=numpy.exp((fitmin - fitnew) / kt) > random.random() if not accept: indiv = prevind Optimizer.output.write('Evaluated '+repr(step)+' steps\n') if flag==False: Optimizer.output.write('Failed to find lower energy permuted structure\n') #indiv = startindiv else: Optimizer.output.write('Found lower energy permuted structure\n') Optimizer.alloy=alloysetting Optimizer.fingerprinting=fingerprintsetting if Optimizer.structure=='Defect': Optimizer.finddefects=finddefectsetting Optimizer.mutation_options = mutation_options muttype='BHP'+repr(step) if indiv.energy==0: indiv.history_index=indiv.history_index+'m'+muttype else: indiv.history_index=repr(indiv.index)+'m'+muttype return indiv
def quench(indiv, Optimizer): """Move function to perform a molecular dynamics NVT quenching of structure Inputs: indiv = Individual class object to be altered Optimizer = Optimizer class object with needed parameters Outputs: indiv = Altered Individual class object """ if 'MU' in Optimizer.debug: debug = True else: debug = False try: omin = copy.deepcopy(Optimizer.calc.parameters['minimize']) mincomd = omin + '\nunfix fix_nve\nfix fix_nvt all nvt temp ' + repr( Optimizer.quench_max_temp) + ' ' + repr( Optimizer.quench_min_temp) + ' ' + repr( Optimizer.quench_step_size) mincomd += '\nrun ' + repr( Optimizer.quench_n_steps_1 ) + '\nunfix fix_nvt\nfix fix_nve all nve\nminimize ' + omin mincomd += '\nunfix fix_nve\nfix fix_nvt all nvt temp ' + repr( Optimizer.quench_max_temp) + ' ' + repr( Optimizer.quench_min_temp) + ' ' + repr( Optimizer.quench_step_size) mincomd += '\nrun ' + repr( Optimizer.quench_n_steps_2 ) + '\nunfix fix_nvt\nfix fix_nve all nve\nminimize ' + omin except: omin = None pms = copy.deepcopy(Optimizer.calc.parameters) mincomd = '1.0e-8 1.0e-8 1000 100000\nunfix fix_nve\nfix fix_nvt all nvt temp ' + repr( Optimizer.quench_max_temp) + ' ' + repr( Optimizer.quench_min_temp) + ' ' + repr( Optimizer.quench_step_size) mincomd += '\nrun ' + repr( Optimizer.quench_n_steps_1 ) + '\nunfix fix_nvt\nfix fix_nve all nve\nminimize 1.0e-8 1.0e-8 1000 100000' mincomd += '\nunfix fix_nve\nfix fix_nvt all nvt temp ' + repr( Optimizer.quench_max_temp) + ' ' + repr( Optimizer.quench_min_temp) + ' ' + repr( Optimizer.quench_step_size) mincomd += '\nrun ' + repr( Optimizer.quench_n_steps_2 ) + '\nunfix fix_nvt\nfix fix_nve all nve\nminimize 1.0e-8 1.0e-8 1000 100000' Optimizer.calc.parameters['minimize'] = mincomd Optimizer.calc.parameters['thermosteps'] = Optimizer.lammps_thermo_steps outs = fitness_switch([Optimizer, indiv]) indiv = outs[0] Optimizer.output.write('Quench1 NVT Mutation performed on individual\n') Optimizer.output.write('Index = ' + repr(indiv.index) + '\n') Optimizer.output.write(outs[1]) Optimizer.output.write('New fitness : ' + repr(indiv.fitness) + '\n') muttype = 'Q' if omin == None: Optimizer.calc.parameters = pms else: Optimizer.calc.parameters['minimize'] = omin if indiv.energy == 0: indiv.history_index = indiv.history_index + 'm' + muttype else: indiv.history_index = repr(indiv.index) + 'm' + muttype return indiv