def prepare_ga(dbfile='godb.db', splits={(2,): 1}, N=20): blocks = [('Pd', 4), ('OH', 8)] # the building blocks volume = 50. * 4 # volume in angstrom^3 l = [list(Atoms(block).numbers)*count for block, count in blocks] stoichiometry = [item for sublist in l for item in sublist] atom_numbers = list(set(stoichiometry)) blmin = closest_distances_generator(atom_numbers=atom_numbers, ratio_of_covalent_radii=0.6) blmin[(1, 8)] = blmin[(8, 1)] = 2.0 cellbounds = CellBounds(bounds={'phi': [0.2 * 180., 0.8 * 180.], 'chi': [0.2 * 180., 0.8 * 180.], 'psi': [0.2 *180., 0.8 * 180.], 'a': [2, 8], 'b': [2, 8], 'c': [2, 8]}) # create the starting population sg = StartGenerator(blocks, blmin, volume, cellbounds=cellbounds, splits=splits) # create the database to store information in da = PrepareDB(db_file_name=dbfile, stoichiometry=stoichiometry) for i in range(N): a = sg.get_new_candidate() a.set_initial_magnetic_moments(magmoms=None) niggli_reduce(a) da.add_unrelaxed_candidate(a) return
blmin = closest_distances_generator(atom_numbers=atom_numbers, ratio_of_covalent_radii=1.3) cellbounds = CellBounds( bounds={ 'phi': [30, 150], 'chi': [30, 150], 'psi': [30, 150], 'a': [3, 50], 'b': [3, 50], 'c': [3, 50] }) sg = StartGenerator(blocks, blmin, volume, cellbounds=cellbounds, splits=splits) # Generate 2 candidates a1 = sg.get_new_candidate() a1.info['confid'] = 1 a2 = sg.get_new_candidate() a2.info['confid'] = 2 # Define and test genetic operators pairing = CutAndSplicePairing(blmin, p1=1., p2=0., minfrac=0.15, cellbounds=cellbounds,
def test_bulk_operators(): h2 = Atoms('H2', positions=[[0, 0, 0], [0, 0, 0.75]]) blocks = [('H', 4), ('H2O', 3), (h2, 2)] # the building blocks volume = 40. * sum([x[1] for x in blocks]) # cell volume in angstrom^3 splits = {(2,): 1, (1,): 1} # cell splitting scheme stoichiometry = [] for block, count in blocks: if type(block) == str: stoichiometry += list(Atoms(block).numbers) * count else: stoichiometry += list(block.numbers) * count atom_numbers = list(set(stoichiometry)) blmin = closest_distances_generator(atom_numbers=atom_numbers, ratio_of_covalent_radii=1.3) cellbounds = CellBounds(bounds={'phi': [30, 150], 'chi': [30, 150], 'psi': [30, 150], 'a': [3, 50], 'b': [3, 50], 'c': [3, 50]}) sg = StartGenerator(blocks, blmin, volume, cellbounds=cellbounds, splits=splits) # Generate 2 candidates a1 = sg.get_new_candidate() a1.info['confid'] = 1 a2 = sg.get_new_candidate() a2.info['confid'] = 2 # Define and test genetic operators pairing = CutAndSplicePairing(blmin, p1=1., p2=0., minfrac=0.15, cellbounds=cellbounds, use_tags=True) a3, desc = pairing.get_new_individual([a1, a2]) cell = a3.get_cell() assert cellbounds.is_within_bounds(cell) assert not atoms_too_close(a3, blmin, use_tags=True) n_top = len(a1) strainmut = StrainMutation(blmin, stddev=0.7, cellbounds=cellbounds, use_tags=True) softmut = SoftMutation(blmin, bounds=[2., 5.], used_modes_file=None, use_tags=True) rotmut = RotationalMutation(blmin, fraction=0.3, min_angle=0.5 * np.pi) rattlemut = RattleMutation(blmin, n_top, rattle_prop=0.3, rattle_strength=0.5, use_tags=True, test_dist_to_slab=False) rattlerotmut = RattleRotationalMutation(rattlemut, rotmut) permut = PermutationMutation(n_top, probability=0.33, test_dist_to_slab=False, use_tags=True, blmin=blmin) combmut = CombinationMutation(rattlemut, rotmut, verbose=True) mutations = [strainmut, softmut, rotmut, rattlemut, rattlerotmut, permut, combmut] for i, mut in enumerate(mutations): a = [a1, a2][i % 2] a3 = None while a3 is None: a3, desc = mut.get_new_individual([a]) cell = a3.get_cell() assert cellbounds.is_within_bounds(cell) assert np.all(a3.numbers == a.numbers) assert not atoms_too_close(a3, blmin, use_tags=True) modes_file = 'modes.txt' softmut_with = SoftMutation(blmin, bounds=[2., 5.], use_tags=True, used_modes_file=modes_file) no_muts = 3 for _ in range(no_muts): softmut_with.get_new_individual([a1]) softmut_with.read_used_modes(modes_file) assert len(list(softmut_with.used_modes.values())[0]) == no_muts os.remove(modes_file) comparator = OFPComparator(recalculate=True) gold = bulk('Au') * (2, 2, 2) assert comparator.looks_like(gold, gold) # This move should not exceed the default threshold gc = gold.copy() gc[0].x += .1 assert comparator.looks_like(gold, gc) # An additional step will exceed the threshold gc[0].x += .2 assert not comparator.looks_like(gold, gc)
def construct_init_parent(self, ads_cell, ads_pos): """ construct the initial set of parents """ self.ads_cell = ads_cell self.ads_pos = ads_pos Ads_vol = ads_cell[0] * ads_cell[1] * ads_cell[2] Ads_cell = [[ads_cell[0], 0, 0], [0, ads_cell[1], 0], [0, 0, ads_cell[2]]] if self.n_ads == 1: Atom_Num = self.Ads.get_atomic_numbers( ) # get atomic numbers of your adsorbate if self.n_ads == 2: TEMP_for_num = self.Ads[0] + self.Ads[1] Atom_Num = TEMP_for_num.get_atomic_numbers() #Atom_Num.append(self.Ads[1].get_atomic_numbers()) unique_atom_types = get_all_atom_types( self.FW, Atom_Num) # get atomic numbers of your system cd = closest_distances_generator( atom_numbers=unique_atom_types, ratio_of_covalent_radii=0.7 ) # Generate a dictionary of closest distances pop = self.pop_size if self.n_ads == 1: sg = StartGenerator( [(self.Ads, self.n_ads)], # Generator Parameters cd, Ads_vol, cell=Ads_cell) starting_population = [sg.get_new_candidate() for i in range(pop)] for i in range(pop): TEMPMOL = self.FW + starting_population[ i] # Add the adsorbates to the frame work self.Start_Set.append(TEMPMOL) num = len(self.Ads) if self.n_ads == 2: sg = StartGenerator([(self.Ads[0], 1), (self.Ads[1], 1)], cd, Ads_vol, cell=Ads_cell) starting_population = [sg.get_new_candidate() for i in range(pop)] for i in range(pop): TEMPMOL = self.FW + starting_population[i] self.Start_Set.append(TEMPMOL) num = len(self.Ads[0]) + len(self.Ads[1]) Cent_Pos = self.ads_pos #num = len(self.Ads)*self.n_ads Fin_atoms = np.linspace(0, num - 1, num) for i in range(pop): for j in Fin_atoms: Coord = self.Start_Set[i].get_positions()[-( int(j) + 1 )] + Cent_Pos # Move the corner of the adsorbate cell to p.o.i. self.Start_Set[i][-(int(j) + 1)].x = Coord[0] - Ads_cell[0][ 0] / 2 # Then you have to fudge the box so its centered self.Start_Set[i][-(int(j) + 1)].y = Coord[ 1] - Ads_cell[1][1] / 2 # around the p.o.i. self.Start_Set[i][-(int(j) + 1)].z = Coord[2] - Ads_cell[2][2] / 2 self.Start_Set[i].wrap()