Exemplo n.º 1
0
def constrain_positions(indiv, bulk, sf):
    STR=''
    ts = indiv.copy()
    indc,indb,vacant,swap,stro = find_defects(ts,bulk,0)
    sbulk = bulk.copy()
    bcom = sbulk.get_center_of_mass()
    #totalsol.translate(-bulkcom)
    #indc.translate(-bulkcom)
    #totalsol.append(Atom(position=[0,0,0]))
    #             for one in indc:
    #                 index = [atm.index for atm in totalsol if atm.position[0]==one.position[0] and atm.position[1]==one.position[1] and atm.position[2]==one.position[2]][0]
    #                 if totalsol.get_distance(-1,index) > Optimizer.sf:
    #                     r = random.random()
    #                     totalsol.set_distance(-1,index,Optimizer.sf*r,fix=0)
    #             totalsol.pop()
    #             totalsol.translate(bulkcom)
    com = indc.get_center_of_mass()
    dist = (sum((bcom[i] - com[i])**2 for i in range(3)))**0.5
    if dist > sf:
        STR+='Shifting structure to within region\n'
        r = random.random()*sf
        comv = numpy.linalg.norm(com)
        ncom = [one*r/comv for one in com]
        trans = [ncom[i]-com[i] for i in range(3)]
        indices = []
        for one in indc:
            id = [atm.index for atm in totalsol if atm.position[0]==one.position[0] and atm.position[1]==one.position[1] and atm.position[2]==one.position[2]][0]
            ts[id].position += trans
    return ts, STR
Exemplo n.º 2
0
def lattice_alteration_crystal(indiv, Optimizer):
    """Move function to perform Lattice Alteration of atoms in size crystal
    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
    cell_max = numpy.maximum.reduce(indiv[0].get_cell())
    cell_min = numpy.minimum.reduce(indiv[0].get_cell())
    if Optimizer.structure == 'Defect':
        if Optimizer.isolate_mutation:
            indc, indb, vacant, swap, stro = find_defects(
                indiv[0], Optimizer.solidbulk, 0)
            positions = indc.get_positions()
        else:
            positions = indiv[0].get_positions()
    else:
        positions = indiv[0].get_positions()
    if len(positions) != 0:
        try:
            natomsmove = random.randint(1, len(positions) / 5)
        except ValueError:
            natomsmove = 1
        ratmlocnew = [0] * natomsmove
        for i in range(natomsmove):
            ratmloc = random.randint(0, len(positions) - 1)
            ratmlocnew[i] = (random.uniform(cell_min[0], cell_max[0]),
                             random.uniform(cell_min[1], cell_max[1]),
                             random.uniform(cell_min[2], cell_max[2]))
            positions[ratmloc] = ratmlocnew[i]
        if Optimizer.structure == 'Defect':
            if Optimizer.isolate_mutation:
                indc.set_positions(positions)
                indiv[0] = indc.copy()
                indiv[0].extend(indb)
            else:
                indiv[0].set_positions(positions)
        else:
            indiv[0].set_positions(positions)
    else:
        natomsmove = 0
        ratmlocnew = 0
    Optimizer.output.write(
        'Lattice Alteration Mutation performed on individual\n')
    Optimizer.output.write('Index = ' + repr(indiv.index) + '\n')
    Optimizer.output.write('Number of atoms moved = ' + repr(natomsmove) +
                           '\n')
    Optimizer.output.write(repr(ratmlocnew) + '\n')
    Optimizer.output.write(repr(indiv[0]) + '\n')
    muttype = 'LAC' + repr(natomsmove)
    if indiv.energy == 0:
        indiv.history_index = indiv.history_index + 'm' + muttype
    else:
        indiv.history_index = repr(indiv.index) + 'm' + muttype
    return indiv
Exemplo n.º 3
0
def constrain_positions(indiv, bulk, sf):
    STR = ''
    ts = indiv.copy()
    indc, indb, vacant, swap, stro = find_defects(ts, bulk, 0)
    sbulk = bulk.copy()
    bcom = sbulk.get_center_of_mass()
    #totalsol.translate(-bulkcom)
    #indc.translate(-bulkcom)
    #totalsol.append(Atom(position=[0,0,0]))
    #             for one in indc:
    #                 index = [atm.index for atm in totalsol if atm.position[0]==one.position[0] and atm.position[1]==one.position[1] and atm.position[2]==one.position[2]][0]
    #                 if totalsol.get_distance(-1,index) > Optimizer.sf:
    #                     r = random.random()
    #                     totalsol.set_distance(-1,index,Optimizer.sf*r,fix=0)
    #             totalsol.pop()
    #             totalsol.translate(bulkcom)
    com = indc.get_center_of_mass()
    dist = (sum((bcom[i] - com[i])**2 for i in range(3)))**0.5
    if dist > sf:
        STR += 'Shifting structure to within region\n'
        r = random.random() * sf
        comv = numpy.linalg.norm(com)
        ncom = [one * r / comv for one in com]
        trans = [ncom[i] - com[i] for i in range(3)]
        indices = []
        for one in indc:
            id = [
                atm.index for atm in totalsol
                if atm.position[0] == one.position[0] and atm.position[1] ==
                one.position[1] and atm.position[2] == one.position[2]
            ][0]
            ts[id].position += trans
    return ts, STR
Exemplo n.º 4
0
def lattice_alteration_crystal(indiv, Optimizer):
    """Move function to perform Lattice Alteration of atoms in size crystal
    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
    cell_max = numpy.maximum.reduce(indiv[0].get_cell())
    cell_min = numpy.minimum.reduce(indiv[0].get_cell())
    if Optimizer.structure == "Defect":
        if Optimizer.isolate_mutation:
            indc, indb, vacant, swap, stro = find_defects(indiv[0], Optimizer.solidbulk, 0)
            positions = indc.get_positions()
        else:
            positions = indiv[0].get_positions()
    else:
        positions = indiv[0].get_positions()
    if len(positions) != 0:
        try:
            natomsmove = random.randint(1, len(positions) / 5)
        except ValueError:
            natomsmove = 1
        ratmlocnew = [0] * natomsmove
        for i in range(natomsmove):
            ratmloc = random.randint(0, len(positions) - 1)
            ratmlocnew[i] = (
                random.uniform(cell_min[0], cell_max[0]),
                random.uniform(cell_min[1], cell_max[1]),
                random.uniform(cell_min[2], cell_max[2]),
            )
            positions[ratmloc] = ratmlocnew[i]
        if Optimizer.structure == "Defect":
            if Optimizer.isolate_mutation:
                indc.set_positions(positions)
                indiv[0] = indc.copy()
                indiv[0].extend(indb)
            else:
                indiv[0].set_positions(positions)
        else:
            indiv[0].set_positions(positions)
    else:
        natomsmove = 0
        ratmlocnew = 0
    Optimizer.output.write("Lattice Alteration Mutation performed on individual\n")
    Optimizer.output.write("Index = " + repr(indiv.index) + "\n")
    Optimizer.output.write("Number of atoms moved = " + repr(natomsmove) + "\n")
    Optimizer.output.write(repr(ratmlocnew) + "\n")
    Optimizer.output.write(repr(indiv[0]) + "\n")
    muttype = "LAC" + repr(natomsmove)
    if indiv.energy == 0:
        indiv.history_index = indiv.history_index + "m" + muttype
    else:
        indiv.history_index = repr(indiv.index) + "m" + muttype
    return indiv
Exemplo n.º 5
0
def lattice_alteration_rdrd(indiv, Optimizer):
    """Move function to move random atoms in random direction for random distance
    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
    d_max=numpy.minimum.reduce(numpy.maximum.reduce(indiv[0].get_positions())-numpy.minimum.reduce(indiv[0].get_positions()))
    if Optimizer.structure=='Defect':
        if Optimizer.isolate_mutation:
            indc,indb,vacant,swap,stro = find_defects(indiv[0],Optimizer.solidbulk,0)
            positions=indc.get_positions()
        else:
            positions = indiv[0].get_positions()
    else:
        positions=indiv[0].get_positions()
    if len(positions) != 0:
        try:
          #  natomsmove=random.randint(1,len(positions)/5)
            natomsmove=random.randint(1,len(positions)/50)
        except ValueError:
            natomsmove=1
        r=random.uniform(0.3,d_max)
        theta=math.radians(random.uniform(0,360))
        phi=math.radians(random.uniform(0,180))
        direction=[r*math.sin(theta)*math.cos(phi),r*math.sin(theta)*math.sin(phi),r*math.cos(theta)]
        ratmlocnew=[0]*natomsmove
        for i in range(natomsmove):
            ratmloc=random.randint(0,len(positions)-1)
            ratmlocnew[i]=(direction[0]+positions[ratmloc][0],direction[1]+positions[ratmloc][1],direction[2]+positions[ratmloc][2])
            positions[ratmloc]=ratmlocnew[i]
        if Optimizer.structure=='Defect':
            if Optimizer.isolate_mutation:
                indc.set_positions(positions)
                indiv[0]=indc.copy()
                indiv[0].extend(indb)
            else:
                indiv[0].set_positions(positions)
        else:
            indiv[0].set_positions(positions)
    else:
        natomsmove=0
        ratmlocnew=0
    Optimizer.output.write('Lattice Alteration Mutation performed on individual\n')
    Optimizer.output.write('Index = '+repr(indiv.index)+'\n')
    Optimizer.output.write('Number of atoms moved = '+repr(natomsmove)+'\n')
    Optimizer.output.write(repr(ratmlocnew)+'\n')
    #Optimizer.output.write(repr(indiv[0])+'\n')
    muttype='LARD'+repr(natomsmove)	
    if indiv.energy==0:
        indiv.history_index=indiv.history_index+'m'+muttype
    else:
        indiv.history_index=repr(indiv.index)+'m'+muttype
    return indiv
Exemplo n.º 6
0
def get_defect_restart_indiv(Optimizer, indiv):
    """
    Function to generate an structopt Individual class object containing 
    	a defect structure from a previously existing structure
    Inputs:
    	Optimizer = structopt Optimizer class
    	indiv = ASE Atoms object containing the previously existing structure
    Outputs:
    	individ = structopt Individual class object containing defect structure data
    """
    if not Optimizer.solidbulk:
		#Initialize Bulk - Generate or load positions of bulk solid
		try:
		    rank = MPI.COMM_WORLD.Get_rank()
		except:
		    rank = 0
		outfilename = os.path.join(os.path.join(os.getcwd(),Optimizer.filename+'-rank'+repr(rank)),'Bulkfile.xyz')
		if Optimizer.evalsolid:
			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.summary.write('CIBS Run Pure Bulk Energy per Atom:'+
			repr(PureBulkEnpa)+'\n')
		Optimizer.purebulkenpa = PureBulkEnpa
		Optimizer.natomsbulk = natomsbulk
    indiv.set_cell(Optimizer.solidcell)
    indiv.set_pbc(True)
    if Optimizer.restart_ints == 0:
        outt = find_defects(indiv,Optimizer.solidbulk,Optimizer.sf)
    else:
        indicop = [atm for atm in indiv if atm.symbol != 'X']
        indiv = Atoms(cell=Optimizer.solidcell, pbc=True)
        for atm in indicop:
            indiv.append(atm)
        outt=[indiv[0:Optimizer.restart_ints],indiv[Optimizer.restart_ints::], Atoms(),
        	Atoms(),'Assuming first '+repr(Optimizer.restart_ints)+' are interstitials\n']
    indi = outt[0].copy()
    bulki = outt[1].copy()
    individ = Individual(indi)
    individ.bulko = bulki.copy()
    individ.bulki = bulki.copy()
    individ.purebulkenpa = Optimizer.purebulkenpa
    individ.natomsbulk = Optimizer.natomsbulk
    individ.vacancies = outt[2].copy()
    individ.swaps = outt[3].copy()
    Optimizer.output.write(outt[4])
    return individ
Exemplo n.º 7
0
def rattle(indiv):
    """Function to slightly alter atoms in structure. Intended for use in defect function.
    """
    atms,indb,vacant,swap,stro = find_defects(indiv[0],self.solidbulk,0.0)
    atmsl,indbl,vacantl,swapl,strol = find_defects(indiv[0],self.solidbulk,2.0)
    atmslist = []
    for atm1 in atmsl:
        for atm2 in atms:
            if atm1.symbol==atm2.symbol:
                if atm1.position[0]==atm2.position[0] and atm1.position[1]==atm2.position[1] and atm1.position[2]==atm2.position[2]:
                    atmslist.append(atm1.index)
    atmolist=[atm for atm in atmsl if atm.index not in atmslist]
    rat=Atoms(cell=atms.get_cell(), pbc=atms.get_pbc)
    for one in atmolist:
        rat.append(one)
    rat.rattle(stdev=0.2)
    ind=atms.copy()
    ind.extend(rat)
    ind.extend(indbl)
    return ind
	
	
Exemplo n.º 8
0
def zp_rotation(indiv, Optimizer):
    """Move function to perform Zero point rotation of atoms
    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.forcing != 'FreeNatom':
       ax=['x', '-x','y','-y','z','-z']
    else:
       ax=['z','-z']
    #Identify random rotation about axis and rotate all atoms
    rax=ax[random.randint(0,len(ax)-1)]
    #rang=random.uniform(30,180)
    rang=random.random()*math.pi
    #rang=random.random()*90
    if Optimizer.structure=='Defect':
        if Optimizer.isolate_mutation:
            atms,indb,vacant,swap,stro = find_defects(indiv[0],Optimizer.solidbulk,0)
        else:
            atms = indiv[0]
    else:
        atms=indiv[0]
    atms.rotate(rax,a=rang,center='COM',rotate_cell=False)
    if Optimizer.structure=='Defect':
        if Optimizer.isolate_mutation:
            atms.extend(indb)
    indiv[0]=atms.copy()
    Optimizer.output.write('Zero point full rotation performed on individual\n')
    Optimizer.output.write('Index = '+repr(indiv.index)+'\n')
    Optimizer.output.write('Rotation vector = '+repr(rax)+'\n')
    Optimizer.output.write('Rotation angle = '+repr(rang)+'\n')
    muttype='ZPR'
    if indiv.energy==0:
        indiv.history_index=indiv.history_index+'m'+muttype
    else:
        indiv.history_index=repr(indiv.index)+'m'+muttype
    return indiv
Exemplo n.º 9
0
def move_la(indiv, Optimizer):
    """Move function to move atoms in structure by lattice constant.  Intended for use in Defect optimization.
    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
    #Move structure by lattice constant
    Optimizer.output.write(
        'Lattice Constant Move Mutation performed on individual\n')
    if Optimizer.structure == 'Defect':
        if Optimizer.isolate_mutation:
            indc, indb, vacant, swaps, stro = find_defects(
                indiv[0], Optimizer.solidbulk, 0)
            ind = indc.copy()
        else:
            ind = indiv[0]
        la = numpy.maximum.reduce(
            numpy.maximum.reduce(ind.get_cell()) / Optimizer.solidcell)
        ax = [[1, 0, 0], [0, 1, 0], [0, 0, 1], [-1, 0, 0], [0, -1, 0],
              [0, 0, -1]]
        selax = [la * i for i in random.choice(ax)]
        ind.translate(selax)
        indiv[0] = ind.copy()
        if Optimizer.isolate_mutation:
            indiv[0].extend(indb)
    else:
        Optimizer.output.write(
            'WARNING: Move Mutation performed on non-Defect structure\n')
    Optimizer.output.write('Index = ' + repr(indiv.index) + '\n')
    Optimizer.output.write(repr(indiv[0]) + '\n')
    muttype = 'LM'
    if indiv.energy == 0:
        indiv.history_index = indiv.history_index + 'm' + muttype
    else:
        indiv.history_index = repr(indiv.index) + 'm' + muttype
    return indiv
Exemplo n.º 10
0
def zp_rotation(indiv, Optimizer):
    """Move function to perform Zero point rotation of atoms
    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
    ax = ['x', '-x', 'y', '-y', 'z', '-z']
    #Identify random rotation about axis and rotate all atoms
    rax = ax[random.randint(0, len(ax) - 1)]
    rang = random.uniform(30, 180)
    #rang=random.random()*90
    if Optimizer.structure == 'Defect':
        if Optimizer.isolate_mutation:
            atms, indb, vacant, swap, stro = find_defects(
                indiv[0], Optimizer.solidbulk, 0)
        else:
            atms = indiv[0]
    else:
        atms = indiv[0]
    atms.rotate(rax, a=rang, center='COM', rotate_cell=False)
    if Optimizer.structure == 'Defect':
        if Optimizer.isolate_mutation:
            atms.extend(indb)
    indiv[0] = atms.copy()
    Optimizer.output.write(
        'Zero point full rotation performed on individual\n')
    Optimizer.output.write('Index = ' + repr(indiv.index) + '\n')
    Optimizer.output.write('Rotation vector = ' + repr(rax) + '\n')
    Optimizer.output.write('Rotation angle = ' + repr(rang) + '\n')
    muttype = 'ZPR'
    if indiv.energy == 0:
        indiv.history_index = indiv.history_index + 'm' + muttype
    else:
        indiv.history_index = repr(indiv.index) + 'm' + muttype
    return indiv
Exemplo n.º 11
0
Arquivo: move_la.py Projeto: m-yu/MAST
def move_la(indiv, Optimizer):
    """Move function to move atoms in structure by lattice constant.  Intended for use in Defect optimization.
    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
    #Move structure by lattice constant
    Optimizer.output.write('Lattice Constant Move Mutation performed on individual\n')
    if Optimizer.structure=='Defect':
        if Optimizer.isolate_mutation:
            indc,indb,vacant,swaps,stro = find_defects(indiv[0],Optimizer.solidbulk,0)
            ind = indc.copy()
        else:
            ind = indiv[0]
        la = numpy.maximum.reduce(numpy.maximum.reduce(ind.get_cell())/Optimizer.solidcell)
        ax = [[1,0,0],[0,1,0],[0,0,1],[-1,0,0],[0,-1,0],[0,0,-1]]
        selax = [la*i for i in random.choice(ax)]
        ind.translate(selax)
        indiv[0]=ind.copy()
        if Optimizer.isolate_mutation:
            indiv[0].extend(indb)
    else:
        Optimizer.output.write('WARNING: Move Mutation performed on non-Defect structure\n')
    Optimizer.output.write('Index = '+repr(indiv.index)+'\n')
    Optimizer.output.write(repr(indiv[0])+'\n')
    muttype='LM'
    if indiv.energy==0:
        indiv.history_index=indiv.history_index+'m'+muttype
    else:
        indiv.history_index=repr(indiv.index)+'m'+muttype
    return indiv
    
Exemplo n.º 12
0
def eval_energy(Optimizer, individ):
    """Function to evaluate energy of an individual
    Inputs:
        input = [Optimizer class object with parameters, Individual class structure to be evaluated]
    Outputs:
        energy, bul, individ, signal
        energy = energy of Individual evaluated
        bul = bulk structure of Individual if simulation structure is Defect
        individ = Individual class structure evaluated
        signal = string of information about evaluation
    """
    #logger = initialize_logger(Optimizer.loggername)
    logger = logging.getLogger(Optimizer.loggername)
    if 'MAST' in Optimizer.calc_method:
        energy = individ.energy
        bul = individ.bulki
        signal = 'Received MAST structure\n'
        logger.info(
            'Received individual index = {0} from MAST with energy {1}. Returning with no evaluation'
            .format(individ.index, individ.energy))
    else:
        if Optimizer.parallel:
            rank = MPI.COMM_WORLD.Get_rank()
        logger.info(
            'Received individual HI = {0} with energy {1} for energy evaluation'
            .format(individ.history_index, individ.energy))
        STR = '----Individual ' + str(
            individ.history_index) + ' Optimization----\n'
        indiv = individ[0]
        if 'EE' in Optimizer.debug:
            debug = True
        else:
            debug = False
        if debug:
            write_xyz(Optimizer.debugfile, indiv, 'Received by eval_energy')
            Optimizer.debugfile.flush()
            logger.debug('Writing recieved individual to debug file')
        # Establish individual structure for evaluation.  Piece together regions when necessary.
        if Optimizer.structure == 'Defect':
            indi = indiv.copy()
            bulk = individ.bulki
            nat = indi.get_number_of_atoms()
            if debug:
                logger.info(
                    'Extending defect structure to include bulk len(r1+r2)={0} len(bulk)={1}'
                    .format(nat, len(bulk)))
            csize = bulk.get_cell()
            totalsol = Atoms(cell=csize, pbc=True)
            totalsol.extend(indi)
            totalsol.extend(bulk)
            for sym, c, m, u in Optimizer.atomlist:
                nc = len([atm for atm in totalsol if atm.symbol == sym])
                STR += 'Defect configuration contains ' + repr(
                    nc) + ' ' + repr(sym) + ' atoms\n'
        elif Optimizer.structure == 'Surface':
            totalsol = Atoms()
            totalsol.extend(indiv)
            nat = indiv.get_number_of_atoms()
            totalsol.extend(individ.bulki)
            if debug:
                logger.info(
                    'Extending surface structure to include bulk len(r1+r2)={0} len(bulk)={1}'
                    .format(nat, len(individ.bulki)))
            for sym, c, m, u in Optimizer.atomlist:
                nc = len([atm for atm in totalsol if atm.symbol == sym])
                STR += 'Surface-Bulk configuration contains ' + repr(
                    nc) + ' ' + repr(sym) + ' atoms\n'
            cell = numpy.maximum.reduce(indiv.get_cell())
            totalsol.set_cell([cell[0], cell[1], 500])
            totalsol.set_pbc([True, True, False])
        elif Optimizer.structure == 'Cluster':
            totalsol = indiv.copy()
            nat = len(totalsol)
            if debug:
                logger.info(
                    'Extending cluster with {0} atoms to center of evaluation box of size {1}'
                    .format(nat, Optimizer.large_box_size))
            origcell = indiv.get_cell()
            totalsol.set_cell([
                Optimizer.large_box_size, Optimizer.large_box_size,
                Optimizer.large_box_size
            ])
            totalsol.translate([
                Optimizer.large_box_size / 2.0, Optimizer.large_box_size / 2.0,
                Optimizer.large_box_size / 2.0
            ])
        elif Optimizer.structure == 'Crystal':
            totalsol = indiv.copy()
            nat = len(totalsol)
        else:
            print 'WARNING: In EvalEnergy. Optimizer.structure not recognized'
            logger.warning('Optimizer.structure not recognized')

        # Check for atoms that are too close or out of constrained location
        if Optimizer.constrain_position:
            if Optimizer.structure == 'Defect':
                if debug:
                    logger.info('Constraining positions of defect')
                totalsol, stro = constrain_positions(totalsol,
                                                     Optimizer.solidbulk,
                                                     Optimizer.sf)
                if debug:
                    logger.info(stro)
                STR += str0
        min_len = 0.7
        if not Optimizer.fixed_region:
            if debug:
                logger.info('Running check minimum distance')
            totalsol, STR = check_min_dist(totalsol, Optimizer.structure, nat,
                                           min_len, STR)
            if debug:
                write_xyz(Optimizer.debugfile, totalsol,
                          'After minlength check')
                Optimizer.debugfile.flush()
                logger.debug(
                    'Writing individual after checking minimum length')

        # Set calculator to use to get forces/energies
        if Optimizer.parallel:
            calc = setup_calculator(Optimizer)
            if Optimizer.fixed_region:
                if debug:
                    logger.info('Setting up fixed region calculator')
                pms = copy.deepcopy(calc.parameters)
                try:
                    pms['mass'][
                        len(pms['mass']) -
                        1] += '\ngroup RO id >= {0}\nfix freeze RO setforce 0.0 0.0 0.0\n'.format(
                            nat)
                except KeyError:
                    pms['pair_coeff'][
                        0] += '\ngroup RO id >= {0}\nfix freeze RO setforce 0.0 0.0 0.0\n'.format(
                            nat)
                calc = LAMMPS(parameters=pms,
                              files=calc.files,
                              keep_tmp_files=calc.keep_tmp_files,
                              tmp_dir=calc.tmp_dir)
                lmin = copy.copy(Optimizer.lammps_min)
                if debug:
                    logger.info('Setting up no local minimization calculator')
                Optimizer.lammps_min = None
                Optimizer.static_calc = setup_calculator(Optimizer)
                Optimizer.lammps_min = lmin
        else:
            calc = Optimizer.calc
        totalsol.set_calculator(calc)
        totalsol.set_pbc(True)

        # Perform Energy Minimization
        if not Optimizer.parallel:
            if debug:
                write_xyz(Optimizer.debugfile, totalsol,
                          'Individual sent to Energy Minimizer')
                logger.debug('Writing structure sent to energy minimizer')
        try:
            cwd = os.getcwd()
            if Optimizer.ase_min == True:
                if debug:
                    logger.info('Running ASE minimizer')
                if Optimizer.calc_method == 'LennardJones':
                    logger.warn('Must run ase LJ calculator with pbc=False')
                    totalsol.set_pbc(False)
                totalsol, energy, pressure, volume, STR = run_ase_min(
                    totalsol, Optimizer.ase_min_fmax,
                    Optimizer.ase_min_maxsteps, Optimizer.fitness_scheme, STR)
            else:
                if debug:
                    logger.info('Running local energy calculator')
                if Optimizer.fixed_region:
                    totalsol, energy, pressure, volume, STR = run_energy_eval(
                        totalsol, Optimizer.calc_method,
                        Optimizer.fixed_region, Optimizer.fitness_scheme, STR,
                        Optimizer.static_calc)
                else:
                    totalsol, energy, pressure, volume, STR = run_energy_eval(
                        totalsol, Optimizer.calc_method, False,
                        Optimizer.fitness_scheme, STR)
        except Exception, e:
            logger.critical('Error in energy evaluation: {0}'.format(e),
                            exc_info=True)
            path = os.path.join(cwd, 'TroubledLammps')
            if not os.path.exists(path):
                os.mkdir(path)
            #Copy files over
            shutil.copyfile(
                calc.trajfile,
                os.path.join(path, os.path.basename(calc.trajfile)))
            shutil.copyfile(calc.infile,
                            os.path.join(path, os.path.basename(calc.infile)))
            shutil.copyfile(calc.logfile,
                            os.path.join(path, os.path.basename(calc.logfile)))
            shutil.copyfile(
                calc.datafile,
                os.path.join(path, os.path.basename(calc.datafile)))
            raise RuntimeError('{0}:{1}'.format(Exception, e))
        if not Optimizer.parallel:
            if debug:
                write_xyz(Optimizer.debugfile, totalsol,
                          'Individual after Energy Minimization')
                Optimizer.debugfile.flush()
                logger.debug(
                    'Writing structure recieved from energy minimizer')

        # Separate structures into distinct pieces
        if Optimizer.structure == 'Defect':
            if Optimizer.fixed_region == True or Optimizer.finddefects == False:
                if debug:
                    logger.info(
                        'Identifying atoms in defect structure based on ID')
                individ[0] = totalsol[0:nat]
                bul = totalsol[(nat):len(totalsol)]
                individ[0].set_cell(csize)
            else:
                if debug:
                    logger.info(
                        'Applying find defects scheme to identify R1 and R2 for Defect'
                    )
                if 'FD' in Optimizer.debug:
                    outt = find_defects(totalsol,
                                        Optimizer.solidbulk,
                                        Optimizer.sf,
                                        atomlistcheck=Optimizer.atomlist,
                                        trackvacs=Optimizer.trackvacs,
                                        trackswaps=Optimizer.trackswaps,
                                        debug=Optimizer.debugfile)
                else:
                    outt = find_defects(totalsol,
                                        Optimizer.solidbulk,
                                        Optimizer.sf,
                                        atomlistcheck=Optimizer.atomlist,
                                        trackvacs=Optimizer.trackvacs,
                                        trackswaps=Optimizer.trackswaps,
                                        debug=False)
                individ[0] = outt[0]
                bul = outt[1]
                individ.vacancies = outt[2]
                individ.swaps = outt[3]
                STR += outt[4]
            indiv = individ[0]
        elif Optimizer.structure == 'Surface':
            if debug:
                logger.info('Finding surface top layer')
            top, bul = find_top_layer(totalsol, Optimizer.surftopthick)
            indiv = top.copy()
            individ[0] = top.copy()
            bul = Atoms()
        elif Optimizer.structure == 'Crystal':
            if debug:
                logger.info('Checking crystal cell type')
            celltype = check_cell_type(totalsol)
            STR += 'Cell structure = {0}\n'.format(celltype)
            bul = Atoms()
            individ[0] = totalsol.copy()
        elif Optimizer.structure == 'Cluster':
            volume = get_cluster_volume(totalsol)
            bul = Atoms()
            if debug:
                logger.info(
                    'Translating cluster back to smaller box size location')
            totalsol.translate([
                -Optimizer.large_box_size / 2.0,
                -Optimizer.large_box_size / 2.0,
                -Optimizer.large_box_size / 2.0
            ])
            totalsol.set_cell(origcell)
            individ[0] = totalsol.copy()

        # Add concentration energy dependence
        if Optimizer.forcing == 'energy_bias':
            if debug:
                logger.info(
                    'Applying energy bias for atoms with different number of atoms of type than in atomlist'
                )
            n = [0] * len(Optimizer.atomlist)
            for i in range(len(Optimizer.atomlist)):
                n[i] = len([
                    inds for inds in totalsol
                    if inds.symbol == Optimizer.atomlist[i][0]
                ])
                n[i] = abs(n[i] - Optimizer.atomlist[i][1])
            factor = sum(n)**3
            energy = (energy + factor) / totalsol.get_number_of_atoms()
            STR += 'Energy with Bias = {0}\n'.format(energy)
        elif Optimizer.forcing == 'chem_pot':
            if debug:
                logger.info(
                    'Applying chemical potential bias for atoms with different number of atoms of type than in atomlist'
                )
            n = [0] * len(Optimizer.atomlist)
            for i in range(len(Optimizer.atomlist)):
                n[i] = len([
                    inds for inds in totalsol
                    if inds.symbol == Optimizer.atomlist[i][0]
                ])
                n[i] = n[i] * Optimizer.atomlist[i][3]
            factor = sum(n)
            energy = (energy + factor) / totalsol.get_number_of_atoms()
            STR += 'Energy with Chemical Potential = {0}\n'.format(energy)

        individ.energy = energy
        individ.buli = bul
        individ.pressure = pressure
        individ.volume = volume

        if Optimizer.fingerprinting:
            if debug:
                logger.info('Identifying fingerprint of new structure')
            individ.fingerprint = get_fingerprint(Optimizer, individ,
                                                  Optimizer.fpbin,
                                                  Optimizer.fpcutoff)
        if Optimizer.parallel:
            calc.clean()
            signal = 'Evaluated individual {0} on {1}\n'.format(
                individ.index, rank)
            signal += STR
        else:
            signal = STR
Exemplo n.º 13
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
Exemplo n.º 14
0
def rotct_rand_defect(ind1, ind2, Optimizer):
    """Rotate atoms cut and splice
    Translates atoms to center of positions first
    Rotates atoms randomly around center of mass and cuts with xy plane
    Maintains number of atoms
    Maintains concentration of atoms
    Returns individuals to standard positions at end (un-rotates)
    """
    if "CX" in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write(
        "Random Rotate Cut/Splice Cx for defects between individual "
        + repr(ind1.index)
        + " and individual "
        + repr(ind2.index)
        + "\n"
    )

    # Perserve starting conditions of individual
    indi1 = ind1[0].copy()
    indi2 = ind2[0].copy()
    # Translate individuals so COP is at (0,0,0)
    if Optimizer.structure == "Defect":
        # Identify center of positions for defect structure
        indi1c, indi1b, vacant1, swap1, stro1 = find_defects(indi1, Optimizer.solidbulk, 0)
        com1 = position_average(indi1c)
        indi1 = shift_atoms(indi1, com1)
        # Do the same for second individual
        indi2c, indi2b, vacant2, swap2, stro2 = find_defects(indi2, Optimizer.solidbulk, 0)
        com2 = position_average(indi2c)
        indi2 = shift_atoms(indi2, com2)
    else:
        com1 = indi1.get_center_of_mass()
        indi1.translate(-1 * com1)
        com2 = indi2.get_center_of_mass()
        indi2.translate(-1 * com2)
    # Select random axis, random angle, and random position and rotate individuals
    cmax = [
        min(numpy.maximum.reduce(indi1.get_positions())[i], numpy.maximum.reduce(indi2.get_positions())[i])
        for i in range(3)
    ]
    cmin = [
        min(numpy.minimum.reduce(indi1.get_positions())[i], numpy.minimum.reduce(indi2.get_positions())[i])
        for i in range(3)
    ]
    n = 0
    while n < 10:
        rax = random.choice(["x", "-x", "y", "-y", "z", "-z"])
        rang = random.random() * 90
        rpos = [random.uniform(cmin[i] * 0.8, cmax[i] * 0.8) for i in range(3)]
        indi1.rotate(rax, a=rang, center=rpos, rotate_cell=False)
        # Search for atoms in individual 1 that are above the xy plane
        group1 = Atoms(cell=ind1[0].get_cell(), pbc=ind1[0].get_pbc())
        indices1 = []
        for one in indi1:
            if one.position[2] >= 0:
                group1.append(one)
                indices1.append(one.index)
        if len(group1) > 2 and len(group1) < len(indi1):
            break
        else:
            n += 1
            indi1.rotate(rax, a=-1 * rang, center=rpos, rotate_cell=False)
    indi2.rotate(rax, a=rang, center=rpos, rotate_cell=False)
    if debug:
        print "Group1 size = ", len(group1)
        print "Position = ", rpos
        print "Angle = ", rang
        print "Axis = ", rax
        print "Number of tries = ", n
    if len(group1) != 0:
        # Apply concentration forcing if needed
        group2 = Atoms(cell=ind2[0].get_cell(), pbc=ind2[0].get_pbc())
        indices2 = []
        dellist = []
        for one in indi2:
            if one.position[2] >= 0:
                group2.append(one)
                indices2.append(one.index)
        if Optimizer.forcing == "Concentration":
            symlist = list(set(indi1.get_chemical_symbols()))
            seplist = [[atm for atm in group2 if atm.symbol == sym] for sym in symlist]
            group2n = Atoms(cell=group2.get_cell(), pbc=group2.get_pbc())
            indices2n = []
            dellist = []
            for one in group1:
                sym1 = one.symbol
                listpos = [i for i, s in enumerate(symlist) if s == sym1][0]
                if len(seplist[listpos]) > 0:
                    pos = random.choice(range(len(seplist[listpos])))
                    group2n.append(seplist[listpos][pos])
                    indices2n.append(indices2[seplist[listpos][pos].index])
                    del seplist[listpos][pos]
                else:
                    dellist.append(one.index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group1[one]
                    del indices1[one]
            indices2 = indices2n
            group2 = group2n.copy()
        else:
            dellist = []
            while len(group2) < len(group1) - len(dellist):
                # Too many atoms in group 1
                dellist.append(random.choice(group1).index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group1[one]
                    del indices1[one]
            dellist = []
            while len(group1) < len(group2) - len(dellist):
                # Too many atoms in group 2
                dellist.append(random.choice(group2).index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group2[one]
                    del indices2[one]

        other2 = Atoms(cell=ind2[0].get_cell(), pbc=ind2[0].get_pbc())
        for one in indi2:
            if one.index not in indices2:
                other2.append(one)
        other1 = Atoms(cell=ind1[0].get_cell(), pbc=ind1[0].get_pbc())
        for one in indi1:
            if one.index not in indices1:
                other1.append(one)
        indi1 = group2.copy()
        indi1.extend(other1)
        indi2 = group1.copy()
        indi2.extend(other2)

        # DEBUG: Write crossover to file
        if debug:
            write_xyz(Optimizer.debugfile, group1, "group1")
            write_xyz(Optimizer.debugfile, other1, "other1")
            write_xyz(Optimizer.debugfile, group2, "group2")
            write_xyz(Optimizer.debugfile, other2, "other2")
            print "Length of group1 = ", len(group1), "Length of group2", len(group2)

        # DEBUG: Check structure of atoms exchanged
        for sym, c, m, u in Optimizer.atomlist:
            nc = len([atm for atm in indi1 if atm.symbol == sym])
            Optimizer.output.write(
                "CX RANDROTCT_Defect: Individual 1 contains " + repr(nc) + " " + repr(sym) + " atoms\n"
            )
            nc = len([atm for atm in indi2 if atm.symbol == sym])
            Optimizer.output.write(
                "CX RANDROTCT_Defect: Individual 2 contains " + repr(nc) + " " + repr(sym) + " atoms\n"
            )
        if Optimizer.forcing != "Concentration":
            for i in range(len(Optimizer.atomlist)):
                atms1 = [inds for inds in indi1 if inds.symbol == Optimizer.atomlist[i][0]]
                atms2 = [inds for inds in indi2 if inds.symbol == Optimizer.atomlist[i][0]]
                if len(atms1) == 0:
                    if len(atms2) == 0:
                        indi1[random.randint(0, len(indi1) - 1)].symbol == Optimizer.atomlist[i][0]
                        indi2[random.randint(0, len(indi2) - 1)].symbol == Optimizer.atomlist[i][0]
                    else:
                        indi1.append(atms2[random.randint(0, len(atms2) - 1)])
                        indi1.pop(random.randint(0, len(indi1) - 2))
                else:
                    if len(atms2) == 0:
                        indi2.append(atms1[random.randint(0, len(atms1) - 1)])
                        indi2.pop(random.randint(0, len(indi2) - 2))
        indi1.rotate(rax, a=-1 * rang, center=rpos, rotate_cell=False)
        indi2.rotate(rax, a=-1 * rang, center=rpos, rotate_cell=False)
        if Optimizer.structure == "Defect":
            indi1 = shift_atoms(indi1, [-p for p in com1])
            indi2 = shift_atoms(indi2, [-p for p in com2])
        else:
            indi1.translate(com1)
            indi2.translate(com2)

        # DEBUG: Check structure and number of atoms in crystal
        if Optimizer.structure == "Defect":
            solid1 = Atoms()
            solid1.extend(indi1)
            solid1.extend(ind1.bulki)
            solid2 = Atoms()
            solid2.extend(indi2)
            solid2.extend(ind2.bulki)
            for sym, c, m, u in Optimizer.atomlist:
                nc = len([atm for atm in solid1 if atm.symbol == sym])
                Optimizer.output.write(
                    "CX RANDROTCT_Defect: Defect 1 configuration contains " + repr(nc) + " " + repr(sym) + " atoms\n"
                )
                nc = len([atm for atm in solid2 if atm.symbol == sym])
                Optimizer.output.write(
                    "CX RANDROTCT_Defect: Defect 2 configuration contains " + repr(nc) + " " + repr(sym) + " atoms\n"
                )
        if debug:
            Optimizer.output.flush()
        # pdb.set_trace()
        ind1[0] = indi1
        ind2[0] = indi2

    return ind1, ind2
Exemplo n.º 15
0
def lattice_alteration_rdrd(indiv, Optimizer):
    """Move function to move random atoms in random direction for random distance
    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
    d_max = numpy.minimum.reduce(
        numpy.maximum.reduce(indiv[0].get_positions()) -
        numpy.minimum.reduce(indiv[0].get_positions()))
    if Optimizer.structure == 'Defect':
        if Optimizer.isolate_mutation:
            indc, indb, vacant, swap, stro = find_defects(
                indiv[0], Optimizer.solidbulk, 0)
            positions = indc.get_positions()
        else:
            positions = indiv[0].get_positions()
    else:
        positions = indiv[0].get_positions()
    if len(positions) != 0:
        try:
            natomsmove = random.randint(1, len(positions) / 5)
        except ValueError:
            natomsmove = 1
        r = random.uniform(0.5, d_max)
        theta = math.radians(random.uniform(0, 360))
        phi = math.radians(random.uniform(0, 180))
        direction = [
            r * math.sin(theta) * math.cos(phi),
            r * math.sin(theta) * math.sin(phi), r * math.cos(theta)
        ]
        ratmlocnew = [0] * natomsmove
        for i in range(natomsmove):
            ratmloc = random.randint(0, len(positions) - 1)
            ratmlocnew[i] = (direction[0] + positions[ratmloc][0],
                             direction[1] + positions[ratmloc][1],
                             direction[2] + positions[ratmloc][2])
            positions[ratmloc] = ratmlocnew[i]
        if Optimizer.structure == 'Defect':
            if Optimizer.isolate_mutation:
                indc.set_positions(positions)
                indiv[0] = indc.copy()
                indiv[0].extend(indb)
            else:
                indiv[0].set_positions(positions)
        else:
            indiv[0].set_positions(positions)
    else:
        natomsmove = 0
        ratmlocnew = 0
    Optimizer.output.write(
        'Lattice Alteration Mutation performed on individual\n')
    Optimizer.output.write('Index = ' + repr(indiv.index) + '\n')
    Optimizer.output.write('Number of atoms moved = ' + repr(natomsmove) +
                           '\n')
    Optimizer.output.write(repr(ratmlocnew) + '\n')
    Optimizer.output.write(repr(indiv[0]) + '\n')
    muttype = 'LARD' + repr(natomsmove)
    if indiv.energy == 0:
        indiv.history_index = indiv.history_index + 'm' + muttype
    else:
        indiv.history_index = repr(indiv.index) + 'm' + muttype
    return indiv
Exemplo n.º 16
0
def rotct_rand_clus(ind1, ind2, Optimizer):
    """Rotate atoms cut and splice
    Rotates atoms randomly around center of mass and cuts with xy plane
    Maintains number of atoms
    Maintains concentration of atoms
    Returns individuals to standard positions at end (un-rotates)
    """
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    if Optimizer.structure != 'Defect':
        Optimizer.output.write('Rotate-Cut Random Cluster Cx attempted on Non Defect structure. SKIPPING CX.\n')
    else:
        Optimizer.output.write('Rotate-Cut Random Cluster Cx between individual '+repr(ind1.index)+' and individual '+repr(ind2.index)+'\n')

        #Perserve starting conditions of individual
        indi1 = ind1[0].copy()
        indi2 =ind2[0].copy()

        indi1c,indi1b,vacant1,swap1,stro1 = find_defects(indi1,Optimizer.solidbulk,0)
        indi2c,indi2b,vacant2,swap2,stro2 = find_defects(indi2,Optimizer.solidbulk,0)
    
        if len(indi1c) !=0 and len(indi2c) != 0:
            #Translate individuals so COM is at (0,0,0)
            com1 = indi1c.get_center_of_mass()
            indi1c.translate(-1*com1)
            com2 = indi2c.get_center_of_mass()
            indi2c.translate(-1*com2)
            #Select random axis, random angle, and random position and rotate individuals
            cmax = [min(numpy.maximum.reduce(indi1c.get_positions())[i],numpy.maximum.reduce(indi2c.get_positions())[i]) for i in range(3)]
            cmin = [min(numpy.minimum.reduce(indi1c.get_positions())[i],numpy.minimum.reduce(indi2c.get_positions())[i]) for i in range(3)]
            n=0
            while n<10:
                rax = random.choice(['x', '-x','y','-y','z','-z'])
                rang = random.random()*90
                rpos = [random.uniform(cmin[i]*0.8,cmax[i]*0.8) for i in range(3)]
                indi1c.rotate(rax,a=rang,center=rpos,rotate_cell=False)
                #Search for atoms in individual 1 that are above the xy plane
                group1 = Atoms(cell=ind1[0].get_cell(),pbc=ind1[0].get_pbc())
                indices1=[]
                for one in indi1c:
                    if one.position[2] >= 0:
                        group1.append(one)
                        indices1.append(one.index)
                if len(group1) > 2 and len(group1) < len(indi1):
                    break
                else:
                    n+=1
                    indi1c.rotate(rax,a=-1*rang,center=rpos, rotate_cell=False)
            indi2c.rotate(rax,a=rang,center=rpos,rotate_cell=False)
            if debug: 
                print 'Group1 size = ', len(group1)
                print 'Position = ', rpos
                print 'Angle = ', rang
                print 'Axis = ', rax
                print 'Number of tries = ', n
            if len(group1) != 0:
                #Apply concentration forcing if needed
                group2 = Atoms(cell=ind2[0].get_cell(),pbc=ind2[0].get_pbc())
                indices2 = []
                dellist = []
                for one in indi2c:
                    if one.position[2] >= 0:
                        group2.append(one)
                        indices2.append(one.index)
                if Optimizer.forcing=='Concentration':
                    symlist = list(set(indi1c.get_chemical_symbols()))
                    seplist = [[atm for atm in group2 if atm.symbol == sym] for sym in symlist]
                    group2n=Atoms(cell=group2.get_cell(),pbc=group2.get_pbc())
                    indices2n = []
                    dellist = []
                    for one in group1:
                        sym1=one.symbol
                        listpos=[i for i,s in enumerate(symlist) if s==sym1][0]
                        if len(seplist[listpos]) > 0:
                            pos = random.choice(range(len(seplist[listpos])))
                            group2n.append(seplist[listpos][pos])
                            indices2n.append(indices2[seplist[listpos][pos].index])
                            del seplist[listpos][pos]
                        else:
                            dellist.append(one.index)
                    if len(dellist) != 0:
                        dellist.sort(reverse=True)
                        for one in dellist:
                            del group1[one]
                            del indices1[one]
                    indices2=indices2n
                    group2=group2n.copy()
                else:
                    dellist = []
                    while len(group2) < len(group1)-len(dellist):
                        #Too many atoms in group 1
                        dellist.append(random.choice(group1).index)
                    if len(dellist) != 0:
                        dellist.sort(reverse=True)
                        for one in dellist:
                            del group1[one]
                            del indices1[one]
                    dellist = []
                    while len(group1) < len(group2)-len(dellist):
                        #Too many atoms in group 2
                        dellist.append(random.choice(group2).index)
                    if len(dellist) != 0:
                        dellist.sort(reverse=True)
                        for one in dellist:
                            del group2[one]
                            del indices2[one]

                other2 = Atoms(cell=ind2[0].get_cell(),pbc=ind2[0].get_pbc())
                for one in indi2c:
                    if one.index not in indices2:
                        other2.append(one)

                other1 = Atoms(cell=ind1[0].get_cell(),pbc=ind1[0].get_pbc())
                for one in indi1c:
                    if one.index not in indices1:
                        other1.append(one)
                group1.rotate(rax,a=-1*rang,center=rpos, rotate_cell=False)
                group1.translate(com1)
                other1.rotate(rax,a=-1*rang,center=rpos, rotate_cell=False)
                other1.translate(com1)
                group2.rotate(rax,a=-1*rang,center=rpos, rotate_cell=False)
                group2.translate(com2)
                other2.rotate(rax,a=-1*rang,center=rpos, rotate_cell=False)
                other2.translate(com2)
                indi1 = group2.copy()
                indi1.extend(other1)
                indi1.extend(indi1b)
                indi2 = group1.copy()
                indi2.extend(other2)
                indi2.extend(indi2b)

                #DEBUG: Write crossover to file
                if debug: 
                    write_xyz(Optimizer.debugfile, group1,'group1')
                    write_xyz(Optimizer.debugfile, other1,'other1')
                    write_xyz(Optimizer.debugfile, group2,'group2')
                    write_xyz(Optimizer.debugfile, other2,'other2')
                    print 'Length of group1 = ',len(group1),'Length of group2',len(group2)

                #DEBUG: Check structure of atoms exchanged
                for sym,c,m,u in Optimizer.atomlist:
                    nc=len([atm for atm in indi1 if atm.symbol==sym])
                    Optimizer.output.write('CX RANDROTCT: Individual 1 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
                    nc=len([atm for atm in indi2 if atm.symbol==sym])
                    Optimizer.output.write('CX RANDROTCT: Individual 2 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
                if Optimizer.forcing !='Concentration':
                    for i in range(len(Optimizer.atomlist)):
                        atms1=[inds for inds in indi1 if inds.symbol==Optimizer.atomlist[i][0]]
                        atms2=[inds for inds in indi2 if inds.symbol==Optimizer.atomlist[i][0]]
                        if len(atms1)==0:
                            if len(atms2)==0:
                                indi1[random.randint(0,len(indi1)-1)].symbol==Optimizer.atomlist[i][0]
                                indi2[random.randint(0,len(indi2)-1)].symbol==Optimizer.atomlist[i][0]
                            else:
                                indi1.append(atms2[random.randint(0,len(atms2)-1)])
                                indi1.pop(random.randint(0,len(indi1)-2))
                        else:
                            if len(atms2)==0:
                                indi2.append(atms1[random.randint(0,len(atms1)-1)])
                                indi2.pop(random.randint(0,len(indi2)-2))	

            #DEBUG: Check structure and number of atoms in crystal
            if Optimizer.structure=='Defect':
                solid1=Atoms()
                solid1.extend(indi1)
                solid1.extend(ind1.bulki)
                solid2=Atoms()
                solid2.extend(indi2)
                solid2.extend(ind2.bulki)
                for sym,c,m,u in Optimizer.atomlist:
                    nc=len([atm for atm in solid1 if atm.symbol==sym])
                    Optimizer.output.write('CX RANDROTCT: Defect 1 configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n')
                    nc=len([atm for atm in solid2 if atm.symbol==sym])
                    Optimizer.output.write('CX RANDROTCT: Defect 2 configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n')
            if debug: Optimizer.output.flush()
            #pdb.set_trace()
        else:
            Optimizer.output.write('  Warning: failed to identify a cluster:\n')
            Optimizer.output.write('    Individual '+repr(ind1.index)+' length = '+repr(len(indi1c))+'\n')
            Optimizer.output.write('    Individual '+repr(ind2.index)+' length = '+repr(len(indi2c))+'\n')
        ind1[0]=indi1
        ind2[0]=indi2
    return ind1, ind2
Exemplo n.º 17
0
def lattice_alteration_small(indiv, Optimizer):
    """Move function to perform small Lattice Alteration of atoms
    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
    natomsmove = 0
    ratmlocnew = 0
    if Optimizer.structure=='Defect':
        if Optimizer.isolate_mutation:
            indc,indb,vacant,swap,stro = find_defects(indiv[0],Optimizer.solidbulk,0)
            positions = indc.get_positions()
            if len(positions) != 0:
                try:
                    natomsmove=random.randint(1,len(positions))
                except ValueError:
                    natomsmove=1
            else:
                natomsmove = 0
        else:
            positions=indiv[0].get_positions()
            if len(positions) != 0:
                try:
                    natomsmove=random.randint(1,len(positions)/5)
                except ValueError:
                    natomsmove=1
            else:
                natomsmove = 0
    else:
        positions=indiv[0].get_positions()
        if len(positions) != 0:
            try:
                natomsmove=random.randint(1,len(positions)/5)
            except ValueError:
                natomsmove=1
        else:
            natomsmove = 0
    ratmlocnew=[0]*natomsmove
    for i in range(natomsmove):
        ratmloc=random.randint(0,len(positions)-1)
        ratmlocnew[i]=(random.uniform(-1,1), random.uniform(-1,1), random.uniform(-1,1))
        positions[ratmloc]+=ratmlocnew[i]
    if Optimizer.structure=='Defect':
        if Optimizer.isolate_mutation:
            indc.set_positions(positions)
            indiv[0]=indc.copy()
            indiv[0].extend(indb)
        else:
            indiv[0].set_positions(positions)
    else:
        indiv[0].set_positions(positions)
    Optimizer.output.write('Lattice Alteration Small Mutation performed on individual\n')
    Optimizer.output.write('Index = '+repr(indiv.index)+'\n')
    Optimizer.output.write('Number of atoms moved = '+repr(natomsmove)+'\n')
    Optimizer.output.write(repr(ratmlocnew)+'\n')
    Optimizer.output.write(repr(indiv[0])+'\n')
    muttype='LAS'+repr(natomsmove)
    if indiv.energy==0:
        indiv.history_index=indiv.history_index+'m'+muttype
    else:
        indiv.history_index=repr(indiv.index)+'m'+muttype
    return indiv
Exemplo n.º 18
0
def eval_energy(Optimizer, individ):
    """Function to evaluate energy of an individual
    Inputs:
        input = [Optimizer class object with parameters, Individual class structure to be evaluated]
    Outputs:
        energy, bul, individ, signal
        energy = energy of Individual evaluated
        bul = bulk structure of Individual if simulation structure is Defect
        individ = Individual class structure evaluated
        signal = string of information about evaluation
    """
    #logger = initialize_logger(Optimizer.loggername)
    logger = logging.getLogger(Optimizer.loggername)
    if 'MAST' in Optimizer.calc_method:
        energy = individ.energy
        bul = individ.bulki
        signal = 'Received MAST structure\n'
        logger.info('Received individual index = {0} from MAST with energy {1}. Returning with no evaluation'.format(
            individ.index, individ.energy))
    else:
        if Optimizer.parallel: 
            rank = MPI.COMM_WORLD.Get_rank()
        logger.info('Received individual HI = {0} with energy {1} for energy evaluation'.format(
            individ.history_index, individ.energy))
        STR='----Individual ' + str(individ.history_index)+ ' Optimization----\n'
        indiv=individ[0]
        if 'EE' in Optimizer.debug:
            debug = True
        else:
            debug = False
        if debug: 
            write_xyz(Optimizer.debugfile,indiv,'Received by eval_energy')
            Optimizer.debugfile.flush()
            logger.debug('Writing recieved individual to debug file')
        # Establish individual structure for evaluation.  Piece together regions when necessary.
        if Optimizer.structure=='Defect':
            indi=indiv.copy()
            bulk=individ.bulki
            nat=indi.get_number_of_atoms()
            if debug: 
                logger.info('Extending defect structure to include bulk len(r1+r2)={0} len(bulk)={1}'.format(nat,len(bulk)))
            csize=bulk.get_cell()                                                                                                         
            totalsol=Atoms(cell=csize, pbc=True)
            totalsol.extend(indi)
            totalsol.extend(bulk)
            for sym,c,m,u in Optimizer.atomlist:
                nc=len([atm for atm in totalsol if atm.symbol==sym])
                STR+='Defect configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n'
        elif Optimizer.structure=='Surface':
            totalsol=Atoms()
            totalsol.extend(indiv)
            nat=indiv.get_number_of_atoms()
            totalsol.extend(individ.bulki)
            if debug:
                logger.info('Extending surface structure to include bulk len(r1+r2)={0} len(bulk)={1}'.format(nat,len(individ.bulki)))
            for sym,c,m,u in Optimizer.atomlist:
                nc=len([atm for atm in totalsol if atm.symbol==sym])
                STR+='Surface-Bulk configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n'
            cell=numpy.maximum.reduce(indiv.get_cell())
            totalsol.set_cell([cell[0],cell[1],500])
            totalsol.set_pbc([True,True,False])
        elif Optimizer.structure=='Cluster':
            totalsol = indiv.copy()
            nat = len(totalsol)
            if debug:
                logger.info('Extending cluster with {0} atoms to center of evaluation box of size {1}'.format(nat,Optimizer.large_box_size))
            origcell = indiv.get_cell()
            totalsol.set_cell([Optimizer.large_box_size,Optimizer.large_box_size,Optimizer.large_box_size])
            totalsol.translate([Optimizer.large_box_size/2.0,Optimizer.large_box_size/2.0,Optimizer.large_box_size/2.0])
        elif Optimizer.structure=='Crystal':
            totalsol = indiv.copy()
            nat = len(totalsol)
        else:
            print 'WARNING: In EvalEnergy. Optimizer.structure not recognized'
            logger.warning('Optimizer.structure not recognized')
        
        # Check for atoms that are too close or out of constrained location
        if Optimizer.constrain_position:
            if Optimizer.structure=='Defect':
                if debug:
                    logger.info('Constraining positions of defect')
                totalsol, stro = constrain_positions(totalsol, Optimizer.solidbulk, Optimizer.sf)
                if debug:
                    logger.info(stro)
                STR+=str0
        min_len=0.7
        if not Optimizer.fixed_region:
            if debug:
                logger.info('Running check minimum distance')
            totalsol, STR = check_min_dist(totalsol, Optimizer.structure, nat, min_len, STR)
            if debug:
                write_xyz(Optimizer.debugfile,totalsol,'After minlength check')
                Optimizer.debugfile.flush()
                logger.debug('Writing individual after checking minimum length')
        
        # Set calculator to use to get forces/energies
        if Optimizer.parallel:
            calc = setup_calculator(Optimizer)
            if Optimizer.fixed_region:
                if debug:
                    logger.info('Setting up fixed region calculator')
                pms=copy.deepcopy(calc.parameters)
                try:
                    pms['mass'][len(pms['mass'])-1] += '\ngroup RO id >= {0}\nfix freeze RO setforce 0.0 0.0 0.0\n'.format(nat)
                except KeyError:
                    pms['pair_coeff'][0] += '\ngroup RO id >= {0}\nfix freeze RO setforce 0.0 0.0 0.0\n'.format(nat)
                calc = LAMMPS(parameters=pms, files=calc.files, keep_tmp_files=calc.keep_tmp_files, tmp_dir=calc.tmp_dir)
                lmin = copy.copy(Optimizer.lammps_min)
                if debug:
                    logger.info('Setting up no local minimization calculator')
                Optimizer.lammps_min = None
                Optimizer.static_calc = setup_calculator(Optimizer)
                Optimizer.lammps_min = lmin
        else:
            calc=Optimizer.calc
        totalsol.set_calculator(calc)
        totalsol.set_pbc(True)
        
        # Perform Energy Minimization
        if not Optimizer.parallel:
            if debug: 
                write_xyz(Optimizer.debugfile,totalsol,'Individual sent to Energy Minimizer')
                logger.debug('Writing structure sent to energy minimizer')
        try:
            cwd = os.getcwd()
            if Optimizer.ase_min == True:
                if debug:
                    logger.info('Running ASE minimizer')
                if Optimizer.calc_method=='LennardJones':
                    logger.warn('Must run ase LJ calculator with pbc=False')
                    totalsol.set_pbc(False)
                totalsol, energy, pressure, volume, STR = run_ase_min(totalsol, Optimizer.ase_min_fmax, Optimizer.ase_min_maxsteps, Optimizer.fitness_scheme, STR)
            else:
                if debug:
                    logger.info('Running local energy calculator')
                if Optimizer.fixed_region:
                    totalsol, energy, pressure, volume, STR = run_energy_eval(totalsol, Optimizer.calc_method, Optimizer.fixed_region, Optimizer.fitness_scheme, STR, Optimizer.static_calc)
                else:
                    totalsol, energy, pressure, volume, STR = run_energy_eval(totalsol, Optimizer.calc_method, False, Optimizer.fitness_scheme, STR)
        except Exception, e:
            logger.critical('Error in energy evaluation: {0}'.format(e), exc_info=True)
            path = os.path.join(cwd,'TroubledLammps')
            if not os.path.exists(path):
                os.mkdir(path)
            #Copy files over
            shutil.copyfile(calc.trajfile,os.path.join(path,os.path.basename(calc.trajfile)))
            shutil.copyfile(calc.infile,os.path.join(path,os.path.basename(calc.infile)))
            shutil.copyfile(calc.logfile,os.path.join(path,os.path.basename(calc.logfile)))
            shutil.copyfile(calc.datafile,os.path.join(path,os.path.basename(calc.datafile)))
            raise RuntimeError('{0}:{1}'.format(Exception,e))
        if not Optimizer.parallel:
            if debug:
                write_xyz(Optimizer.debugfile,totalsol,'Individual after Energy Minimization')
                Optimizer.debugfile.flush()
                logger.debug('Writing structure recieved from energy minimizer')
       
        # Separate structures into distinct pieces
        if Optimizer.structure=='Defect':
            if Optimizer.fixed_region==True or Optimizer.finddefects==False:
                if debug:
                    logger.info('Identifying atoms in defect structure based on ID')
                individ[0]=totalsol[0:nat]
                bul=totalsol[(nat):len(totalsol)]
                individ[0].set_cell(csize)
            else:
                if debug:
                    logger.info('Applying find defects scheme to identify R1 and R2 for Defect')
                if 'FD' in Optimizer.debug:
                    outt=find_defects(totalsol,Optimizer.solidbulk,Optimizer.sf,atomlistcheck=Optimizer.atomlist,trackvacs=Optimizer.trackvacs,trackswaps=Optimizer.trackswaps,debug=Optimizer.debugfile)
                else:
                    outt=find_defects(totalsol,Optimizer.solidbulk,Optimizer.sf,atomlistcheck=Optimizer.atomlist,trackvacs=Optimizer.trackvacs,trackswaps=Optimizer.trackswaps,debug=False)
                individ[0]=outt[0]
                bul=outt[1]
                individ.vacancies = outt[2]
                individ.swaps = outt[3]
                STR += outt[4]
            indiv=individ[0]
        elif Optimizer.structure=='Surface':
            if debug:
                logger.info('Finding surface top layer')
            top,bul=find_top_layer(totalsol,Optimizer.surftopthick)
            indiv=top.copy()
            individ[0]=top.copy()
            bul = Atoms()
        elif Optimizer.structure=='Crystal':
            if debug:
                logger.info('Checking crystal cell type')
            celltype = check_cell_type(totalsol)
            STR+='Cell structure = {0}\n'.format(celltype)
            bul = Atoms()
            individ[0] = totalsol.copy()
        elif Optimizer.structure=='Cluster':
            volume = get_cluster_volume(totalsol)
            bul = Atoms()
            if debug:
                logger.info('Translating cluster back to smaller box size location')
            totalsol.translate([-Optimizer.large_box_size/2.0,-Optimizer.large_box_size/2.0,-Optimizer.large_box_size/2.0])
            totalsol.set_cell(origcell)
            individ[0] = totalsol.copy()
        
        # Add concentration energy dependence
        if Optimizer.forcing=='energy_bias':
            if debug:
                logger.info('Applying energy bias for atoms with different number of atoms of type than in atomlist')
            n=[0]*len(Optimizer.atomlist)
            for i in range(len(Optimizer.atomlist)):
                n[i]=len([inds for inds in totalsol if inds.symbol==Optimizer.atomlist[i][0]])
                n[i]=abs(n[i]-Optimizer.atomlist[i][1])
            factor=sum(n)**3
            energy=(energy+factor)/totalsol.get_number_of_atoms()
            STR+='Energy with Bias = {0}\n'.format(energy)
        elif Optimizer.forcing=='chem_pot':
            if debug:
                logger.info('Applying chemical potential bias for atoms with different number of atoms of type than in atomlist')
            n=[0]*len(Optimizer.atomlist)
            for i in range(len(Optimizer.atomlist)):
                n[i]=len([inds for inds in totalsol if inds.symbol==Optimizer.atomlist[i][0]])
                n[i]=n[i]*Optimizer.atomlist[i][3]
            factor=sum(n)
            energy=(energy+factor)/totalsol.get_number_of_atoms()
            STR+='Energy with Chemical Potential = {0}\n'.format(energy)

        individ.energy=energy
        individ.buli=bul
        individ.pressure=pressure
        individ.volume=volume
    
        if Optimizer.fingerprinting:
            if debug:
                logger.info('Identifying fingerprint of new structure')
            individ.fingerprint=get_fingerprint(Optimizer,individ,Optimizer.fpbin,Optimizer.fpcutoff)
        if Optimizer.parallel:
            calc.clean()
            signal = 'Evaluated individual {0} on {1}\n'.format(individ.index,rank)
            signal +=STR
        else:
            signal=STR
Exemplo n.º 19
0
def randalloybox(ind1, ind2, Optimizer):
    """Select a box in the alloy configuration
    *** Note: CX may be obsolete. In development ***
    """
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    if Optimizer.structure != 'Defect':
        Optimizer.output.write(
            'WARNING: Box Random alloy Cx attempted on nondefect structure. SKIPPING CX.\n'
        )
    else:
        Optimizer.output.write('Box Random alloy Cx between individual ' +
                               repr(ind1.index) + ' and individual ' +
                               repr(ind2.index) + '\n')

        #Perserve starting conditions of individual
        indi1 = ind1[0].copy()
        indi2 = ind2[0].copy()
        cell1 = numpy.maximum.reduce(indi1.get_cell())
        cell2 = numpy.maximum.reduce(indi2.get_cell())
        cell = numpy.minimum(cell1, cell2)
        pbc1 = indi1.get_pbc()
        pbc2 = indi2.get_pbc()

        #Build solids
        solid1 = indi1.copy()
        solid1.extend(ind1.bulki.copy())
        solid2 = indi2.copy()
        solid2.extend(ind2.bulki.copy())

        #Get starting concentrations and number of atoms
        nat1 = len(solid1)
        nat2 = len(solid2)
        symlist = list(set(solid1.get_chemical_symbols()))
        #Assumes same types of atoms in both solid1 and solid2
        concent1 = []
        concent2 = []
        for one in symlist:
            atmss = [atm for atm in solid1 if atm.symbol == one]
            concent1.append(len(atmss))
            atmss = [atm for atm in solid2 if atm.symbol == one]
            concent2.append(len(atmss))

        # Pick a origin point for box in the cell
        #pt=[random.uniform(0,cell[0]),random.uniform(0,cell[1]),random.uniform(0,cell[2])]
        pt1 = solid1[0].position
        pt2 = solid2[0].position

        #Find max radius of circle cut
        r1 = min([
            min(cell1[0] - pt1[0], pt1[0]),
            min(cell1[1] - pt1[1], pt1[1]),
            min(cell1[2] - pt1[2], pt1[2])
        ])
        r2 = min([
            min(cell2[0] - pt2[0], pt2[0]),
            min(cell2[1] - pt2[1], pt2[1]),
            min(cell2[2] - pt2[2], pt2[2])
        ])
        r = min(r1, r2)
        mcell = min(cell)
        if r > mcell * 0.125:
            r = mcell * 0.125
        if debug:
            Optimizer.output.write('Radius of box = ' + repr(r) +
                                   '\nPosition in solid1 = ' + repr(pt1) +
                                   '\nPosition in solid2 = ' + repr(pt2) +
                                   '\n')

        #Find atoms within sphere of radius r
        solid1.append(Atom(position=pt1))
        dist1 = []
        blist1 = []
        for i in range(len(solid1) - 1):
            d = solid1.get_distance(i, len(solid1) - 1)
            if d < r:
                dist1.append((d, solid1[i]))
            else:
                blist1.append((d, solid1[i]))
        solid1.pop()

        solid2.append(Atom(position=pt2))
        dist2 = []
        blist2 = []
        for i in range(len(solid2) - 1):
            d = solid2.get_distance(i, len(solid2) - 1)
            if d < r:
                dist2.append((d, solid2[i]))
            else:
                blist2.append((d, solid2[i]))
        solid2.pop()

        #Translate spheres to opposite location
        dats1 = Atoms()
        for d, atm in dist1:
            dats1.append(atm)
        dats1.translate(-pt1)
        dats1.translate(pt2)
        dats2 = Atoms()
        for d, atm in dist2:
            dats2.append(atm)
        dats2.translate(-pt2)
        dats2.translate(pt1)

        #Exchange atoms in sphere and build new solids
        nsolid1 = dats2.copy()
        for d, atm in blist1:
            nsolid1.append(atm)
        nsolid2 = dats1.copy()
        for d, atm in blist2:
            nsolid2.append(atm)

        #Identify new number of atoms
        nnat1 = len(nsolid1)
        nnat2 = len(nsolid2)

        if nnat1 > nat1:
            ds = []
            #More atoms in new solid1 means solid2 has less atoms
            #Need to transfer atoms from solid1 to solid2
            #Find atoms that are too close
            for i in range(len(dist2)):
                for j in range(len(dist2), len(nsolid1)):
                    ds.append((nsolid1.get_distance(i, j), i))
            #Sort distances by longest to shortest
            ds = sorted(ds, key=lambda one: one[0])
            diff = nnat1 - nat1
            exchangeindices = []
            while len(exchangeindices) < diff:
                #Grab shortest distance in ds list
                d, index = ds.pop()
                if index not in exchangeindices:
                    exchangeindices.append(index)
            nnsolid1 = Atoms()
            for i in range(len(nsolid1)):
                if i not in exchangeindices:
                    nnsolid1.append(nsolid1[i])
            nnsolid2 = nsolid2.copy()
            for i in exchangeindices:
                #for j in range(3):
                #	position[j]=nsolid2[i].position[j]-pt1[j]+pt2[j]
                position = [
                    random.uniform(pt2[0] - r / (2**0.5),
                                   pt2[0] + r / (2**0.5)),
                    random.uniform(pt2[1] - r / (2**0.5),
                                   pt2[1] + r / (2**0.5)),
                    random.uniform(pt2[2] - r / (2**0.5),
                                   pt2[2] + r / (2**0.5))
                ]
                nnsolid2.append(
                    Atom(symbol=nsolid1[i].symbol, position=position))
            nsolid1 = nnsolid1.copy()
            nsolid2 = nnsolid2.copy()

        elif nnat1 < nat1:
            ds = []
            #More atoms in new solid2 means solid1 has less atoms
            #Need to transfer atoms from solid2 to solid1
            #Find atoms that are too close
            for i in range(len(dist1)):
                for j in range(len(dist1), len(nsolid2)):
                    ds.append((nsolid2.get_distance(i, j), i))
            #Sort distances by longest to shortest
            ds = sorted(ds, key=lambda one: one[0])
            diff = nnat2 - nat2
            exchangeindices = []
            while len(exchangeindices) < diff:
                #Grab shortest distance in ds list
                d, index = ds.pop()
                if index not in exchangeindices:
                    exchangeindices.append(index)
            nnsolid2 = Atoms()
            for i in range(len(nsolid2)):
                if i not in exchangeindices:
                    nnsolid2.append(nsolid2[i])
            nnsolid1 = nsolid1.copy()
            for i in exchangeindices:
                #for j in range(3):
                #	position[j]=nsolid2[i].position[j]-pt1[j]+pt2[j]
                position = [
                    random.uniform(pt1[0] - r / (2**0.5),
                                   pt1[0] + r / (2**0.5)),
                    random.uniform(pt1[1] - r / (2**0.5),
                                   pt1[1] + r / (2**0.5)),
                    random.uniform(pt1[2] - r / (2**0.5),
                                   pt1[2] + r / (2**0.5))
                ]
                nnsolid1.append(
                    Atom(symbol=nsolid2[i].symbol, position=position))
            nsolid1 = nnsolid1.copy()
            nsolid2 = nnsolid2.copy()

        #Number of atoms in each individual should now be preserved
        if Optimizer.forcing == 'Concentration':
            #Need to check concentrations
            nconcent1 = []
            for one in symlist:
                atmss = [atm for atm in nsolid1 if atm.symbol == one]
                nconcent1.append(len(atmss))
            nconcent2 = []
            for one in symlist:
                atmss = [atm for atm in nsolid2 if atm.symbol == one]
                nconcent2.append(len(atmss))
            #Let's assume a random perturbation to concentration in order to correct this issue
            posd = []
            negd = []
            for i in range(len(nconcent1)):
                diff = nconcent1[i] - concent1[i]
                if diff > 0:
                    posd.append((diff, symlist[i]))
                elif diff < 0:
                    negd.append((diff, symlist[i]))
            for c, sym in negd:
                while c != 0:
                    symr = posd[0][1]
                    rlist = [
                        atm.index for atm in nsolid1 if atm.symbol == symr
                    ]
                    index1 = random.choice(rlist)
                    nsolid1[index1].symbol = sym
                    c += 1
                    posd[0] = (posd[0][0] - 1, posd[0][1])
                    if posd[0][0] == 0:
                        posd = posd[1::]
            #Do the same for solid2
            posd = []
            negd = []
            for i in range(len(nconcent2)):
                diff = nconcent2[i] - concent2[i]
                if diff > 0:
                    posd.append((diff, symlist[i]))
                elif diff < 0:
                    negd.append((diff, symlist[i]))
            for c, sym in negd:
                while c != 0:
                    symr = posd[0][1]
                    rlist = [
                        atm.index for atm in nsolid2 if atm.symbol == symr
                    ]
                    index1 = random.choice(rlist)
                    nsolid2[index1].symbol = sym
                    c += 1
                    posd[0] = (posd[0][0] - 1, posd[0][1])
                    if posd[0][0] == 0:
                        posd = posd[1::]

        #DEBUG: Write crossover to file
        if debug:
            write_xyz(Optimizer.debugfile, nsolid1, 'CX(randalloybx):nsolid1')
            write_xyz(Optimizer.debugfile, nsolid2, 'CX(randalloybx):nsolid2')

        #DEBUG: Check structure of atoms exchanged
        for sym, c, m, u in Optimizer.atomlist:
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            Optimizer.output.write('CX(randalloybx):New solid1 contains ' +
                                   repr(nc) + ' ' + repr(sym) + ' atoms\n')
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            Optimizer.output.write('CX(randalloybx):New solid2 contains ' +
                                   repr(nc) + ' ' + repr(sym) + ' atoms\n')
        if Optimizer.forcing != 'Concentration':
            for i in range(len(Optimizer.atomlist)):
                atms1 = [
                    inds for inds in nsolid1
                    if inds.symbol == Optimizer.atomlist[i][0]
                ]
                atms2 = [
                    inds for inds in nsolid2
                    if inds.symbol == Optimizer.atomlist[i][0]
                ]
                if len(atms1) == 0:
                    if len(atms2) == 0:
                        nsolid1[random.randint(
                            0,
                            len(indi1) - 1)].symbol = Optimizer.atomlist[i][0]
                        nsolid2[random.randint(
                            0,
                            len(indi2) - 1)].symbol = Optimizer.atomlist[i][0]
                    else:
                        nsolid1.append(atms2[random.randint(0,
                                                            len(atms2) - 1)])
                        nsolid1.pop(random.randint(0, len(nsolid1) - 2))
                else:
                    if len(atms2) == 0:
                        nsolid2.append(atms1[random.randint(0,
                                                            len(atms1) - 1)])
                        nsolid2.pop(random.randint(0, len(nsolid2) - 2))

        nsolid1.set_cell(cell1)
        nsolid2.set_cell(cell2)
        nsolid1.set_pbc(pbc1)
        nsolid2.set_pbc(pbc2)

        outs = find_defects(nsolid1,
                            Optimizer.solidbulk,
                            Optimizer.sf,
                            atomlistcheck=Optimizer.atomlist,
                            trackvacs=Optimizer.trackvacs,
                            trackswaps=Optimizer.trackswaps,
                            debug=False)
        ind1[0] = outs[0].copy()
        ind1.bulki = outs[1].copy()
        ind1.vacancies = outs[2].copy()
        ind1.swaps = outs[3].copy()
        outs = find_defects(nsolid2,
                            Optimizer.solidbulk,
                            Optimizer.sf,
                            atomlistcheck=Optimizer.atomlist,
                            trackvacs=Optimizer.trackvacs,
                            trackswaps=Optimizer.trackswaps,
                            debug=False)
        ind2[0] = outs[0].copy()
        ind2.bulki = outs[1].copy()
        ind2.vacancies = outs[2].copy()
        ind2.swaps = outs[3].copy()

    return ind1, ind2
Exemplo n.º 20
0
def randalloybox(ind1, ind2, Optimizer):
    """Select a box in the alloy configuration
    *** Note: CX may be obsolete. In development ***
    """
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    if Optimizer.structure != 'Defect':
        Optimizer.output.write('WARNING: Box Random alloy Cx attempted on nondefect structure. SKIPPING CX.\n')
    else:
        Optimizer.output.write('Box Random alloy Cx between individual '+repr(ind1.index)+' and individual '+repr(ind2.index)+'\n')
    
        #Perserve starting conditions of individual
        indi1 = ind1[0].copy()
        indi2 = ind2[0].copy()
        cell1 = numpy.maximum.reduce(indi1.get_cell())
        cell2 = numpy.maximum.reduce(indi2.get_cell())
        cell = numpy.minimum(cell1,cell2)
        pbc1 = indi1.get_pbc()
        pbc2 = indi2.get_pbc()

        #Build solids
        solid1 = indi1.copy()
        solid1.extend(ind1.bulki.copy())
        solid2 = indi2.copy()
        solid2.extend(ind2.bulki.copy())

        #Get starting concentrations and number of atoms
        nat1 = len(solid1)
        nat2 = len(solid2)
        symlist = list(set(solid1.get_chemical_symbols()))
        #Assumes same types of atoms in both solid1 and solid2
        concent1 = []
        concent2 = []
        for one in symlist:
            atmss = [atm for atm in solid1 if atm.symbol==one]
            concent1.append(len(atmss))
            atmss = [atm for atm in solid2 if atm.symbol==one]
            concent2.append(len(atmss))

        # Pick a origin point for box in the cell
        #pt=[random.uniform(0,cell[0]),random.uniform(0,cell[1]),random.uniform(0,cell[2])]
        pt1 = solid1[0].position
        pt2 = solid2[0].position

        #Find max radius of circle cut
        r1 = min([min(cell1[0]-pt1[0],pt1[0]),min(cell1[1]-pt1[1],pt1[1]),min(cell1[2]-pt1[2],pt1[2])])
        r2 = min([min(cell2[0]-pt2[0],pt2[0]),min(cell2[1]-pt2[1],pt2[1]),min(cell2[2]-pt2[2],pt2[2])])
        r = min(r1,r2)
        mcell = min(cell)
        if r > mcell*0.125:
            r = mcell*0.125
        if debug:
            Optimizer.output.write('Radius of box = '+repr(r)+'\nPosition in solid1 = '+repr(pt1)+'\nPosition in solid2 = '+repr(pt2)+'\n')

        #Find atoms within sphere of radius r
        solid1.append(Atom(position=pt1))
        dist1 = []
        blist1 = []
        for i in range(len(solid1)-1):
            d = solid1.get_distance(i,len(solid1)-1)
            if d < r:
                dist1.append((d,solid1[i]))
            else:
                blist1.append((d,solid1[i]))
        solid1.pop()

        solid2.append(Atom(position=pt2))
        dist2 = []
        blist2 = []
        for i in range(len(solid2)-1):
            d = solid2.get_distance(i,len(solid2)-1)
            if d < r:
                dist2.append((d,solid2[i]))
            else:
                blist2.append((d,solid2[i]))
        solid2.pop()

        #Translate spheres to opposite location
        dats1 = Atoms()
        for d,atm in dist1:
            dats1.append(atm)
        dats1.translate(-pt1)
        dats1.translate(pt2)
        dats2 = Atoms()
        for d,atm in dist2:
            dats2.append(atm)
        dats2.translate(-pt2)
        dats2.translate(pt1)

        #Exchange atoms in sphere and build new solids
        nsolid1 = dats2.copy()
        for d,atm in blist1:
            nsolid1.append(atm)
        nsolid2 = dats1.copy()
        for d,atm in blist2:
            nsolid2.append(atm)

        #Identify new number of atoms
        nnat1 = len(nsolid1)
        nnat2 = len(nsolid2)

        if nnat1 > nat1:
            ds = []
            #More atoms in new solid1 means solid2 has less atoms
            #Need to transfer atoms from solid1 to solid2
            #Find atoms that are too close
            for i in range(len(dist2)):
                for j in range(len(dist2),len(nsolid1)):
                    ds.append((nsolid1.get_distance(i,j),i))
            #Sort distances by longest to shortest
            ds = sorted(ds, key=lambda one:one[0])
            diff = nnat1-nat1
            exchangeindices = []
            while len(exchangeindices) < diff:
                #Grab shortest distance in ds list
                d, index = ds.pop()
                if index not in exchangeindices:
                    exchangeindices.append(index)
            nnsolid1 = Atoms()
            for i in range(len(nsolid1)):
                if i not in exchangeindices:
                    nnsolid1.append(nsolid1[i])
            nnsolid2 = nsolid2.copy()
            for i in exchangeindices:
                #for j in range(3):
                #	position[j]=nsolid2[i].position[j]-pt1[j]+pt2[j]
                position = [random.uniform(pt2[0]-r/(2**0.5),pt2[0]+r/(2**0.5)),random.uniform(pt2[1]-r/(2**0.5),pt2[1]+r/(2**0.5)),random.uniform(pt2[2]-r/(2**0.5),pt2[2]+r/(2**0.5))]
                nnsolid2.append(Atom(symbol=nsolid1[i].symbol, position=position))
            nsolid1 = nnsolid1.copy()
            nsolid2 = nnsolid2.copy()

        elif nnat1 < nat1:
            ds = []
            #More atoms in new solid2 means solid1 has less atoms
            #Need to transfer atoms from solid2 to solid1
            #Find atoms that are too close
            for i in range(len(dist1)):
                for j in range(len(dist1),len(nsolid2)):
                    ds.append((nsolid2.get_distance(i,j),i))
            #Sort distances by longest to shortest
            ds = sorted(ds, key=lambda one:one[0])
            diff = nnat2-nat2
            exchangeindices = []
            while len(exchangeindices) < diff:
                #Grab shortest distance in ds list
                d, index = ds.pop()
                if index not in exchangeindices:
                    exchangeindices.append(index)
            nnsolid2 = Atoms()
            for i in range(len(nsolid2)):
                if i not in exchangeindices:
                    nnsolid2.append(nsolid2[i])
            nnsolid1 = nsolid1.copy()
            for i in exchangeindices:
                #for j in range(3):
                #	position[j]=nsolid2[i].position[j]-pt1[j]+pt2[j]
                position = [random.uniform(pt1[0]-r/(2**0.5),pt1[0]+r/(2**0.5)),random.uniform(pt1[1]-r/(2**0.5),pt1[1]+r/(2**0.5)),random.uniform(pt1[2]-r/(2**0.5),pt1[2]+r/(2**0.5))]
                nnsolid1.append(Atom(symbol=nsolid2[i].symbol, position=position))
            nsolid1 = nnsolid1.copy()
            nsolid2 = nnsolid2.copy()

        #Number of atoms in each individual should now be preserved
        if Optimizer.forcing=='Concentration':
            #Need to check concentrations
            nconcent1 = []
            for one in symlist:
                atmss = [atm for atm in nsolid1 if atm.symbol==one]
                nconcent1.append(len(atmss))
            nconcent2 = []
            for one in symlist:
                atmss = [atm for atm in nsolid2 if atm.symbol==one]
                nconcent2.append(len(atmss))
            #Let's assume a random perturbation to concentration in order to correct this issue
            posd = []
            negd = []
            for i in range(len(nconcent1)):
                diff = nconcent1[i]-concent1[i]
                if diff >0:
                    posd.append((diff,symlist[i]))
                elif diff<0:
                    negd.append((diff,symlist[i]))
            for c,sym in negd:
                while c !=0:
                    symr = posd[0][1]
                    rlist = [atm.index for atm in nsolid1 if atm.symbol==symr]
                    index1 = random.choice(rlist)
                    nsolid1[index1].symbol=sym
                    c += 1
                    posd[0] = (posd[0][0]-1,posd[0][1])
                    if posd[0][0]==0:
                        posd = posd[1::]
            #Do the same for solid2
            posd = []
            negd = []
            for i in range(len(nconcent2)):
                diff = nconcent2[i]-concent2[i]
                if diff >0:
                    posd.append((diff,symlist[i]))
                elif diff<0:
                    negd.append((diff,symlist[i]))
            for c,sym in negd:
                while c !=0:
                    symr = posd[0][1]
                    rlist = [atm.index for atm in nsolid2 if atm.symbol==symr]
                    index1 = random.choice(rlist)
                    nsolid2[index1].symbol=sym
                    c += 1
                    posd[0] = (posd[0][0]-1,posd[0][1])
                    if posd[0][0]==0:
                        posd = posd[1::]

        #DEBUG: Write crossover to file
        if debug: 
            write_xyz(Optimizer.debugfile, nsolid1,'CX(randalloybx):nsolid1')
            write_xyz(Optimizer.debugfile, nsolid2,'CX(randalloybx):nsolid2')

        #DEBUG: Check structure of atoms exchanged
        for sym,c,m,u in Optimizer.atomlist:
                nc = len([atm for atm in nsolid1 if atm.symbol==sym])
                Optimizer.output.write('CX(randalloybx):New solid1 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
                nc = len([atm for atm in nsolid2 if atm.symbol==sym])
                Optimizer.output.write('CX(randalloybx):New solid2 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
        if Optimizer.forcing !='Concentration':
            for i in range(len(Optimizer.atomlist)):
                atms1 = [inds for inds in nsolid1 if inds.symbol==Optimizer.atomlist[i][0]]
                atms2 = [inds for inds in nsolid2 if inds.symbol==Optimizer.atomlist[i][0]]
                if len(atms1)==0:
                    if len(atms2)==0:
                        nsolid1[random.randint(0,len(indi1)-1)].symbol = Optimizer.atomlist[i][0]
                        nsolid2[random.randint(0,len(indi2)-1)].symbol = Optimizer.atomlist[i][0]
                    else:
                        nsolid1.append(atms2[random.randint(0,len(atms2)-1)])
                        nsolid1.pop(random.randint(0,len(nsolid1)-2))
                else:
                    if len(atms2)==0:
                        nsolid2.append(atms1[random.randint(0,len(atms1)-1)])
                        nsolid2.pop(random.randint(0,len(nsolid2)-2))	

        nsolid1.set_cell(cell1)
        nsolid2.set_cell(cell2)
        nsolid1.set_pbc(pbc1)
        nsolid2.set_pbc(pbc2)

        outs = find_defects(nsolid1,Optimizer.solidbulk,Optimizer.sf,atomlistcheck=Optimizer.atomlist,trackvacs=Optimizer.trackvacs,trackswaps=Optimizer.trackswaps,debug=False)
        ind1[0] = outs[0].copy()
        ind1.bulki = outs[1].copy()
        ind1.vacancies = outs[2].copy()
        ind1.swaps = outs[3].copy()
        outs = find_defects(nsolid2,Optimizer.solidbulk,Optimizer.sf,atomlistcheck=Optimizer.atomlist,trackvacs=Optimizer.trackvacs,trackswaps=Optimizer.trackswaps,debug=False)
        ind2[0] = outs[0].copy()
        ind2.bulki = outs[1].copy()
        ind2.vacancies = outs[2].copy()
        ind2.swaps = outs[3].copy()
    
    return ind1, ind2
Exemplo n.º 21
0
def lattice_alteration_nn(indiv, Optimizer):
    """Move function to perform random move along random axis for nearest neighbor distance to random atoms
    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:
            indc,indb,vacant,swaps,stro = find_defects(indiv[0],Optimizer.solidbulk,0)
            ind = indc.copy()
            ind.extend(indb)
        else:
            ind=indiv[0].copy()
            indc=indiv[0].copy()
    else:
        ind=indiv[0].copy()
        indc=indiv[0].copy()
    if len(indc) != 0:
        ctoff1 = [1.0 for one in ind]
        nl = NeighborList(ctoff1, bothways=True, self_interaction=False)
        nl.update(ind)
        try:
            natomsmove=random.randint(1,len(indc)/2)
        except ValueError:
            natomsmove=1
        passn=0
        for count in range(natomsmove):
            try:
                indexmv = random.choice([i for i in range(len(indc))])
                indices, offsets = nl.get_neighbors(indexmv)
                nns = Atoms()
                nns.append(ind[indexmv])
                for index, d in zip(indices,offsets):
                    index = int(index)
                    pos = ind[index].position + numpy.dot(d,ind.get_cell())
                    nns.append(Atom(symbol=ind[index].symbol, position=pos))
                dist = [nns.get_distance(0,i) for i in range(1, len(nns))]
                r = sum(dist)/len(dist)
                dir = random.choice([[1,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]])
                ind[indexmv].position += [i*r for i in dir]
            except:
                passn+=1
        indiv[0]=ind.copy()
    else:
        natomsmove=0
        passn=0
    Optimizer.output.write('Lattice Alteration NN Mutation performed on individual\n')
    Optimizer.output.write('Index = '+repr(indiv.index)+'\n')
    natomsmove-=passn
    Optimizer.output.write('Number of atoms moved = '+repr(natomsmove)+'\n')
    Optimizer.output.write(repr(indiv[0])+'\n')
    muttype='LANN'+repr(natomsmove)
    if indiv.energy==0:
        indiv.history_index=indiv.history_index+'m'+muttype
    else:
        indiv.history_index=repr(indiv.index)+'m'+muttype
    return indiv
Exemplo n.º 22
0
Arquivo: sibias.py Projeto: m-yu/MAST
     indiv.energy = 10000
     f.close()
     print '    Writing structure to problemstructures.xyz file. Structure (hindex) : '+indiv.history_index
     print '    Setting individual energy to 50000.'
     outs = [10000, starting.bulki, starting, stro]
 indiv = outs[2]
 indiv.energy = outs[0]
 stro=outs[3]
 if Optimizer.structure == 'Defect' or Optimizer.structure=='Surface':
     indiv.bulki = outs[1]
 indiv.fitness = indiv.energy
 if abs(indiv.fitness) > Optimizer.energy_cutoff_factor*(len(indiv[0])+len(indiv.bulki)):
     indiv.fitness=10000
     message = 'Warning: Found oddly large energy from Lammps in structure HI={0}'.format(indiv.history_index)
     logger.warn(message)
     print message
     print '    Setting fitness to 10000'
 if math.isnan(indiv.fitness):
     logger.warn('Found NAN energy structure HI={0}'.format(indiv.history_index))
     indiv.fitness=10000
     indiv.energy = 10000
 indc,indb,vacant,swap,stro = find_defects(indiv[0],Optimizer.solidbulk,0)
 syms = indc.get_chemical_symbols()
 for sym in syms:
     if sym=='Si':
         message = 'Identified Si atom in defect added energy bias +50eV'
         logger.info(message)
         stro+='    '+message+'\n'
         indiv.fitness+=50
         indiv.energy+=50
 return indiv, stro
Exemplo n.º 23
0
     indiv.bulki = outs[1]
 indiv.fitness = indiv.energy
 if abs(indiv.fitness) > Optimizer.energy_cutoff_factor * (
         len(indiv[0]) + len(indiv.bulki)):
     indiv.fitness = 10000
     message = 'Warning: Found oddly large energy from Lammps in structure HI={0}'.format(
         indiv.history_index)
     logger.warn(message)
     print message
     print '    Setting fitness to 10000'
 if math.isnan(indiv.fitness):
     logger.warn('Found NAN energy structure HI={0}'.format(
         indiv.history_index))
     indiv.fitness = 10000
     indiv.energy = 10000
 indc, indb, vacant, swap, stro = find_defects(indiv[0],
                                               Optimizer.solidbulk, 0)
 syms = indc.get_chemical_symbols()
 for sym in syms:
     if sym == 'Si':
         message = 'Identified Si atom in defect added energy bias +50eV'
         logger.info(message)
         stro += '    ' + message + '\n'
         indiv.fitness += 50
         indiv.energy += 50
 nindiv = Atoms(cell=indiv[0].get_cell(), pbc=True)
 nbulk = indiv.bulki.copy()
 for at in indiv[0]:
     if at.symbol == 'Si':
         nbulk.append(at)
     else:
         nindiv.append(at)
Exemplo n.º 24
0
def rotation(indiv, Optimizer):
    """Move function to perform rotation of a group of atoms
    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]
    else:
        atms = indiv[0]
    nat = len(atms)
    if nat != 0:
        if nat <= 1:
            natrot2 = 1
            natrot1 = 0
        elif nat <= 6:
            natrot2 = 2
            natrot1 = 0
        else:
            natrot1 = random.randint(1, nat / 2)
            natrot2 = random.randint(2, (nat - 1) / 2)
            if natrot2 >= natrot1:
                natrot2 += 1
            else:
                natrot1, natrot2 = natrot2, natrot1
        natrot = natrot2 - natrot1
        atmsr = atms[natrot1:natrot2]
        del atms[natrot1:natrot2]
        ax = ['x', '-x', 'y', '-y', 'z', '-z']
        rax = ax[random.randint(0, len(ax) - 1)]
        rang = random.uniform(30, 180)
        #rang=random.random()*90
        atmsr.rotate(rax, a=rang, center='COM', rotate_cell=False)
        atms.extend(atmsr)
        if Optimizer.structure == 'Defect':
            if Optimizer.isolate_mutation:
                atms.extend(indb)
        indiv[0] = atms.copy()
    else:
        natrot = 0
        rax = 0
        rang = 0
    Optimizer.output.write('Rotation Mutation performed on individual\n')
    Optimizer.output.write('Index = ' + repr(indiv.index) + '\n')
    Optimizer.output.write('Number of atoms rotated = ' + repr(natrot) + '\n')
    Optimizer.output.write('Rotation vector = ' + repr(rax) + '\n')
    Optimizer.output.write('Rotation angle = ' + repr(rang) + '\n')
    Optimizer.output.write(repr(indiv[0]) + '\n')
    muttype = 'R' + repr(natrot)
    if indiv.energy == 0:
        indiv.history_index = indiv.history_index + 'm' + muttype
    else:
        indiv.history_index = repr(indiv.index) + 'm' + muttype
    return indiv
Exemplo n.º 25
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
Exemplo n.º 26
0
def eval_energy(input):
    """Function to evaluate energy of an individual
    Inputs:
        input = [Optimizer class object with parameters, Individual class structure to be evaluated]
    Outputs:
        energy, bul, individ, signal
        energy = energy of Individual evaluated
        bul = bulk structure of Individual if simulation structure is Defect
        individ = Individual class structure evaluated
        signal = string of information about evaluation
    """
    if input[0]==None:
        energy=0
        bul=0
        individ=0
        rank = MPI.COMM_WORLD.Get_rank()
        signal='Evaluated none individual on '+repr(rank)+'\n'
    else:
        [Optimizer, individ]=input
    if Optimizer.calc_method=='MAST':
        energy = individ.energy
        bul = individ.energy
        signal = 'Recieved MAST structure\n'
    else:
        if Optimizer.parallel: rank = MPI.COMM_WORLD.Get_rank()
        if not Optimizer.genealogy:
            STR='----Individual ' + str(individ.index)+ ' Optimization----\n'
        else:
            STR='----Individual ' + str(individ.history_index)+ ' Optimization----\n'
        indiv=individ[0]
        if 'EE' in Optimizer.debug:
            debug = True
        else:
            debug = False
        if debug: 
            write_xyz(Optimizer.debugfile,indiv,'Recieved by eval_energy')
            Optimizer.debugfile.flush()
        if Optimizer.structure=='Defect':
            indi=indiv.copy()
            if Optimizer.alloy==True:
                bulk=individ.bulki
            else:
                bulk=individ.bulko
            nat=indi.get_number_of_atoms()
            csize=bulk.get_cell()                                                                                                         
            totalsol=Atoms(cell=csize, pbc=True)
            totalsol.extend(indi)
            totalsol.extend(bulk)
            for sym,c,m,u in Optimizer.atomlist:
                nc=len([atm for atm in totalsol if atm.symbol==sym])
                STR+='Defect configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n'
    
        elif Optimizer.structure=='Surface':
            totalsol=Atoms()
            totalsol.extend(indiv)
            nat=indiv.get_number_of_atoms()
            totalsol.extend(individ.bulki)
            for sym,c,m,u in Optimizer.atomlist:
                nc=len([atm for atm in totalsol if atm.symbol==sym])
                STR+='Surface-Bulk configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n'
            cell=numpy.maximum.reduce(indiv.get_cell())
            totalsol.set_cell([cell[0],cell[1],500])
            totalsol.set_pbc([True,True,False])
    
        if Optimizer.constrain_position:
            ts = totalsol.copy()
            indc,indb,vacant,swap,stro = find_defects(ts,Optimizer.solidbulk,0)
            sbulk = Optimizer.solidbulk.copy()
            bcom = sbulk.get_center_of_mass()
            #totalsol.translate(-bulkcom)
            #indc.translate(-bulkcom)
            #totalsol.append(Atom(position=[0,0,0]))
    # 			for one in indc:
    # 				index = [atm.index for atm in totalsol if atm.position[0]==one.position[0] and atm.position[1]==one.position[1] and atm.position[2]==one.position[2]][0]
    # 				if totalsol.get_distance(-1,index) > Optimizer.sf:
    # 					r = random.random()
    # 					totalsol.set_distance(-1,index,Optimizer.sf*r,fix=0)
    # 			totalsol.pop()
    # 			totalsol.translate(bulkcom)
            com = indc.get_center_of_mass()
            dist = (sum((bcom[i] - com[i])**2 for i in range(3)))**0.5
            if dist > Optimizer.sf:
                STR+='Shifting structure to within region\n'
                r = random.random()*Optimizer.sf
                comv = numpy.linalg.norm(com)
                ncom = [one*r/comv for one in com]
                trans = [ncom[i]-com[i] for i in range(3)]
                indices = []
                for one in indc:
                    id = [atm.index for atm in totalsol if atm.position[0]==one.position[0] and atm.position[1]==one.position[1] and atm.position[2]==one.position[2]][0]
                    totalsol[id].position += trans
    
        # Check for atoms that are too close
        min_len=0.7
        #pdb.set_trace()
        if not Optimizer.fixed_region:
            if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
                cutoffs=[2.0 for one in totalsol]
                nl=NeighborList(cutoffs,bothways=True,self_interaction=False)
                nl.update(totalsol)
                for one in totalsol[0:nat]:
                    nbatoms=Atoms()
                    nbatoms.append(one)
                    indices, offsets=nl.get_neighbors(one.index)
                    for index, d in zip(indices,offsets):
                        index = int(index)
                        sym=totalsol[index].symbol
                        pos=totalsol[index].position + numpy.dot(d,totalsol.get_cell())
                        at=Atom(symbol=sym,position=pos)
                        nbatoms.append(at)
                    while True:
                        dflag=False
                        for i in range(1,len(nbatoms)):
                            d=nbatoms.get_distance(0,i)
                            if d < min_len:
                                nbatoms.set_distance(0,i,min_len+.01,fix=0.5)
                                STR+='--- WARNING: Atoms too close (<0.7A) - Implement Move ---\n'
                                dflag=True
                        if dflag==False:
                            break
                    for i in range(len(indices)):
                        totalsol[indices[i]].position=nbatoms[i+1].position
                    totalsol[one.index].position=nbatoms[0].position
                    nl.update(totalsol)
                if debug:
                    write_xyz(Optimizer.debugfile,totalsol,'After minlength check')
                    Optimizer.debugfile.flush()
            else:
                for i in range(len(indiv)):
                    for j in range(len(indiv)):
                        if i != j:
                            d=indiv.get_distance(i,j)
                            if d < min_len:
                                indiv.set_distance(i,j,min_len,fix=0.5)
                                STR+='--- WARNING: Atoms too close (<0.7A) - Implement Move ---\n'
                if debug:
                    write_xyz(Optimizer.debugfile,indiv,'After minlength check')
                    Optimizer.debugfile.flush()
    
        # Set calculator to use to get forces/energies
        if Optimizer.parallel:
            calc = setup_calculator(Optimizer)
            if Optimizer.fixed_region:
                pms=copy.deepcopy(calc.parameters)
                try:
                    pms['mass'][len(pms['mass'])-1] += '\ngroup RO id >= '+repr(nat)+'\nfix freeze RO setforce 0.0 0.0 0.0\n'
                except KeyError:
                    pms['pair_coeff'][0] += '\ngroup RO id >= '+repr(nat)+'\nfix freeze RO setforce 0.0 0.0 0.0\n'
                calc = LAMMPS(parameters=pms, files=calc.files, keep_tmp_files=calc.keep_tmp_files, tmp_dir=calc.tmp_dir)
                lmin = copy.copy(Optimizer.lammps_min)
                Optimizer.lammps_min = None
                Optimizer.static_calc = setup_calculator(Optimizer)
                Optimizer.lammps_min = lmin
        else:
            calc=Optimizer.calc
        if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
            totalsol.set_calculator(calc)
            totalsol.set_pbc(True)
        else:
            indiv.set_calculator(calc)
            indiv.set_pbc(True)	#Current bug in ASE optimizer-Lammps prevents pbc=false 
            if Optimizer.structure=='Cluster':
                indiv.set_cell([500,500,500])
                indiv.translate([250,250,250])
    
        cwd=os.getcwd()
        # Perform Energy Minimization
        if not Optimizer.parallel:
            Optimizer.output.flush()
        if Optimizer.ase_min == True:
            try:
                if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
                    dyn=BFGS(totalsol)
                else:
                    dyn=BFGS(indiv)
                dyn.run(fmax=Optimizer.ase_min_fmax, steps=Optimizer.ase_min_maxsteps)
            except OverflowError:
                STR+='--- Error: Infinite Energy Calculated - Implement Random ---\n'
                box=Atoms()
                indiv=gen_pop_box(Optimizer.natoms, Optimizer.atomlist, Optimizer.size)
                indiv.set_calculator(calc)
                dyn=BFGS(indiv)
                dyn.run(fmax=fmax, steps=steps)
            except numpy.linalg.linalg.LinAlgError:
                STR+='--- Error: Singular Matrix - Implement Random ---\n'
                indiv=gen_pop_box(Optimizer.natoms, Optimizer.atomlist, Optimizer.size)
                indiv.set_calculator(calc)
                dyn=BFGS(indiv)
                dyn.run(fmax=fmax, steps=steps)
            # Get Energy of Minimized Structure
            if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
                en=totalsol.get_potential_energy()
                #force=numpy.maximum.reduce(abs(totalsol.get_forces()))
                if Optimizer.fitness_scheme == 'enthalpyfit':
                    pressure=totalsol.get_isotropic_pressure(totalsol.get_stress())
                    cell_max=numpy.maximum.reduce(totalsol.get_positions())
                    cell_min=numpy.minimum.reduce(totalsol.get_positions())
                    cell=cell_max-cell_min
                    volume=cell[0]*cell[1]*cell[2]
                else:
                    pressure=0
                    volume=0
                na=totalsol.get_number_of_atoms()
                ena=en/na
                energy=en
                individ[0]=totalsol[0:nat]
                bul=totalsol[(nat):len(totalsol)]
                STR+='Number of positions = '+repr(len(bul)+len(individ[0]))+'\n'
                individ[0].set_cell(csize)
                indiv=individ[0]
            else:
                en=indiv.get_potential_energy()
                if Optimizer.fitness_scheme == 'enthalpyfit':
                    pressure=indiv.get_isotropic_pressure(indiv.get_stress())
                    cell_max=numpy.maximum.reduce(indiv.get_positions())
                    cell_min=numpy.minimum.reduce(indiv.get_positions())
                    cell=cell_max-cell_min
                    volume=cell[0]*cell[1]*cell[2]
                else: 
                    pressure=0
                    volume=0
                na=indiv.get_number_of_atoms()
                ena=en/na
                energy=ena
                individ[0]=indiv
                bul=0
        else:
            if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
                if Optimizer.calc_method=='VASP':
                    en=totalsol.get_potential_energy()
                    calcb=Vasp(restart=True)
                    totalsol=calcb.get_atoms()
                    stress=calcb.read_stress()
                else:
                    try:
                        totcop=totalsol.copy()
                        if debug: write_xyz(Optimizer.debugfile,totcop,'Individual sent to lammps')
                        OUT=totalsol.calc.calculate(totalsol)
                        totalsol=OUT['atoms']
                        totalsol.set_pbc(True)
                        if Optimizer.fixed_region:
                            if debug:
                                print 'Energy of fixed region calc = ', OUT['thermo'][-1]['pe']
                            totalsol.set_calculator(Optimizer.static_calc)
                            OUT=totalsol.calc.calculate(totalsol)
                            totalsol=OUT['atoms']
                            totalsol.set_pbc(True)
                            if debug:
                                print 'Energy of static calc = ', OUT['thermo'][-1]['pe']
                        en=OUT['thermo'][-1]['pe']
                        stress=numpy.array([OUT['thermo'][-1][i] for i in ('pxx','pyy','pzz','pyz','pxz','pxy')])*(-1e-4*GPa)
                        #force=numpy.maximum.reduce(abs(totalsol.get_forces()))
                        if debug:
                            write_xyz(Optimizer.debugfile,totalsol,'After Lammps Minimization')
                            Optimizer.debugfile.flush()
                    except Exception, e:
                        os.chdir(cwd)
                        STR+='WARNING: Exception during energy eval:\n'+repr(e)+'\n'
                        f=open('problem-structures.xyz','a')
                        write_xyz(f,totcop,data='Starting structure hindex='+individ.history_index)
                        write_xyz(f,totalsol,data='Lammps Min structure')
                        en=10
                        stress=0
                        f.close()
                if Optimizer.fitness_scheme == 'enthalpyfit':
                    pressure=totalsol.get_isotropic_pressure(stress)
                    cell_max=numpy.maximum.reduce(totalsol.get_positions())
                    cell_min=numpy.minimum.reduce(totalsol.get_positions())
                    cell=cell_max-cell_min
                    volume=cell[0]*cell[1]*cell[2]
                else:
                    pressure=totalsol.get_isotropic_pressure(stress)
                    volume=0
                na=totalsol.get_number_of_atoms()
                ena=en/na
                energy=en
                if Optimizer.structure=='Defect':
                    if Optimizer.fixed_region==True or Optimizer.finddefects==False:
                        individ[0]=totalsol[0:nat]
                        bul=totalsol[(nat):len(totalsol)]
                        individ[0].set_cell(csize)
                    else:
                        if 'FI' in Optimizer.debug:
                            outt=find_defects(totalsol,Optimizer.solidbulk,Optimizer.sf,atomlistcheck=Optimizer.atomlist,trackvacs=Optimizer.trackvacs,trackswaps=Optimizer.trackswaps,debug=Optimizer.debugfile)
                        else:
                            outt=find_defects(totalsol,Optimizer.solidbulk,Optimizer.sf,atomlistcheck=Optimizer.atomlist,trackvacs=Optimizer.trackvacs,trackswaps=Optimizer.trackswaps,debug=False)
                        individ[0]=outt[0]
                        bul=outt[1]
                        individ.vacancies = outt[2]
                        individ.swaps = outt[3]
                        STR += outt[4]
                    indiv=individ[0]
                else:
                    top,bul=find_top_layer(totalsol,Optimizer.surftopthick)
                    indiv=top.copy()
                    individ[0]=top.copy()
            else:
Exemplo n.º 27
0
def rotct_rand_defect(ind1, ind2, Optimizer):
    """Rotate atoms cut and splice
    Translates atoms to center of positions first
    Rotates atoms randomly around center of mass and cuts with xy plane
    Maintains number of atoms
    Maintains concentration of atoms
    Returns individuals to standard positions at end (un-rotates)
    """
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write(
        'Random Rotate Cut/Splice Cx for defects between individual ' +
        repr(ind1.index) + ' and individual ' + repr(ind2.index) + '\n')

    #Perserve starting conditions of individual
    indi1 = ind1[0].copy()
    indi2 = ind2[0].copy()
    #Translate individuals so COP is at (0,0,0)
    if Optimizer.structure == 'Defect':
        #Identify center of positions for defect structure
        indi1c, indi1b, vacant1, swap1, stro1 = find_defects(
            indi1, Optimizer.solidbulk, 0)
        com1 = position_average(indi1c)
        indi1 = shift_atoms(indi1, com1)
        #Do the same for second individual
        indi2c, indi2b, vacant2, swap2, stro2 = find_defects(
            indi2, Optimizer.solidbulk, 0)
        com2 = position_average(indi2c)
        indi2 = shift_atoms(indi2, com2)
    else:
        com1 = indi1.get_center_of_mass()
        indi1.translate(-1 * com1)
        com2 = indi2.get_center_of_mass()
        indi2.translate(-1 * com2)
    #Select random axis, random angle, and random position and rotate individuals
    cmax = [
        min(
            numpy.maximum.reduce(indi1.get_positions())[i],
            numpy.maximum.reduce(indi2.get_positions())[i]) for i in range(3)
    ]
    cmin = [
        min(
            numpy.minimum.reduce(indi1.get_positions())[i],
            numpy.minimum.reduce(indi2.get_positions())[i]) for i in range(3)
    ]
    n = 0
    while n < 10:
        rax = random.choice(['x', '-x', 'y', '-y', 'z', '-z'])
        rang = random.random() * 90
        rpos = [random.uniform(cmin[i] * 0.8, cmax[i] * 0.8) for i in range(3)]
        indi1.rotate(rax, a=rang, center=rpos, rotate_cell=False)
        #Search for atoms in individual 1 that are above the xy plane
        group1 = Atoms(cell=ind1[0].get_cell(), pbc=ind1[0].get_pbc())
        indices1 = []
        for one in indi1:
            if one.position[2] >= 0:
                group1.append(one)
                indices1.append(one.index)
        if len(group1) > 2 and len(group1) < len(indi1):
            break
        else:
            n += 1
            indi1.rotate(rax, a=-1 * rang, center=rpos, rotate_cell=False)
    indi2.rotate(rax, a=rang, center=rpos, rotate_cell=False)
    if debug:
        print 'Group1 size = ', len(group1)
        print 'Position = ', rpos
        print 'Angle = ', rang
        print 'Axis = ', rax
        print 'Number of tries = ', n
    if len(group1) != 0:
        #Apply concentration forcing if needed
        group2 = Atoms(cell=ind2[0].get_cell(), pbc=ind2[0].get_pbc())
        indices2 = []
        dellist = []
        for one in indi2:
            if one.position[2] >= 0:
                group2.append(one)
                indices2.append(one.index)
        if Optimizer.forcing == 'Concentration':
            symlist = list(set(indi1.get_chemical_symbols()))
            seplist = [[atm for atm in group2 if atm.symbol == sym]
                       for sym in symlist]
            group2n = Atoms(cell=group2.get_cell(), pbc=group2.get_pbc())
            indices2n = []
            dellist = []
            for one in group1:
                sym1 = one.symbol
                listpos = [i for i, s in enumerate(symlist) if s == sym1][0]
                if len(seplist[listpos]) > 0:
                    pos = random.choice(range(len(seplist[listpos])))
                    group2n.append(seplist[listpos][pos])
                    indices2n.append(indices2[seplist[listpos][pos].index])
                    del seplist[listpos][pos]
                else:
                    dellist.append(one.index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group1[one]
                    del indices1[one]
            indices2 = indices2n
            group2 = group2n.copy()
        else:
            dellist = []
            while len(group2) < len(group1) - len(dellist):
                #Too many atoms in group 1
                dellist.append(random.choice(group1).index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group1[one]
                    del indices1[one]
            dellist = []
            while len(group1) < len(group2) - len(dellist):
                #Too many atoms in group 2
                dellist.append(random.choice(group2).index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group2[one]
                    del indices2[one]

        other2 = Atoms(cell=ind2[0].get_cell(), pbc=ind2[0].get_pbc())
        for one in indi2:
            if one.index not in indices2:
                other2.append(one)
        other1 = Atoms(cell=ind1[0].get_cell(), pbc=ind1[0].get_pbc())
        for one in indi1:
            if one.index not in indices1:
                other1.append(one)
        indi1 = group2.copy()
        indi1.extend(other1)
        indi2 = group1.copy()
        indi2.extend(other2)

        #DEBUG: Write crossover to file
        if debug:
            write_xyz(Optimizer.debugfile, group1, 'group1')
            write_xyz(Optimizer.debugfile, other1, 'other1')
            write_xyz(Optimizer.debugfile, group2, 'group2')
            write_xyz(Optimizer.debugfile, other2, 'other2')
            print 'Length of group1 = ', len(group1), 'Length of group2', len(
                group2)

        #DEBUG: Check structure of atoms exchanged
        for sym, c, m, u in Optimizer.atomlist:
            nc = len([atm for atm in indi1 if atm.symbol == sym])
            Optimizer.output.write(
                'CX RANDROTCT_Defect: Individual 1 contains ' + repr(nc) +
                ' ' + repr(sym) + ' atoms\n')
            nc = len([atm for atm in indi2 if atm.symbol == sym])
            Optimizer.output.write(
                'CX RANDROTCT_Defect: Individual 2 contains ' + repr(nc) +
                ' ' + repr(sym) + ' atoms\n')
        if Optimizer.forcing != 'Concentration':
            for i in range(len(Optimizer.atomlist)):
                atms1 = [
                    inds for inds in indi1
                    if inds.symbol == Optimizer.atomlist[i][0]
                ]
                atms2 = [
                    inds for inds in indi2
                    if inds.symbol == Optimizer.atomlist[i][0]
                ]
                if len(atms1) == 0:
                    if len(atms2) == 0:
                        indi1[random.randint(
                            0,
                            len(indi1) - 1)].symbol == Optimizer.atomlist[i][0]
                        indi2[random.randint(
                            0,
                            len(indi2) - 1)].symbol == Optimizer.atomlist[i][0]
                    else:
                        indi1.append(atms2[random.randint(0, len(atms2) - 1)])
                        indi1.pop(random.randint(0, len(indi1) - 2))
                else:
                    if len(atms2) == 0:
                        indi2.append(atms1[random.randint(0, len(atms1) - 1)])
                        indi2.pop(random.randint(0, len(indi2) - 2))
        indi1.rotate(rax, a=-1 * rang, center=rpos, rotate_cell=False)
        indi2.rotate(rax, a=-1 * rang, center=rpos, rotate_cell=False)
        if Optimizer.structure == 'Defect':
            indi1 = shift_atoms(indi1, [-p for p in com1])
            indi2 = shift_atoms(indi2, [-p for p in com2])
        else:
            indi1.translate(com1)
            indi2.translate(com2)

        #DEBUG: Check structure and number of atoms in crystal
        if Optimizer.structure == 'Defect':
            solid1 = Atoms()
            solid1.extend(indi1)
            solid1.extend(ind1.bulki)
            solid2 = Atoms()
            solid2.extend(indi2)
            solid2.extend(ind2.bulki)
            for sym, c, m, u in Optimizer.atomlist:
                nc = len([atm for atm in solid1 if atm.symbol == sym])
                Optimizer.output.write(
                    'CX RANDROTCT_Defect: Defect 1 configuration contains ' +
                    repr(nc) + ' ' + repr(sym) + ' atoms\n')
                nc = len([atm for atm in solid2 if atm.symbol == sym])
                Optimizer.output.write(
                    'CX RANDROTCT_Defect: Defect 2 configuration contains ' +
                    repr(nc) + ' ' + repr(sym) + ' atoms\n')
        if debug: Optimizer.output.flush()
        #pdb.set_trace()
        ind1[0] = indi1
        ind2[0] = indi2

    return ind1, ind2
Exemplo n.º 28
0
def get_defect_restart_indiv(Optimizer, indiv):
    """
    Function to generate an structopt Individual class object containing 
    	a defect structure from a previously existing structure
    Inputs:
    	Optimizer = structopt Optimizer class
    	indiv = ASE Atoms object containing the previously existing structure
    Outputs:
    	individ = structopt Individual class object containing defect structure data
    """
    if not Optimizer.solidbulk:
        #Initialize Bulk - Generate or load positions of bulk solid
        try:
            rank = MPI.COMM_WORLD.Get_rank()
        except:
            rank = 0
        outfilename = os.path.join(
            os.path.join(os.getcwd(),
                         Optimizer.filename + '-rank' + repr(rank)),
            'Bulkfile.xyz')
        if Optimizer.evalsolid:
            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.summary.write('CIBS Run Pure Bulk Energy per Atom:' +
                                repr(PureBulkEnpa) + '\n')
        Optimizer.purebulkenpa = PureBulkEnpa
        Optimizer.natomsbulk = natomsbulk
    indiv.set_cell(Optimizer.solidcell)
    indiv.set_pbc(True)
    if Optimizer.restart_ints == 0:
        outt = find_defects(indiv, Optimizer.solidbulk, Optimizer.sf)
    else:
        indicop = [atm for atm in indiv if atm.symbol != 'X']
        indiv = Atoms(cell=Optimizer.solidcell, pbc=True)
        for atm in indicop:
            indiv.append(atm)
        outt = [
            indiv[0:Optimizer.restart_ints], indiv[Optimizer.restart_ints::],
            Atoms(),
            Atoms(), 'Assuming first ' + repr(Optimizer.restart_ints) +
            ' are interstitials\n'
        ]
    indi = outt[0].copy()
    bulki = outt[1].copy()
    individ = Individual(indi)
    individ.bulko = bulki.copy()
    individ.bulki = bulki.copy()
    individ.purebulkenpa = Optimizer.purebulkenpa
    individ.natomsbulk = Optimizer.natomsbulk
    individ.vacancies = outt[2].copy()
    individ.swaps = outt[3].copy()
    Optimizer.output.write(outt[4])
    return individ
Exemplo n.º 29
0
def rotation(indiv, Optimizer):
    """Move function to perform rotation of a group of atoms
    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]
    else:
        atms=indiv[0]
    nat=len(atms)
    if nat != 0:
        if nat<=1:
            natrot2=1
            natrot1=0
        elif nat<=6:
            natrot2=2
            natrot1=0
        else: 
            natrot1=random.randint(1,nat/2)
            natrot2=random.randint(2,(nat-1)/2)
            if natrot2 >= natrot1:
                natrot2 +=1
            else:
                natrot1, natrot2 = natrot2, natrot1
        natrot=natrot2 - natrot1
        atmsr=atms[natrot1:natrot2]
        del atms[natrot1:natrot2]
        if Optimizer.forcing != 'FreeNatom':
           ax=['x', '-x','y','-y','z','-z']
        else:
           ax=['z','-z']
        rax=ax[random.randint(0,len(ax)-1)]
        #rang=random.uniform(30,180)
        rang=random.random()*math.pi
        #rang=random.random()*90
        atmsr.rotate(rax,a=rang,center='COM',rotate_cell=False)
        atms.extend(atmsr)
        if Optimizer.structure=='Defect':
            if Optimizer.isolate_mutation:
                atms.extend(indb)
        indiv[0]=atms.copy()
    else:
        natrot=0
        rax=0
        rang=0
    Optimizer.output.write('Rotation Mutation performed on individual\n')
    Optimizer.output.write('Index = '+repr(indiv.index)+'\n')
    Optimizer.output.write('Number of atoms rotated = '+repr(natrot)+'\n')
    Optimizer.output.write('Rotation vector = '+repr(rax)+'\n')
    Optimizer.output.write('Rotation angle = '+repr(rang)+'\n')
    Optimizer.output.write(repr(indiv[0])+'\n')
    muttype='R'+repr(natrot)
    if indiv.energy==0:
        indiv.history_index=indiv.history_index+'m'+muttype
    else:
        indiv.history_index=repr(indiv.index)+'m'+muttype
    return indiv
Exemplo n.º 30
0
def eval_energy(input):
    """Function to evaluate energy of an individual
    Inputs:
        input = [Optimizer class object with parameters, Individual class structure to be evaluated]
    Outputs:
        energy, bul, individ, signal
        energy = energy of Individual evaluated
        bul = bulk structure of Individual if simulation structure is Defect
        individ = Individual class structure evaluated
        signal = string of information about evaluation
    """
    if input[0] == None:
        energy = 0
        bul = 0
        individ = 0
        rank = MPI.COMM_WORLD.Get_rank()
        signal = 'Evaluated none individual on ' + repr(rank) + '\n'
    else:
        [Optimizer, individ] = input
    if Optimizer.calc_method == 'MAST':
        energy = individ.energy
        bul = individ.energy
        signal = 'Recieved MAST structure\n'
    else:
        if Optimizer.parallel: rank = MPI.COMM_WORLD.Get_rank()
        if not Optimizer.genealogy:
            STR = '----Individual ' + str(
                individ.index) + ' Optimization----\n'
        else:
            STR = '----Individual ' + str(
                individ.history_index) + ' Optimization----\n'
        indiv = individ[0]
        if 'EE' in Optimizer.debug:
            debug = True
        else:
            debug = False
        if debug:
            write_xyz(Optimizer.debugfile, indiv, 'Recieved by eval_energy')
            Optimizer.debugfile.flush()
        if Optimizer.structure == 'Defect':
            indi = indiv.copy()
            if Optimizer.alloy == True:
                bulk = individ.bulki
            else:
                bulk = individ.bulko
            nat = indi.get_number_of_atoms()
            csize = bulk.get_cell()
            totalsol = Atoms(cell=csize, pbc=True)
            totalsol.extend(indi)
            totalsol.extend(bulk)
            for sym, c, m, u in Optimizer.atomlist:
                nc = len([atm for atm in totalsol if atm.symbol == sym])
                STR += 'Defect configuration contains ' + repr(
                    nc) + ' ' + repr(sym) + ' atoms\n'

        elif Optimizer.structure == 'Surface':
            totalsol = Atoms()
            totalsol.extend(indiv)
            nat = indiv.get_number_of_atoms()
            totalsol.extend(individ.bulki)
            for sym, c, m, u in Optimizer.atomlist:
                nc = len([atm for atm in totalsol if atm.symbol == sym])
                STR += 'Surface-Bulk configuration contains ' + repr(
                    nc) + ' ' + repr(sym) + ' atoms\n'
            cell = numpy.maximum.reduce(indiv.get_cell())
            totalsol.set_cell([cell[0], cell[1], 500])
            totalsol.set_pbc([True, True, False])

        if Optimizer.constrain_position:
            ts = totalsol.copy()
            indc, indb, vacant, swap, stro = find_defects(
                ts, Optimizer.solidbulk, 0)
            sbulk = Optimizer.solidbulk.copy()
            bcom = sbulk.get_center_of_mass()
            #totalsol.translate(-bulkcom)
            #indc.translate(-bulkcom)
            #totalsol.append(Atom(position=[0,0,0]))
            # 			for one in indc:
            # 				index = [atm.index for atm in totalsol if atm.position[0]==one.position[0] and atm.position[1]==one.position[1] and atm.position[2]==one.position[2]][0]
            # 				if totalsol.get_distance(-1,index) > Optimizer.sf:
            # 					r = random.random()
            # 					totalsol.set_distance(-1,index,Optimizer.sf*r,fix=0)
            # 			totalsol.pop()
            # 			totalsol.translate(bulkcom)
            com = indc.get_center_of_mass()
            dist = (sum((bcom[i] - com[i])**2 for i in range(3)))**0.5
            if dist > Optimizer.sf:
                STR += 'Shifting structure to within region\n'
                r = random.random() * Optimizer.sf
                comv = numpy.linalg.norm(com)
                ncom = [one * r / comv for one in com]
                trans = [ncom[i] - com[i] for i in range(3)]
                indices = []
                for one in indc:
                    id = [
                        atm.index for atm in totalsol
                        if atm.position[0] == one.position[0]
                        and atm.position[1] == one.position[1]
                        and atm.position[2] == one.position[2]
                    ][0]
                    totalsol[id].position += trans

        # Check for atoms that are too close
        min_len = 0.7
        #pdb.set_trace()
        if not Optimizer.fixed_region:
            if Optimizer.structure == 'Defect' or Optimizer.structure == 'Surface':
                cutoffs = [2.0 for one in totalsol]
                nl = NeighborList(cutoffs,
                                  bothways=True,
                                  self_interaction=False)
                nl.update(totalsol)
                for one in totalsol[0:nat]:
                    nbatoms = Atoms()
                    nbatoms.append(one)
                    indices, offsets = nl.get_neighbors(one.index)
                    for index, d in zip(indices, offsets):
                        index = int(index)
                        sym = totalsol[index].symbol
                        pos = totalsol[index].position + numpy.dot(
                            d, totalsol.get_cell())
                        at = Atom(symbol=sym, position=pos)
                        nbatoms.append(at)
                    while True:
                        dflag = False
                        for i in range(1, len(nbatoms)):
                            d = nbatoms.get_distance(0, i)
                            if d < min_len:
                                nbatoms.set_distance(0,
                                                     i,
                                                     min_len + .01,
                                                     fix=0.5)
                                STR += '--- WARNING: Atoms too close (<0.7A) - Implement Move ---\n'
                                dflag = True
                        if dflag == False:
                            break
                    for i in range(len(indices)):
                        totalsol[indices[i]].position = nbatoms[i + 1].position
                    totalsol[one.index].position = nbatoms[0].position
                    nl.update(totalsol)
                if debug:
                    write_xyz(Optimizer.debugfile, totalsol,
                              'After minlength check')
                    Optimizer.debugfile.flush()
            else:
                for i in range(len(indiv)):
                    for j in range(len(indiv)):
                        if i != j:
                            d = indiv.get_distance(i, j)
                            if d < min_len:
                                indiv.set_distance(i, j, min_len, fix=0.5)
                                STR += '--- WARNING: Atoms too close (<0.7A) - Implement Move ---\n'
                if debug:
                    write_xyz(Optimizer.debugfile, indiv,
                              'After minlength check')
                    Optimizer.debugfile.flush()

        # Set calculator to use to get forces/energies
        if Optimizer.parallel:
            calc = setup_calculator(Optimizer)
            if Optimizer.fixed_region:
                pms = copy.deepcopy(calc.parameters)
                try:
                    pms['mass'][
                        len(pms['mass']) - 1] += '\ngroup RO id >= ' + repr(
                            nat) + '\nfix freeze RO setforce 0.0 0.0 0.0\n'
                except KeyError:
                    pms['pair_coeff'][0] += '\ngroup RO id >= ' + repr(
                        nat) + '\nfix freeze RO setforce 0.0 0.0 0.0\n'
                calc = LAMMPS(parameters=pms,
                              files=calc.files,
                              keep_tmp_files=calc.keep_tmp_files,
                              tmp_dir=calc.tmp_dir)
                lmin = copy.copy(Optimizer.lammps_min)
                Optimizer.lammps_min = None
                Optimizer.static_calc = setup_calculator(Optimizer)
                Optimizer.lammps_min = lmin
        else:
            calc = Optimizer.calc
        if Optimizer.structure == 'Defect' or Optimizer.structure == 'Surface':
            totalsol.set_calculator(calc)
            totalsol.set_pbc(True)
        else:
            indiv.set_calculator(calc)
            indiv.set_pbc(
                True)  #Current bug in ASE optimizer-Lammps prevents pbc=false
            if Optimizer.structure == 'Cluster':
                indiv.set_cell([500, 500, 500])
                indiv.translate([250, 250, 250])

        cwd = os.getcwd()
        # Perform Energy Minimization
        if not Optimizer.parallel:
            Optimizer.output.flush()
        if Optimizer.ase_min == True:
            try:
                if Optimizer.structure == 'Defect' or Optimizer.structure == 'Surface':
                    dyn = BFGS(totalsol)
                else:
                    dyn = BFGS(indiv)
                dyn.run(fmax=Optimizer.ase_min_fmax,
                        steps=Optimizer.ase_min_maxsteps)
            except OverflowError:
                STR += '--- Error: Infinite Energy Calculated - Implement Random ---\n'
                box = Atoms()
                indiv = gen_pop_box(Optimizer.natoms, Optimizer.atomlist,
                                    Optimizer.size)
                indiv.set_calculator(calc)
                dyn = BFGS(indiv)
                dyn.run(fmax=fmax, steps=steps)
            except numpy.linalg.linalg.LinAlgError:
                STR += '--- Error: Singular Matrix - Implement Random ---\n'
                indiv = gen_pop_box(Optimizer.natoms, Optimizer.atomlist,
                                    Optimizer.size)
                indiv.set_calculator(calc)
                dyn = BFGS(indiv)
                dyn.run(fmax=fmax, steps=steps)
            # Get Energy of Minimized Structure
            if Optimizer.structure == 'Defect' or Optimizer.structure == 'Surface':
                en = totalsol.get_potential_energy()
                #force=numpy.maximum.reduce(abs(totalsol.get_forces()))
                if Optimizer.fitness_scheme == 'enthalpyfit':
                    pressure = totalsol.get_isotropic_pressure(
                        totalsol.get_stress())
                    cell_max = numpy.maximum.reduce(totalsol.get_positions())
                    cell_min = numpy.minimum.reduce(totalsol.get_positions())
                    cell = cell_max - cell_min
                    volume = cell[0] * cell[1] * cell[2]
                else:
                    pressure = 0
                    volume = 0
                na = totalsol.get_number_of_atoms()
                ena = en / na
                energy = en
                individ[0] = totalsol[0:nat]
                bul = totalsol[(nat):len(totalsol)]
                STR += 'Number of positions = ' + repr(
                    len(bul) + len(individ[0])) + '\n'
                individ[0].set_cell(csize)
                indiv = individ[0]
            else:
                en = indiv.get_potential_energy()
                if Optimizer.fitness_scheme == 'enthalpyfit':
                    pressure = indiv.get_isotropic_pressure(indiv.get_stress())
                    cell_max = numpy.maximum.reduce(indiv.get_positions())
                    cell_min = numpy.minimum.reduce(indiv.get_positions())
                    cell = cell_max - cell_min
                    volume = cell[0] * cell[1] * cell[2]
                else:
                    pressure = 0
                    volume = 0
                na = indiv.get_number_of_atoms()
                ena = en / na
                energy = ena
                individ[0] = indiv
                bul = 0
        else:
            if Optimizer.structure == 'Defect' or Optimizer.structure == 'Surface':
                if Optimizer.calc_method == 'VASP':
                    en = totalsol.get_potential_energy()
                    calcb = Vasp(restart=True)
                    totalsol = calcb.get_atoms()
                    stress = calcb.read_stress()
                else:
                    try:
                        totcop = totalsol.copy()
                        if debug:
                            write_xyz(Optimizer.debugfile, totcop,
                                      'Individual sent to lammps')
                        OUT = totalsol.calc.calculate(totalsol)
                        totalsol = OUT['atoms']
                        totalsol.set_pbc(True)
                        if Optimizer.fixed_region:
                            if debug:
                                print 'Energy of fixed region calc = ', OUT[
                                    'thermo'][-1]['pe']
                            totalsol.set_calculator(Optimizer.static_calc)
                            OUT = totalsol.calc.calculate(totalsol)
                            totalsol = OUT['atoms']
                            totalsol.set_pbc(True)
                            if debug:
                                print 'Energy of static calc = ', OUT[
                                    'thermo'][-1]['pe']
                        en = OUT['thermo'][-1]['pe']
                        stress = numpy.array([
                            OUT['thermo'][-1][i]
                            for i in ('pxx', 'pyy', 'pzz', 'pyz', 'pxz', 'pxy')
                        ]) * (-1e-4 * GPa)
                        #force=numpy.maximum.reduce(abs(totalsol.get_forces()))
                        if debug:
                            write_xyz(Optimizer.debugfile, totalsol,
                                      'After Lammps Minimization')
                            Optimizer.debugfile.flush()
                    except Exception, e:
                        os.chdir(cwd)
                        STR += 'WARNING: Exception during energy eval:\n' + repr(
                            e) + '\n'
                        f = open('problem-structures.xyz', 'a')
                        write_xyz(f,
                                  totcop,
                                  data='Starting structure hindex=' +
                                  individ.history_index)
                        write_xyz(f, totalsol, data='Lammps Min structure')
                        en = 10
                        stress = 0
                        f.close()
                if Optimizer.fitness_scheme == 'enthalpyfit':
                    pressure = totalsol.get_isotropic_pressure(stress)
                    cell_max = numpy.maximum.reduce(totalsol.get_positions())
                    cell_min = numpy.minimum.reduce(totalsol.get_positions())
                    cell = cell_max - cell_min
                    volume = cell[0] * cell[1] * cell[2]
                else:
                    pressure = totalsol.get_isotropic_pressure(stress)
                    volume = 0
                na = totalsol.get_number_of_atoms()
                ena = en / na
                energy = en
                if Optimizer.structure == 'Defect':
                    if Optimizer.fixed_region == True or Optimizer.finddefects == False:
                        individ[0] = totalsol[0:nat]
                        bul = totalsol[(nat):len(totalsol)]
                        individ[0].set_cell(csize)
                    else:
                        if 'FI' in Optimizer.debug:
                            outt = find_defects(
                                totalsol,
                                Optimizer.solidbulk,
                                Optimizer.sf,
                                atomlistcheck=Optimizer.atomlist,
                                trackvacs=Optimizer.trackvacs,
                                trackswaps=Optimizer.trackswaps,
                                debug=Optimizer.debugfile)
                        else:
                            outt = find_defects(
                                totalsol,
                                Optimizer.solidbulk,
                                Optimizer.sf,
                                atomlistcheck=Optimizer.atomlist,
                                trackvacs=Optimizer.trackvacs,
                                trackswaps=Optimizer.trackswaps,
                                debug=False)
                        individ[0] = outt[0]
                        bul = outt[1]
                        individ.vacancies = outt[2]
                        individ.swaps = outt[3]
                        STR += outt[4]
                    indiv = individ[0]
                else:
                    top, bul = find_top_layer(totalsol, Optimizer.surftopthick)
                    indiv = top.copy()
                    individ[0] = top.copy()
            else:
Exemplo n.º 31
0
def lattice_alteration_nn(indiv, Optimizer):
    """Move function to perform random move along random axis for nearest neighbor distance to random atoms
    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:
            indc, indb, vacant, swaps, stro = find_defects(
                indiv[0], Optimizer.solidbulk, 0)
            ind = indc.copy()
            ind.extend(indb)
        else:
            ind = indiv[0].copy()
            indc = indiv[0].copy()
    else:
        ind = indiv[0].copy()
        indc = indiv[0].copy()
    if len(indc) != 0:
        ctoff1 = [1.0 for one in ind]
        nl = NeighborList(ctoff1, bothways=True, self_interaction=False)
        nl.update(ind)
        try:
            natomsmove = random.randint(1, len(indc) / 2)
        except ValueError:
            natomsmove = 1
        passn = 0
        for count in range(natomsmove):
            try:
                indexmv = random.choice([i for i in range(len(indc))])
                indices, offsets = nl.get_neighbors(indexmv)
                nns = Atoms()
                nns.append(ind[indexmv])
                for index, d in zip(indices, offsets):
                    index = int(index)
                    pos = ind[index].position + numpy.dot(d, ind.get_cell())
                    nns.append(Atom(symbol=ind[index].symbol, position=pos))
                dist = [nns.get_distance(0, i) for i in range(1, len(nns))]
                r = sum(dist) / len(dist)
                dir = random.choice([[1, 0, 0], [-1, 0, 0], [0, 1, 0],
                                     [0, -1, 0], [0, 0, 1], [0, 0, -1]])
                ind[indexmv].position += [i * r for i in dir]
            except:
                passn += 1
        indiv[0] = ind.copy()
    else:
        natomsmove = 0
        passn = 0
    Optimizer.output.write(
        'Lattice Alteration NN Mutation performed on individual\n')
    Optimizer.output.write('Index = ' + repr(indiv.index) + '\n')
    natomsmove -= passn
    Optimizer.output.write('Number of atoms moved = ' + repr(natomsmove) +
                           '\n')
    Optimizer.output.write(repr(indiv[0]) + '\n')
    muttype = 'LANN' + repr(natomsmove)
    if indiv.energy == 0:
        indiv.history_index = indiv.history_index + 'm' + muttype
    else:
        indiv.history_index = repr(indiv.index) + 'm' + muttype
    return indiv
Exemplo n.º 32
0
def lattice_alteration_group(indiv, Optimizer):
    """Move function to perform Lattice Alteration of group of atoms based on location
    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:
            indc, indb, vacant, swap, stro = find_defects(indiv[0], Optimizer.solidbulk, 0)
            atms = indc.copy()
        else:
            atms = indiv[0].copy()
    else:
        atms = indiv[0].copy()
    if len(atms) != 0:
        try:
            natomsmove = random.randint(1, len(atms) / 5)
        except ValueError:
            natomsmove = 1
        # Select random position in cluster
        cellx = numpy.maximum.reduce(atms.get_positions())
        cellm = numpy.minimum.reduce(atms.get_positions())
        pt = [
            random.uniform(cellm[0], cellx[0]),
            random.uniform(cellm[1], cellx[1]),
            random.uniform(cellm[2], cellx[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
        atmst = Atoms()
        indexlist = []
        for i in range(natomsmove):
            atmst.append(dlist[i][1])
            indexlist.append(dlist[i][1].index)
        trans = (
            random.uniform(0, cellx[0] - cellm[0]),
            random.uniform(0, cellx[1] - cellm[1]),
            random.uniform(0, cellx[2] - cellm[2]),
        )
        atmst.translate(trans)
        for i in range(len(indexlist)):
            index = indexlist[i]
            atms[index].position = atmst[i].position
        if Optimizer.structure == "Defect":
            if Optimizer.isolate_mutation:
                indiv[0] = atms.copy()
                indiv[0].extend(indb)
            else:
                indiv[0] = atms.copy()
        else:
            indiv[0] = atms.copy()
    else:
        natomsmove = 0
        trans = 0
    Optimizer.output.write("Group Lattice Alteration Mutation performed on individual\n")
    Optimizer.output.write("Index = " + repr(indiv.index) + "\n")
    Optimizer.output.write("Number of atoms moved = " + repr(natomsmove) + "\n")
    Optimizer.output.write(repr(trans) + "\n")
    Optimizer.output.write(repr(indiv[0]) + "\n")
    muttype = "LAGC" + repr(natomsmove)
    if indiv.energy == 0:
        indiv.history_index = indiv.history_index + "m" + muttype
    else:
        indiv.history_index = repr(indiv.index) + "m" + muttype
    return indiv
Exemplo n.º 33
0
def lattice_alteration_group(indiv, Optimizer):
    """Move function to perform Lattice Alteration of group of atoms based on location
    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:
            indc, indb, vacant, swap, stro = find_defects(
                indiv[0], Optimizer.solidbulk, 0)
            atms = indc.copy()
        else:
            atms = indiv[0].copy()
    else:
        atms = indiv[0].copy()
    if len(atms) != 0:
        try:
            natomsmove = random.randint(1, len(atms) / 5)
        except ValueError:
            natomsmove = 1
        #Select random position in cluster
        cellx = numpy.maximum.reduce(atms.get_positions())
        cellm = numpy.minimum.reduce(atms.get_positions())
        pt = [
            random.uniform(cellm[0], cellx[0]),
            random.uniform(cellm[1], cellx[1]),
            random.uniform(cellm[2], cellx[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
        atmst = Atoms()
        indexlist = []
        for i in range(natomsmove):
            atmst.append(dlist[i][1])
            indexlist.append(dlist[i][1].index)
        trans = (random.uniform(0, cellx[0] - cellm[0]),
                 random.uniform(0, cellx[1] - cellm[1]),
                 random.uniform(0, cellx[2] - cellm[2]))
        atmst.translate(trans)
        for i in range(len(indexlist)):
            index = indexlist[i]
            atms[index].position = atmst[i].position
        if Optimizer.structure == 'Defect':
            if Optimizer.isolate_mutation:
                indiv[0] = atms.copy()
                indiv[0].extend(indb)
            else:
                indiv[0] = atms.copy()
        else:
            indiv[0] = atms.copy()
    else:
        natomsmove = 0
        trans = 0
    Optimizer.output.write(
        'Group Lattice Alteration Mutation performed on individual\n')
    Optimizer.output.write('Index = ' + repr(indiv.index) + '\n')
    Optimizer.output.write('Number of atoms moved = ' + repr(natomsmove) +
                           '\n')
    Optimizer.output.write(repr(trans) + '\n')
    Optimizer.output.write(repr(indiv[0]) + '\n')
    muttype = 'LAGC' + repr(natomsmove)
    if indiv.energy == 0:
        indiv.history_index = indiv.history_index + 'm' + muttype
    else:
        indiv.history_index = repr(indiv.index) + 'm' + muttype
    return indiv
Exemplo n.º 34
0
def rotation_geo(indiv, Optimizer):
    '''Function to handle a geometry based rotation mutation
    Rotates a small group of atoms based on location within structure
    Input:
        indiv = structopt Individual class object to be mutated
        Optimizer = structopt Optimizer class object
    Output:
        indiv = structopt Individual class object that has been mutated
    '''
    if 'MU' in Optimizer.debug:
        debug = True
    else:
        debug = False
    #Rotate group of atoms based on geometry
    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 > 1:
        #Select number of atoms to rotate
        if nat==2:
            natrot=2
        else:
            natrot = random.randint(2,nat)
        #Select random position in cluster
        cell=numpy.maximum.reduce(atms.get_positions())-numpy.minimum.reduce(atms.get_positions())
        pt=[random.uniform(0,cell[0]),random.uniform(0,cell[1]),random.uniform(0,cell[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(natrot):
            atmsr.append(dlist[i][1])
            indexlist.append(dlist[i][1].index)
        #Identify random rotation and rotate selected atoms
        ax=['x', '-x','y','-y','z','-z']
        rax=ax[random.randint(0,len(ax)-1)]
        rang=random.uniform(30,180)
        #rang=random.random()*90
        atmsr.rotate(rax,a=rang,center='COM',rotate_cell=False)
        #Update individual with new atom positions
        for i in range(len(indexlist)):
            index=indexlist[i]
            atms[index].position=atmsr[i].position
        if Optimizer.structure=='Defect':
            if Optimizer.isolate_mutation:
                atms.extend(indb)
        indiv[0]=atms.copy()
        #Optimizer.output.write('New positions = '+repr(indiv[0].get_positions())+'\n')
    else:
        natrot=0
        pt=0
        rax=0
        rang=0
    Optimizer.output.write('Geometry Rotation Mutation performed on individual\n')
    Optimizer.output.write('Index = '+repr(indiv.index)+'\n')
    Optimizer.output.write('Number of atoms rotated = '+repr(natrot)+'\n')
    Optimizer.output.write('Geometry point = '+repr(pt)+'\n')
    Optimizer.output.write('Rotation vector = '+repr(rax)+'\n')
    Optimizer.output.write('Rotation angle = '+repr(rang)+'\n')
    Optimizer.output.write(repr(indiv[0])+'\n')
    muttype='GR'+repr(natrot)
    if indiv.energy==0:
        indiv.history_index=indiv.history_index+'m'+muttype
    else:
        indiv.history_index=repr(indiv.index)+'m'+muttype
    return indiv