Пример #1
0
def fitpred_new(pop, Optimizer):
    """Predator function to identify similar structures based on energy and replace one with new structure.
    """
    fitlist = [one.fitness for one in pop]
    nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin)
    STR = ''
    newpop = []
    if len(nfitlist) != len(fitlist):
        STR += 'Predator: Removed total of ' + repr(
            len(fitlist) - len(nfitlist)) + ' from population\n'
    otherlist = []
    for i in range(len(pop)):
        if i not in nindices:
            STR += 'Predator: Removed ' + repr(pop[i].history_index) + '\n'
            otherlist.append(pop[i])
        else:
            newpop.append(pop[i])
    while len(newpop) < Optimizer.nindiv:
        if Optimizer.structure == 'Defect' or Optimizer.structure == 'Cluster':
            ind = gen_pop_box(Optimizer.atomlist, Optimizer.size)
        elif Optimizer.structure == 'Crystal':
            outts = gen_pop_box(Optimizer.atomlist, Optimizer.size,
                                Optimizer.cell_shape_options)
            ind = outts[0]
        elif Optimizer.structure == 'Surface':
            mutopto = Optimizer.mutation_options
            Optimizer.mutation_options = ['Lattice_Alteration_rdrd']
            topind = random.choice(pop)[0].copy()
            ind, scheme = moves_switch(topind, Optimizer)
            Optimizer.mutation_options = mutopto
        individ = Individual(ind)
        #CHECK THIS LATER!! MAY NEED TO ADD MORE PROPERTIES!!
        individ.energy = 1000
        individ.fitness = 1000
        newpop.append(individ)
        STR += 'Predator: Adding mutated duplicates to new pop history=' + individ.history_index + '\n'
        nindices.append(individ.index)
    nindices.sort()
    if Optimizer.natural_selection_scheme == 'fussf':
        for ind in newpop:
            if ind.fingerprint == 0:
                ind.fingerprint = get_fingerprint(Optimizer, ind,
                                                  Optimizer.fpbin,
                                                  Optimizer.fpcutoff)
    if 'lambda,mu' in Optimizer.algorithm_type:
        try:
            mark = [
                index for index, n in enumerate(nindices)
                if n > Optimizer.nindiv - 1
            ][0]
        except:
            mark = Optimizer.nindiv
        Optimizer.mark = mark
        pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer)
        STR += str1
    else:
        pop = selection_switch(newpop, Optimizer.nindiv,
                               Optimizer.natural_selection_scheme, Optimizer)
    pop = get_best(pop, len(pop))
    return pop, STR
Пример #2
0
def fitpred_new(pop,Optimizer):
    """Predator function to identify similar structures based on energy and replace one with new structure.
    """
    fitlist = [one.fitness for one in pop]
    nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin)
    STR = ''
    newpop = []
    if len(nfitlist) != len(fitlist):
        STR+='Predator: Removed total of '+repr(len(fitlist)-len(nfitlist))+' from population\n'
    otherlist = []
    for i in range(len(pop)):
        if i not in nindices:
            STR+='Predator: Removed '+repr(pop[i].history_index)+'\n'
            otherlist.append(pop[i])
        else:
            newpop.append(pop[i])
    while len(newpop) < Optimizer.nindiv:
        if Optimizer.structure=='Defect' or Optimizer.structure=='Cluster':
            ind=gen_pop_box(Optimizer.atomlist,Optimizer.size)
        elif Optimizer.structure=='Crystal':
            outts=gen_pop_box(Optimizer.atomlist,Optimizer.size,Optimizer.cell_shape_options)
            ind=outts[0]
        elif Optimizer.structure=='Surface':
            mutopto=Optimizer.mutation_options
            Optimizer.mutation_options=['Lattice_Alteration_rdrd']
            topind=random.choice(pop)[0].copy()
            ind, scheme = moves_switch(topind,Optimizer)
            Optimizer.mutation_options=mutopto
        individ=Individual(ind)
        #CHECK THIS LATER!! MAY NEED TO ADD MORE PROPERTIES!!
        individ.energy=1000
        individ.fitness=1000
        newpop.append(individ)
        STR+='Predator: Adding mutated duplicates to new pop history='+individ.history_index+'\n'
        nindices.append(individ.index)
    nindices.sort()
    if Optimizer.natural_selection_scheme=='fussf':
        for ind in newpop:
            if ind.fingerprint == 0:
                ind.fingerprint = get_fingerprint(Optimizer,ind,Optimizer.fpbin,Optimizer.fpcutoff)
    if 'lambda,mu' in Optimizer.algorithm_type:
        try:
            mark = [ index for index,n in enumerate(nindices) if n > Optimizer.nindiv-1][0]
        except:
            mark = Optimizer.nindiv
        Optimizer.mark = mark
        pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer)
        STR+=str1
    else:
        pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer)
    pop = get_best(pop,len(pop))
    return pop, STR
Пример #3
0
def get_population(Optimizer):
    """
	Function to generate a population of structures.
	Inputs:
		Optimizer = structopt_stem Optimizer class object
	Outputs:
		pop = List of structopt_stem Individual class objects containing new structures.
	"""
    index1 = 0
    pop = []
    for i in range(Optimizer.nindiv):
        if Optimizer.structure == 'Defect':
            individ = get_defect_indiv(Optimizer)
        elif Optimizer.structure == 'Surface':
            individ = get_surface_indiv(Optimizer)
        elif Optimizer.structure == 'Crystal':
            individ = get_crystal_indiv(Optimizer)
        else:
            if 'sphere' in Optimizer.generate_flag:
                ind = gen_pop_sphere(Optimizer.atomlist,Optimizer.size)
            else:
                ind = gen_pop_box(Optimizer.atomlist,Optimizer.size)
            individ = Individual(ind)
        individ.index = index1
        if Optimizer.genealogy: 
            individ.history_index = repr(index1)
        Optimizer.output.write('Generated cluster individual with natoms = '+
            repr(individ[0].get_number_of_atoms())+'\n')
        pop.append(individ)
        index1=index1+1
    # Generate new atomlist concentrations based on cluster+box
    if Optimizer.structure == 'Defect':
        if Optimizer.alloy:
            concents=[]
            for ind in pop:
                cs=[]
                for sym,c,u,m in Optimizer.atomlist:
                    sylen=[atm for atm in ind[0] if atm.symbol==sym]
                    cs.append(len(sylen))
                concents.append(cs)
            natmlist=[0]*len(Optimizer.atomlist)
            for i in range(len(concents[0])):
                alls=[cs[i] for cs in concents]
                avgall=int(sum(alls)/len(alls))
                if avgall>=Optimizer.atomlist[i][1]:
                    natmlist[i]=(Optimizer.atomlist[i][0], avgall,
                        Optimizer.atomlist[i][2],Optimizer.atomlist[i][3])
                else:
                    natmlist[i]=(Optimizer.atomlist[i][0], Optimizer.atomlist[i][1],
                        Optimizer.atomlist[i][2],Optimizer.atomlist[i][3])
        else:
            natmlist=[0]*len(Optimizer.atomlist)
            for i in range(len(Optimizer.atomlist)):
                atms1=[inds for inds in pop[0][0] if inds.symbol==Optimizer.atomlist[i][0]]
                natmlist[i]=(Optimizer.atomlist[i][0], len(atms1),Optimizer.atomlist[i][2],
                    Optimizer.atomlist[i][3])
        Optimizer.atomlist=natmlist
        Optimizer.output.write('\n\nNew atomlist concentrations based on cluster+box = '+
            repr(Optimizer.atomlist)+'\n')
    return pop
Пример #4
0
def get_crystal_indiv(Optimizer):
    """
    Function to generate an structopt Individual class object containing a crystal structure.
    Inputs:
    	Optimizer = structopt Optimizer class
    Outputs:
    	individ = structopt Individual class object containing crystal structure data
    """
    if 'sphere' in Optimizer.generate_flag:
        outts = gen_pop_sphere(Optimizer.atomlist,Optimizer.size,Optimizer.cell_shape_options)
    else:
        outts = gen_pop_box(Optimizer.atomlist,Optimizer.size,Optimizer.cell_shape_options)
    ind = outts[0]
    Optimizer.output.write(outts[1])
    individ = Individual(ind)
    return individ
Пример #5
0
def get_crystal_indiv(Optimizer):
    """
    Function to generate an structopt Individual class object containing a crystal structure.
    Inputs:
    	Optimizer = structopt Optimizer class
    Outputs:
    	individ = structopt Individual class object containing crystal structure data
    """
    if 'sphere' in Optimizer.generate_flag:
        outts = gen_pop_sphere(Optimizer.atomlist, Optimizer.size,
                               Optimizer.cell_shape_options)
    else:
        outts = gen_pop_box(Optimizer.atomlist, Optimizer.size,
                            Optimizer.cell_shape_options)
    ind = outts[0]
    Optimizer.output.write(outts[1])
    individ = Individual(ind)
    return individ
Пример #6
0
def random_replacement(indiv, Optimizer):
    """Move function to replace selection of atoms with randomly generated group
    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
    if Optimizer.structure=='Defect':
        if Optimizer.isolate_mutation:
            atms,indb,vacant,swap,stro = find_defects(indiv[0],Optimizer.solidbulk,0)
        else:
            atms = indiv[0].copy()
    else:
        atms=indiv[0].copy()
    nat=len(atms)
    if nat != 0:
        #Select number of atoms to replace
        if nat<=1:
            natrep2=1
            natrep1=0
        elif nat<=5:
            natrep2=2
            natrep1=0
        else: 
            natrep1=random.randint(1,nat/2)
            while True:
                natrep2=random.randint(2,nat/2)
                if natrep2 != natrep1:
                    break
        natrep=abs(natrep2 - natrep1)
        #Select random position in cluster
        maxcell = numpy.maximum.reduce(atms.get_positions())
        mincell = numpy.minimum.reduce(atms.get_positions())
        pt=[random.uniform(mincell[0],maxcell[0]),random.uniform(mincell[1],maxcell[1]),random.uniform(mincell[2],maxcell[2])]
        #Get distance of atoms from random point
        atpt=Atom(position=pt)
        atms.append(atpt)
        dist=[]
        for i in range(len(atms)-1):
            dist.append(atms.get_distance(i,len(atms)-1))
        atms.pop()
        dlist=zip(dist,atms)
        dlist=sorted(dlist, key=lambda one: one[0], reverse=True)
        # Select atoms closest to random point
        atmsr=Atoms()
        indexlist=[]
        for i in range(natrep):
            atmsr.append(dlist[i][1])
            indexlist.append(dlist[i][1].index)
        natomlist=[0]*len(Optimizer.atomlist)
        for i in range(len(Optimizer.atomlist)):
            atms1=[inds for inds in atmsr if inds.symbol==Optimizer.atomlist[i][0]]
            natomlist[i]=(Optimizer.atomlist[i][0], len(atms1),Optimizer.atomlist[i][2],Optimizer.atomlist[i][3])
        nsize = max(numpy.maximum.reduce(atmsr.get_positions())-numpy.minimum.reduce(atmsr.get_positions()))
        repcenter = atmsr.get_center_of_mass()
        atmsn = gen_pop_box(natomlist,nsize)
        atmsn.translate(repcenter)
        #Update individual with new atom positions
        for i in range(len(indexlist)):
            index=indexlist[i]
            atms[index].position=atmsn[i].position
        if Optimizer.structure=='Defect':
            if Optimizer.isolate_mutation:
                atms.extend(indb)
        indiv[0]=atms.copy()
    else:
        natrep=0
        pt=0
    Optimizer.output.write('Random Group Replacement Mutation performed on individual\n')
    Optimizer.output.write('Index = '+repr(indiv.index)+'\n')
    Optimizer.output.write('Number of atoms replaced = '+repr(natrep)+'\n')
    Optimizer.output.write('Geometry point = '+repr(pt)+'\n')
    Optimizer.output.write(repr(indiv[0])+'\n')
    muttype='RGR'+repr(natrep)
    if indiv.energy==0:
        indiv.history_index=indiv.history_index+'m'+muttype
    else:
        indiv.history_index=repr(indiv.index)+'m'+muttype
    return indiv
Пример #7
0
def get_defect_indiv_random(Optimizer):
    """
    Function to generate a structopt Individual class structure with a defect structure.
    Inputs:
        Optimizer = structopt Optimizer class object
    Outputs:
        individ = structopt Individual class object containing defect structure data
    """
    #Initialize Bulk - Generate or load positions of bulk solid
    if not Optimizer.solidbulk:
        if 'Island_Method' not in Optimizer.algorithm_type:
            outfilename = os.path.join(
                os.path.join(os.getcwd(), Optimizer.filename), 'Bulkfile.xyz')
        else:
            from mpi4py import MPI
            rank = MPI.COMM_WORLD.Get_rank()
            outfilename = os.path.join(
                os.path.join(os.getcwd(),
                             Optimizer.filename + '-rank' + repr(rank)),
                'Bulkfile.xyz')
        if Optimizer.evalsolid:
            if Optimizer.parallel:
                from MAST.structopt_stem.tools.setup_calculator import setup_calculator
                Optimizer.calc = setup_calculator(Optimizer)
            bulk1, PureBulkEnpa, stro = gen_solid(Optimizer.solidfile,
                                                  Optimizer.solidcell,
                                                  outfilename, Optimizer.calc,
                                                  Optimizer.calc_method)
            Optimizer.output.write(stro)
        else:
            bulk1 = gen_solid(Optimizer.solidfile, Optimizer.solidcell,
                              outfilename)
            PureBulkEnpa = 0
        natomsbulk = len(bulk1)
        Optimizer.solidbulk = bulk1.copy()
        Optimizer.purebulkenpa = PureBulkEnpa
        Optimizer.natomsbulk = natomsbulk
    # Identify nearby atoms for region 2 inclusion
    bulk = Optimizer.solidbulk.copy()
    bulkcom = bulk.get_center_of_mass()
    bulk.translate(-bulkcom)
    if Optimizer.sf != 0:
        bulk.append(Atom(position=[0, 0, 0]))
        nbulk = Atoms(pbc=True, cell=bulk.get_cell())
        nr2 = Atoms(pbc=True, cell=bulk.get_cell())
        for i in range(len(bulk) - 1):
            dist = bulk.get_distance(-1, i)
            if dist <= Optimizer.sf:
                nr2.append(bulk[i])
            else:
                nbulk.append(bulk[i])
    else:
        nbulk = bulk.copy()
        nr2 = Atoms(pbc=True, cell=bulk.get_cell())
    #Update atom list with atoms in region 2
    natlist = []
    for sym, c, m, u in Optimizer.atomlist:
        atsym = [atm for atm in nr2 if atm.symbol == sym]
        natlist.append((sym, len(atsym), m, u))
    # Generate random individual and region 2
    if 'sphere' in Optimizer.generate_flag:
        ind = gen_pop_sphere(Optimizer.atomlist, Optimizer.size)
    elif 'dumbbell' in Optimizer.generate_flag:
        ind = Atoms(cell=[Optimizer.size for i in range(3)], pbc=True)
        for sym, c, m, u in Optimizer.atomlist:
            if c > 0:
                dums = generate_dumbbells(c,
                                          dumbbellsym=sym,
                                          nindiv=1,
                                          solid=Optimizer.solidbulk,
                                          size=Optimizer.size)[0]
                ind.extend(dums)
    else:
        ind = gen_pop_box(Optimizer.atomlist, Optimizer.size)
    nnr2 = gen_pop_sphere(natlist, Optimizer.sf * 2.0)
    nnr2.translate([-Optimizer.sf, -Optimizer.sf, -Optimizer.sf])
    nnr2.set_pbc(True)
    nnr2.set_cell(bulk.get_cell())
    # Initialize class individual with known values
    individ = Individual(ind)
    individ.purebulkenpa = Optimizer.purebulkenpa
    individ.natomsbulk = Optimizer.natomsbulk
    # Combine individual with R2
    icom = ind.get_center_of_mass()
    ind.translate(-icom)
    ind.extend(nnr2)
    ind.set_pbc(True)
    ind.set_cell(bulk.get_cell())
    # Recenter structure
    nbulk.translate(bulkcom)
    ind.translate(bulkcom)
    individ[0] = ind.copy()
    individ.bulki = nbulk.copy()
    individ.bulko = nbulk.copy()
    bulk = nbulk.copy()
    bul = bulk.copy()
    for atm in individ[0]:
        bul.append(atm)
    indices = []
    for sym, c, m, u in Optimizer.atomlist:
        if c < 0:
            if Optimizer.randvacst:
                alist = [one for one in bul if one.symbol == sym]
                count = abs(c)
                while count > 0:
                    indices.append(random.choice(alist).index)
                    count -= 1
            else:
                pos = individ[0][0:Optimizer.natoms].get_center_of_mass()
                count = abs(c)
                bul.append(Atom(position=pos))
                alist = [one for one in bul if one.symbol == sym]
                alistd = [(bul.get_distance(len(bul) - 1,
                                            one.index), one.index)
                          for one in alist]
                alistd.sort(reverse=True)
                bul.pop()
                while count > 0:
                    idx = alistd.pop()[1]
                    indices.append(idx)
                    count -= 1
    if len(indices) != 0:
        nbulklist = [
            at for at in bul
            if at.index not in indices and at.index < len(bulk)
        ]
        nalist = [
            at for at in bul
            if at.index not in indices and at.index >= len(bulk)
        ]
        bulkn = Atoms(cell=bulk.get_cell(), pbc=True)
        for atm in nbulklist:
            bulkn.append(atm)
        individ.bulki = bulkn.copy()
        individ.bulko = bulkn.copy()
        newind = Atoms()
        for atm in nalist:
            newind.append(atm)
        newind.set_cell(individ[0].get_cell())
        newind.set_pbc(True)
        individ[0] = newind
    return individ
Пример #8
0
def get_population(Optimizer):
    """
	Function to generate a population of structures.
	Inputs:
		Optimizer = structopt_stem Optimizer class object
	Outputs:
		pop = List of structopt_stem Individual class objects containing new structures.
	"""
    index1 = 0
    pop = []
    for i in range(Optimizer.nindiv):
        if Optimizer.structure == 'Defect':
            individ = get_defect_indiv(Optimizer)
        elif Optimizer.structure == 'Surface':
            individ = get_surface_indiv(Optimizer)
        elif Optimizer.structure == 'Crystal':
            individ = get_crystal_indiv(Optimizer)
        else:
            if 'sphere' in Optimizer.generate_flag:
                ind = gen_pop_sphere(Optimizer.atomlist, Optimizer.size)
            else:
                ind = gen_pop_box(Optimizer.atomlist, Optimizer.size)
            individ = Individual(ind)
        individ.index = index1
        if Optimizer.genealogy:
            individ.history_index = repr(index1)
        Optimizer.output.write('Generated cluster individual with natoms = ' +
                               repr(individ[0].get_number_of_atoms()) + '\n')
        pop.append(individ)
        index1 = index1 + 1
    # Generate new atomlist concentrations based on cluster+box
    if Optimizer.structure == 'Defect':
        if Optimizer.alloy:
            concents = []
            for ind in pop:
                cs = []
                for sym, c, u, m in Optimizer.atomlist:
                    sylen = [atm for atm in ind[0] if atm.symbol == sym]
                    cs.append(len(sylen))
                concents.append(cs)
            natmlist = [0] * len(Optimizer.atomlist)
            for i in range(len(concents[0])):
                alls = [cs[i] for cs in concents]
                avgall = int(sum(alls) / len(alls))
                if avgall >= Optimizer.atomlist[i][1]:
                    natmlist[i] = (Optimizer.atomlist[i][0], avgall,
                                   Optimizer.atomlist[i][2],
                                   Optimizer.atomlist[i][3])
                else:
                    natmlist[i] = (Optimizer.atomlist[i][0],
                                   Optimizer.atomlist[i][1],
                                   Optimizer.atomlist[i][2],
                                   Optimizer.atomlist[i][3])
        else:
            natmlist = [0] * len(Optimizer.atomlist)
            for i in range(len(Optimizer.atomlist)):
                atms1 = [
                    inds for inds in pop[0][0]
                    if inds.symbol == Optimizer.atomlist[i][0]
                ]
                natmlist[i] = (Optimizer.atomlist[i][0], len(atms1),
                               Optimizer.atomlist[i][2],
                               Optimizer.atomlist[i][3])
        Optimizer.atomlist = natmlist
        Optimizer.output.write(
            '\n\nNew atomlist concentrations based on cluster+box = ' +
            repr(Optimizer.atomlist) + '\n')
    return pop
Пример #9
0
def get_defect_indiv_random(Optimizer):
    """
    Function to generate a structopt Individual class structure with a defect structure.
    Inputs:
        Optimizer = structopt Optimizer class object
    Outputs:
        individ = structopt Individual class object containing defect structure data
    """
    #Initialize Bulk - Generate or load positions of bulk solid
    if not Optimizer.solidbulk:
        if 'Island_Method' not in Optimizer.algorithm_type:
            outfilename = os.path.join(os.path.join(os.getcwd(),Optimizer.filename),'Bulkfile.xyz')
        else:
            from mpi4py import MPI
            rank = MPI.COMM_WORLD.Get_rank()
            outfilename = os.path.join(os.path.join(os.getcwd(),Optimizer.filename+'-rank'+repr(rank)),'Bulkfile.xyz')
        if Optimizer.evalsolid:
            if Optimizer.parallel:
                from MAST.structopt_stem.tools.setup_calculator import setup_calculator
                Optimizer.calc = setup_calculator(Optimizer)
            bulk1, PureBulkEnpa, stro = gen_solid(Optimizer.solidfile,
                Optimizer.solidcell,outfilename,Optimizer.calc,Optimizer.calc_method)
            Optimizer.output.write(stro)
        else:
            bulk1 = gen_solid(Optimizer.solidfile,Optimizer.solidcell,outfilename)
            PureBulkEnpa = 0
        natomsbulk = len(bulk1)
        Optimizer.solidbulk = bulk1.copy()
        Optimizer.purebulkenpa = PureBulkEnpa
        Optimizer.natomsbulk = natomsbulk
    # Identify nearby atoms for region 2 inclusion
    bulk = Optimizer.solidbulk.copy()
    bulkcom = bulk.get_center_of_mass()
    bulk.translate(-bulkcom)
    if Optimizer.sf != 0:
        bulk.append(Atom(position=[0,0,0]))
        nbulk = Atoms(pbc=True, cell=bulk.get_cell())
        nr2 = Atoms(pbc=True, cell=bulk.get_cell())
        for i in range(len(bulk)-1):
            dist = bulk.get_distance(-1,i)
            if dist <= Optimizer.sf:
                nr2.append(bulk[i])
            else:
                nbulk.append(bulk[i])
    else:
        nbulk = bulk.copy()
        nr2 = Atoms(pbc=True, cell=bulk.get_cell())
    #Update atom list with atoms in region 2
    natlist = []
    for sym,c,m,u in Optimizer.atomlist:
        atsym = [atm for atm in nr2 if atm.symbol==sym]
        natlist.append((sym,len(atsym),m,u))
    # Generate random individual and region 2
    if 'sphere' in Optimizer.generate_flag:
        ind = gen_pop_sphere(Optimizer.atomlist,Optimizer.size)
    elif 'dumbbell' in Optimizer.generate_flag:
        ind = Atoms(cell=[Optimizer.size for i in range(3)], pbc=True)
        for sym,c,m,u in Optimizer.atomlist:
            if c > 0:
                dums = generate_dumbbells(c, dumbbellsym=sym, nindiv=1, solid = Optimizer.solidbulk, size=Optimizer.size)[0]
                ind.extend(dums)
    else:
        ind = gen_pop_box(Optimizer.atomlist,Optimizer.size)
    nnr2 = gen_pop_sphere(natlist, Optimizer.sf*2.0)
    nnr2.translate([-Optimizer.sf,-Optimizer.sf,-Optimizer.sf])
    nnr2.set_pbc(True)
    nnr2.set_cell(bulk.get_cell())
    # Initialize class individual with known values
    individ = Individual(ind)
    individ.purebulkenpa = Optimizer.purebulkenpa
    individ.natomsbulk = Optimizer.natomsbulk
    # Combine individual with R2
    icom = ind.get_center_of_mass()
    ind.translate(-icom)
    ind.extend(nnr2)
    ind.set_pbc(True)
    ind.set_cell(bulk.get_cell())
    # Recenter structure
    nbulk.translate(bulkcom)
    ind.translate(bulkcom)
    individ[0] = ind.copy()
    individ.bulki = nbulk.copy()
    individ.bulko = nbulk.copy()
    bulk = nbulk.copy()
    bul = bulk.copy()
    for atm in individ[0]:
        bul.append(atm)
    indices = []
    for sym,c,m,u in Optimizer.atomlist:
        if c < 0:
            if Optimizer.randvacst:
                alist = [one for one in bul if one.symbol==sym]
                count = abs(c)
                while count > 0:
                    indices.append(random.choice(alist).index)
                    count -= 1
            else:
                pos = individ[0][0:Optimizer.natoms].get_center_of_mass()
                count = abs(c)
                bul.append(Atom(position=pos))
                alist = [one for one in bul if one.symbol==sym]
                alistd = [(bul.get_distance(len(bul)-1,one.index),one.index)
                			for one in alist]
                alistd.sort(reverse=True)
                bul.pop()
                while count > 0:
                    idx = alistd.pop()[1]
                    indices.append(idx)
                    count-=1
    if len(indices) !=0:
        nbulklist = [at for at in bul if at.index not in indices and at.index<len(bulk)]
        nalist = [at for at in bul if at.index not in indices and at.index>=len(bulk)]
        bulkn = Atoms(cell=bulk.get_cell(),pbc=True)
        for atm in nbulklist:
            bulkn.append(atm)
        individ.bulki = bulkn.copy()
        individ.bulko = bulkn.copy()
        newind = Atoms()
        for atm in nalist:
            newind.append(atm)
        newind.set_cell(individ[0].get_cell())
        newind.set_pbc(True)									
        individ[0] = newind
    return individ