Ejemplo n.º 1
0
    def ga_init(self, ddiff, dmax, dE):
        self.ddiff = ddiff
        self.dmax = dmax
        self.dE = dE

        da = DataConnection(self.db_name)
        atom_numbers_to_optimize = da.get_atom_numbers_to_optimize(
        )  # adsorbate atom numbers to optimize
        n_to_optimize = len(
            atom_numbers_to_optimize)  # number of atoms to optimize
        slab = da.get_slab()
        all_atom_types = get_all_atom_types(slab, atom_numbers_to_optimize)
        blmin = closest_distances_generator(
            all_atom_types,
            ratio_of_covalent_radii=.7)  # closest distance atoms can be

        comp = InteratomicDistanceComparator(
            n_top=None,
            pair_cor_cum_diff=self.ddiff,
            pair_cor_max=dmax,
            dE=dE,
            mic=True)  # comparator to determine if parents should make childer

        pairing = CutAndSplicePairing(
            blmin, None, use_tags=True, p1=.2
        )  # how children are generated (make sure your adsorbates are uniquely tagged)

        population = Population(data_connection=da,
                                population_size=self.pop,
                                comparator=comp)

        for i in range(self.n_to_test):
            print('Now starting configuration number {0}'.format(i))
            a1, a2 = population.get_two_candidates()

            a3, desc = pairing.get_new_individual([a1, a2])
            #print(a3.info)
            #view(a3)
            if a3 is None:
                continue
            da.add_unrelaxed_candidate(a3, description=desc)
Ejemplo n.º 2
0
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.],
Ejemplo n.º 3
0
def run_ga(n_to_test, kptdensity=3.5):
    population_size = 20
    da = DataConnection('godb.db')
    atom_numbers_to_optimize = da.get_atom_numbers_to_optimize()
    n_to_optimize = len(atom_numbers_to_optimize)
    slab = da.get_slab()
    all_atom_types = get_all_atom_types(slab, atom_numbers_to_optimize)
    blmin = closest_distances_generator(all_atom_types, 0.05)  # 0.5

    # defining genetic operators:
    mutation_probability = 0.75
    pairing = CutAndSplicePairing(blmin,
                                  p1=1.,
                                  p2=0.,
                                  minfrac=0.15,
                                  use_tags=False)
    cellbounds = CellBounds(
        bounds={
            'phi': [0.2 * 180., 0.8 * 180.],
            'chi': [0.2 * 180., 0.8 * 180.],
            'psi': [0.2 * 180., 0.8 * 180.]
        })
    strainmut = StrainMutation(blmin,
                               stddev=0.7,
                               cellbounds=cellbounds,
                               use_tags=False)
    blmin_soft = closest_distances_generator(all_atom_types, 0.1)
    softmut = SoftMutation(blmin_soft, bounds=[2., 5.], use_tags=False)
    rattlemut = RattleMutation(blmin,
                               n_to_optimize,
                               rattle_prop=0.8,
                               rattle_strength=2.5,
                               use_tags=False)
    mutations = OperationSelector([4., 4., 2], [softmut, strainmut, rattlemut])

    if True:
        # recalculate raw scores
        structures = da.get_all_relaxed_candidates()
        for atoms in structures:
            atoms = singlepoint(atoms, kptdensity=kptdensity)
            da.c.delete([atoms.info['relax_id']])
            if 'data' not in atoms.info:
                atoms.info['data'] = {}
            da.add_relaxed_step(atoms)
        print('Finished recalculating raw scores')

    # relaxing the initial candidates:
    while da.get_number_of_unrelaxed_candidates() > 0:
        a = da.get_an_unrelaxed_candidate()
        a.wrap()
        a = relax_one(a, kptdensity=kptdensity)
        da.add_relaxed_step(a)

    # create the population
    population = Population(data_connection=da,
                            population_size=population_size,
                            comparator=comparator,
                            logfile='log.txt')

    current_pop = population.get_current_population()
    strainmut.update_scaling_volume(current_pop, w_adapt=0.5, n_adapt=4)
    pairing.update_scaling_volume(current_pop, w_adapt=0.5, n_adapt=4)

    # Test n_to_test new candidates
    ga_raw_scores = []
    step = 0
    for step in range(n_to_test):
        print('Starting configuration number %d' % step, flush=True)

        clock = time()
        a3 = None
        r = random()
        if r > mutation_probability:
            while a3 is None:
                a1, a2 = population.get_two_candidates()
                a3, desc = pairing.get_new_individual([a1, a2])
        else:
            while a3 is None:
                a1 = population.get_one_candidate()
                a3, desc = mutations.get_new_individual([a1])

        dt = time() - clock
        op = 'pairing' if r > mutation_probability else 'mutating'
        print('Time for %s candidate(s): %.3f' % (op, dt), flush=True)

        a3.wrap()
        da.add_unrelaxed_candidate(a3, description=desc)

        a3 = relax_one(a3, kptdensity=kptdensity)
        da.add_relaxed_step(a3)

        # Various updates:
        population.update()
        current_pop = population.get_current_population()

        if step % 10 == 0:
            strainmut.update_scaling_volume(current_pop,
                                            w_adapt=0.5,
                                            n_adapt=4)
            pairing.update_scaling_volume(current_pop, w_adapt=0.5, n_adapt=4)
            write('current_population.traj', current_pop)

        # Print out information for easy analysis/plotting afterwards:
        if r > mutation_probability:
            print('Step %d %s %.3f %.3f %.3f' % (step, desc,\
                   get_raw_score(a1), get_raw_score(a2), get_raw_score(a3)))
        else:
            print('Step %d %s %.3f %.3f' % (step, desc,\
                   get_raw_score(a1), get_raw_score(a3)))

        print('Step %d highest raw score in pop: %.3f' % \
              (step, get_raw_score(current_pop[0])))
        ga_raw_scores.append(get_raw_score(a3))
        print('Step %d highest raw score generated by GA: %.3f' % \
              (step, max(ga_raw_scores)))

    emin = population.pop[0].get_potential_energy()
    print('GA finished after step %d' % step)
    print('Lowest energy = %8.3f eV' % emin, flush=True)
    write('all_candidates.traj', da.get_all_relaxed_candidates())
    write('current_population.traj', population.get_current_population())
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
cellbounds = CellBounds(
    bounds={
        'phi': [20, 160],
        'chi': [20, 160],
        'psi': [20, 160],
        'a': [2, 60],
        'b': [2, 60],
        'c': [2, 60]
    })

# Define a pairing operator with 100% (0%) chance that the first
# (second) parent will be randomly translated, and with each parent
# contributing to at least 15% of the child's scaled coordinates
pairing = CutAndSplicePairing(blmin,
                              p1=1.,
                              p2=0.,
                              minfrac=0.15,
                              cellbounds=cellbounds,
                              use_tags=False)

# Define a strain mutation with a typical standard deviation of 0.7
# for the strain matrix elements (drawn from a normal distribution)
strainmut = StrainMutation(blmin,
                           stddev=0.7,
                           cellbounds=cellbounds,
                           use_tags=False)

# Define a soft mutation; we need to provide a dictionary with
# (typically rather short) minimal interatomic distances which
# is used to determine when to stop displacing the atoms along
# the chosen mode. The minimal and maximal single-atom displacement
# distances (in Angstrom) for a valid mutation are provided via