예제 #1
0
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
예제 #2
0
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)
예제 #4
0
    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()