[ase-users] Particle_mutations in GA

Alexander Romanov alphard.rm at gmail.com
Thu Mar 2 10:51:35 CET 2017


Hi,
We met a strange problem with RandomMutation operator in Genetic Algorithm.
Information about unit cell
is periodically missed. Length of our cell is 36 angstroms but we find 1
angstrom per
dimension in some cases

#-------------------------------------------------------------------------------------------------------
from ase.ga.data import PrepareDB
from ase.ga.startgenerator import StartGenerator
from ase.ga.utilities import closest_distances_generator
from ase.ga.utilities import get_all_atom_types
import numpy as np
from ase import Atoms
from ase.visualize import view
from ase.constraints import FixAtoms

for x in range(13, 12, -1):
    for y in range(1, 2, 1):
        db_file = 'Cu%d_gadb_v%d.db' % (x,y,)

        L = 36.0

        cluster = Atoms('Cu',
                        cell=(L, L, L),
                        pbc=(0., 0., 0.))
        cluster.center()
        for a in cluster:
        a.x=17.25
        a.y=17.25
        a.z=17.25
        #constraint = FixAtoms(mask=[a.symbol == 'Cu' for a in cluster])
        #cluster.set_constraint(constraint)


        # define the volume in which cluster is optimized
        # the volume is defined by a corner position (p0)
        # and three spanning vectors (v1, v2, v3)
        pos = (0.0, 0.0, 0.0)
        b = 20.0
        cell = np.array([(b, 0, 0), (0, b, 0), (0, 0, b)])
        p0 = np.array([10., 10., 10.])
        v1 = cell[0, :]
        v2 = cell[1, :]
        v3 = cell[2, :]


        # Define the composition of the atoms to optimize
        atom_numbers =  (x-1)* [29]


        # define the closest distance two atoms of a given species can be
to each other
        unique_atom_types = get_all_atom_types(cluster, atom_numbers)
        cd = closest_distances_generator(atom_numbers=unique_atom_types,
                                         ratio_of_covalent_radii=0.7)

        # create the starting population
        sg = StartGenerator(slab=cluster,
                            atom_numbers=atom_numbers,
                            closest_allowed_distances=cd,
                            box_to_place_in=[p0, [v1, v2, v3]])

        # generate the starting population
        population_size = 20
        starting_population = [sg.get_new_candidate() for i in
range(population_size)]

        # from ase.visualize import view   # uncomment these lines
        # view(starting_population)        # to see the starting population

        # create the database to store information in
        d = PrepareDB(db_file_name=db_file,
                      simulation_cell=cluster,
                      stoichiometry=atom_numbers)

        for a in starting_population:
            d.add_unrelaxed_candidate(a)

#-------------------------------------------------------------------------------------------------------
from __future__ import print_function
from random import random
from ase.io import write
from ase.optimize import BFGS
from ase.calculators.emt import EMT
from ase.io import read

from ase.ga.data import DataConnection
from ase.ga.population import Population
from ase.ga.standard_comparators import InteratomicDistanceComparator
from ase.ga.cutandsplicepairing import CutAndSplicePairing
from ase.ga.utilities import closest_distances_generator
from ase.ga.utilities import get_all_atom_types
from ase.ga.offspring_creator import OperationSelector
from ase.ga.standardmutations import MirrorMutation
from ase.ga.standardmutations import RattleMutation
from ase.ga.standardmutations import PermutationMutation
from ase.ga.particle_mutations import RandomMutation

# Change the following three parameters to suit your needs
population_size = 20
mutation_probability = 0.3
n_to_test = 200

for x in range(13, 12, -1):
    for y in range(1, 2, 1):
        # Initialize the different components of the GA
        da = DataConnection('Cu%d_gadb_v%d.db' % (x,y,))
        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,
                                            ratio_of_covalent_radii=0.7)

        comp = InteratomicDistanceComparator(n_top=n_to_optimize,
                                             pair_cor_cum_diff=0.015,
                                             pair_cor_max=0.7,
                                             dE=0.02,
                                             mic=False)

        pairing = CutAndSplicePairing(slab, n_to_optimize, blmin)
        mutations = OperationSelector([1., 1., 1.],
                                      [MirrorMutation(blmin, n_to_optimize),
                                       RattleMutation(blmin, n_to_optimize),
                                       RandomMutation(length=2.,
num_muts=4)])

        # Relax all unrelaxed structures (e.g. the starting population)
        while da.get_number_of_unrelaxed_candidates() > 0:
            a = da.get_an_unrelaxed_candidate()
            a.set_calculator(EMT())
            print('Relaxing starting candidate {0}'.format(a.info
['confid']))
            dyn = BFGS(a, trajectory=None, logfile=None)
            dyn.run(fmax=0.05, steps=100)
            a.info['key_value_pairs']['raw_score'] =
-a.get_potential_energy()
            da.add_relaxed_step(a)

        # create the population
        population = Population(data_connection=da,
                                population_size=population_size,
                                comparator=comp)

        # test n_to_test new candidates
        for i in range(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])
            if a3 is None:
                continue
            da.add_unrelaxed_candidate(a3, description=desc)

            # Check if we want to do a mutation
            if random() < mutation_probability:
                confid = a3.info.get('confid')
                a3_mut, desc = mutations.get_new_individual([a3])
                if a3_mut is not None:
                    a3_mut.info['confid'] = confid
                    da.add_unrelaxed_step(a3_mut, desc)
                    a3 = a3_mut

            # Relax the new candidate
            a3.set_calculator(EMT())
            dyn = BFGS(a3, trajectory=None, logfile=None)
            dyn.run(fmax=0.05, steps=100)
            a3.info['key_value_pairs']['raw_score'] =
-a3.get_potential_energy()
            da.add_relaxed_step(a3)
            population.update()

        write('all_candidates_Cu%d_v%d.traj' % (x,y,),
da.get_all_relaxed_candidates() )
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listserv.fysik.dtu.dk/pipermail/ase-users/attachments/20170302/d029f5e4/attachment-0001.html>


More information about the ase-users mailing list