Ejemplo n.º 1
1
def update_structfile(ind, structfile, Optimizer):
    if Optimizer.structure == 'Defect' or Optimizer.structure == 'Surface':
        sols = Atoms()
        sols.extend(ind[0])
        sols.extend(ind.bulki)
    elif Optimizer.structure == 'Crystal':
        sols = ind[0].repeat((3,3,3))
    else:
        sols = ind[0].copy()
    positions = sols.get_positions()
    if Optimizer.vacancy_output:
        for one in ind.vacancies:
            sols.append(Atom(symbol='X',position=one.position))
    #Optimizer.output.write('Number of positions = {0}\n'.format(len(positions)))
    write_xyz(structfile, sols, ind.energy)
    return positions
Ejemplo n.º 2
0
def stem_cost(indiv, Optimizer):
    '''Function to calculate STEM_Cost fitness of individual.
    Input:
        indiv = structopt Individual class object to be evaluated
        Optimizer = structopt Optimizer class object
            Must have STEM Calc function attached
    Output:
        indiv = structopt Individual class object with new fitness.
    '''
    #logger = initialize_logger(Optimizer.loggername)
    logger = logging.getLogger(Optimizer.loggername)
    starting = indiv.duplicate()
    cwd = os.getcwd()
    try:
        outs = eval_energy(Optimizer,indiv)
    except Exception, e:
        logger.warn('Error in energy evaluation: {0}'.format(e), exc_info=True)
        stro = 'ERROR: Problem in Energy Evaluation'
        print stro
        print e
        stro += '\n' + repr(e)
        os.chdir(cwd)
        f=open('problem-structures.xyz','a')
        totalsol = indiv[0].copy()
        totalsol.extend(indiv.bulki)
        write_xyz(f,totalsol,data='Starting structure hindex={0}'.format(indiv.history_index))
        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]
Ejemplo n.º 3
0
def write_pop(Optimizer,pop):
    """
    Function to write the data from a given population.
    Inputs:
        Optimizer = structopt Optimizer class object with output file data
        pop = List of structopt Individual class objects with data to be written
    Outputs:
        None. Data is written to output files provided by Optimizer class object
    """
    Optimizer.output.write('\n--New Population--\n')
    #Write structures
    for ind in pop:
        update_outfile(ind, Optimizer.output)
        if Optimizer.genealogy:
            update_genealogy(ind, Optimizer.Genealogyfile)
        if Optimizer.swaplist: 
            swaplist_check(ind,Optimizer.structure,Optimizer.output)
        if Optimizer.indiv_defect_write:
            write_xyz(Optimizer.ifiles[ind.index],ind[0],ind.energy)
        update_structsumfile(ind, Optimizer.files[Optimizer.nindiv])
        if Optimizer.generation % 10 == 0:
           positions = update_structfile(ind, Optimizer.files[ind.index], Optimizer)
           Optimizer.output.write('Number of positions = {0}\n'.format(len(positions)))
    if Optimizer.genealogy:
        Optimizer.Genealogyfile.write('\n')
    return
Ejemplo n.º 4
0
def surfaceenergy(indiv, Optimizer):
    '''Function to calculate surface energy fitness of individual.
    Input:
        indiv = structopt Individual class object to be evaluated
        Optimizer = structopt Optimizer class object
    Output:
        indiv = structopt Individual class object with new fitness.
    '''
    logger = logging.getLogger(Optimizer.loggername)
    #logger = initialize_logger(Optimizer.loggername)
    starting = indiv.duplicate()
    cwd = os.getcwd()
    try:
        outs = eval_energy(Optimizer, indiv)
    except Exception, e:
        logger.warn('Error in energy evaluation: {0}'.format(e), exc_info=True)
        stro = 'ERROR: Problem in Energy Evaluation'
        print stro
        print e
        stro += '\n' + repr(e)
        os.chdir(cwd)
        f = open('problem-structures.xyz', 'a')
        totalsol = indiv[0].copy()
        totalsol.extend(indiv.bulki)
        write_xyz(f,
                  totalsol,
                  data='Starting structure hindex={0}'.format(
                      indiv.history_index))
        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]
Ejemplo n.º 5
0
def crossover_switch(child1, child2, Optimizer):
    """Functions for selecting and pairing individuals 
    for crossovers"""
    #logger = initialize_logger(Optimizer.loggername)
    logger = logging.getLogger(Optimizer.loggername)
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    if debug:
        s1 = child1[0].copy()
        s2 = child2[0].copy()
        if Optimizer.structure == 'Defect':
            s1.extend(child1.bulki.copy())
            s2.extend(child2.bulki.copy())
        write_xyz(Optimizer.debugfile, s1, 'First Cx Individual - Pre ')
        write_xyz(Optimizer.debugfile, s2, 'Second Cx Individual - Pre')
    passflag = True
    scheme = Optimizer.cx_scheme
    try:
        exec "from MAST.structopt.crossover.{0} import {0}".format(scheme)
        nchild1, nchild2 = eval(
            '{0}(child1, child2, Optimizer)'.format(scheme))
    except NameError, e:
        logger.warning(
            'Specified Crossover not one of the available options. Please check documentation and spelling! Crossover : {0}. {1}'
            .format(Optimizer.cx_scheme, e),
            exc_info=True)
        print 'Name Error:', e
        passflag = False
Ejemplo n.º 6
0
Archivo: enpafit.py Proyecto: m-yu/MAST
def enpafit(indiv,Optimizer):
    """Fitness function to evaluate the energy per atom of an individual structure.
    Inputs:
        indiv = Individual class object to be evaluated
        Optimizer = Optimizer class object with needed parameters
    Outputs:
        indiv = Evaluated Individual class object
    """
    #logger = initialize_logger(Optimizer.loggername)
    logger = logging.getLogger(Optimizer.loggername)
    starting = indiv.duplicate()
    cwd = os.getcwd()
    try:
        outs = eval_energy(Optimizer,indiv)
    except Exception, e:
        logger.warn('Error in energy evaluation: {0}'.format(e), exc_info=True)
        stro = 'ERROR: Problem in Energy Evaluation'
        print stro
        print e
        stro += '\n' + repr(e)
        os.chdir(cwd)
        f=open('problem-structures.xyz','a')
        totalsol = indiv[0].copy()
        totalsol.extend(indiv.bulki)
        write_xyz(f,totalsol,data='Starting structure hindex={0}'.format(indiv.history_index))
        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]
Ejemplo n.º 7
0
def enthalpyfit(indiv, Optimizer):
    """Fitness function to evaluate the enthalpy of an individual structure.
    Inputs:
        indiv = Individual class object to be evaluated
        Optimizer = Optimizer class object with needed parameters
    Outputs:
        indiv = Evaluated Individual class object
    """
    #logger = initialize_logger(Optimizer.loggername)
    logger = logging.getLogger(Optimizer.loggername)
    starting = indiv.duplicate()
    cwd = os.getcwd()
    try:
        outs = eval_energy(Optimizer, indiv)
        passflag = True
    except Exception, e:
        logger.warn('Error in energy evaluation: {0}'.format(e), exc_info=True)
        stro = 'ERROR: Problem in Energy Evaluation'
        print stro
        print e
        stro += '\n' + repr(e)
        os.chdir(cwd)
        f = open('problem-structures.xyz', 'a')
        totalsol = indiv[0].copy()
        totalsol.extend(indiv.bulki)
        write_xyz(f,
                  totalsol,
                  data='Starting structure hindex={0}'.format(
                      indiv.history_index))
        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]
        passflag = False
Ejemplo n.º 8
0
def crossover_switch(child1, child2, Optimizer):
    """Functions for selecting and pairing individuals 
    for crossovers"""
    # logger = initialize_logger(Optimizer.loggername)
    logger = logging.getLogger(Optimizer.loggername)
    if "CX" in Optimizer.debug:
        debug = True
    else:
        debug = False
    if debug:
        s1 = child1[0].copy()
        s2 = child2[0].copy()
        if Optimizer.structure == "Defect":
            s1.extend(child1.bulki.copy())
            s2.extend(child2.bulki.copy())
        write_xyz(Optimizer.debugfile, s1, "First Cx Individual - Pre ")
        write_xyz(Optimizer.debugfile, s2, "Second Cx Individual - Pre")
    passflag = True
    scheme = Optimizer.cx_scheme
    try:
        exec "from MAST.structopt.crossover.{0} import {0}".format(scheme)
        nchild1, nchild2 = eval("{0}(child1, child2, Optimizer)".format(scheme))
    except NameError, e:
        logger.warning(
            "Specified Crossover not one of the available options. Please check documentation and spelling! Crossover : {0}. {1}".format(
                Optimizer.cx_scheme, e
            ),
            exc_info=True,
        )
        print "Name Error:", e
        passflag = False
Ejemplo n.º 9
0
def write_pop(Optimizer, pop):
    """
    Function to write the data from a given population.
    Inputs:
        Optimizer = structopt Optimizer class object with output file data
        pop = List of structopt Individual class objects with data to be written
    Outputs:
        None. Data is written to output files provided by Optimizer class object
    """
    Optimizer.output.write('\n--New Population--\n')
    #Write structures
    for ind in pop:
        update_outfile(ind, Optimizer.output)
        if Optimizer.genealogy:
            update_genealogy(ind, Optimizer.Genealogyfile)
        if Optimizer.swaplist:
            swaplist_check(ind, Optimizer.structure, Optimizer.output)
        if Optimizer.indiv_defect_write:
            write_xyz(Optimizer.ifiles[ind.index], ind[0], ind.energy)
        update_structsumfile(ind, Optimizer.files[Optimizer.nindiv])
        positions = update_structfile(ind, Optimizer.files[ind.index],
                                      Optimizer)
        Optimizer.output.write('Number of positions = {0}\n'.format(
            len(positions)))
    if Optimizer.genealogy:
        Optimizer.Genealogyfile.write('\n')
    return
Ejemplo n.º 10
0
def update_structfile(ind, structfile, Optimizer):
    if Optimizer.structure == 'Defect' or Optimizer.structure == 'Surface':
        sols = Atoms()
        sols.extend(ind[0])
        sols.extend(ind.bulki)
    elif Optimizer.structure == 'Crystal':
        sols = ind[0].repeat((3, 3, 3))
    else:
        sols = ind[0].copy()
    positions = sols.get_positions()
    if Optimizer.vacancy_output:
        for one in ind.vacancies:
            sols.append(Atom(symbol='X', position=one.position))
    Optimizer.output.write('Number of positions = {0}\n'.format(
        len(positions)))
    write_xyz(structfile, sols, ind.energy)
    return positions
Ejemplo n.º 11
0
def write_individual(individ, indivfile):
    """Function to write the data of an individual class object to a flat file
    Input:
        individ = Individual class object to be written
        indivfile = String or fileobject for file to be written to 
    Output:
        No output returned.  Information is written to file
    """
    if isinstance(indivfile, str):
        indivfile=open(indivfile, 'a')
    #Write break
    indivfile.write('----------\n')
    #Write structure information
    indivfile.write('Structure information\n')
    write_xyz(indivfile, individ[0])
    indivfile.write('structure cell = {0}\n'.format(get_atom_cell(individ[0])))
    #Write additional information
    indivfile.write('fitness = {0}\n'.format(individ.fitness))
    indivfile.write('index = {0}\n'.format(individ.index))
    indivfile.write('history_index = {0}\n'.format(individ.index))
    indivfile.write('energy = {0}\n'.format(individ.energy))
    indivfile.write('tenergymx = {0}\n'.format(individ.tenergymx))
    indivfile.write('tenergymin = {0}\n'.format(individ.tenergymin))
    indivfile.write('pressure = {0}\n'.format(individ.pressure))
    indivfile.write('volume = {0}\n'.format(individ.volume))
    indivfile.write('force = {0}\n'.format(individ.force))
    indivfile.write('purebulkenpa = {0}\n'.format(individ.purebulkenpa))
    indivfile.write('natomsbulk = {0}\n'.format(individ.natomsbulk))
    indivfile.write('fingerprint = {0}\n'.format(individ.fingerprint))
    indivfile.write('swaplist = {0}\n'.format(individ.swaplist))
    #Write additional structure information
    indivfile.write('bulki\n')
    write_xyz(indivfile, individ.bulki)
    indivfile.write('bulki cell = {0}\n'.format(get_atom_cell(individ.bulki)))
    indivfile.write('bulko\n')
    write_xyz(indivfile, individ.bulko)
    indivfile.write('bulko cell = {0}\n'.format(get_atom_cell(individ.bulko)))
    indivfile.write('box\n')
    write_xyz(indivfile, individ.box)
    indivfile.write('box cell = {0}\n'.format(get_atom_cell(individ.box)))
    indivfile.write('vacancies\n')
    write_xyz(indivfile, individ.vacancies)
    indivfile.write('vacancies cell = {0}\n'.format(get_atom_cell(individ.vacancies)))
    indivfile.write('swaps\n')
    write_xyz(indivfile, individ.swaps)
    indivfile.write('swaps cell = {0}\n'.format(get_atom_cell(individ.swaps)))
    indivfile.write('Finish')
    indivfile.close()
    return
Ejemplo n.º 12
0
                'Error attempting to load back up cxTP Crossover.  Something very wrong!! {1}'
                .format(e),
                exc_info=True)
            print 'CXTP Name Error: ', e
        except Exception, e:
            logger.error('Error in cxtp Crossover {0}'.format(e),
                         exc_info=True)
            print 'Exception: ', e
    if passflag:
        child1 = nchild1
        child2 = nchild2
        child1.energy = 0
        child2.energy = 0
        child1.fitness = 0
        child2.fitness = 0
        ch1hi = child1.history_index
        child1.history_index = '(' + repr(child1.index) + '+' + repr(
            child2.index) + ')'
        child2.history_index = '(' + repr(child2.index) + '+' + repr(
            child1.index) + ')'
    if debug:
        s1 = child1[0].copy()
        s2 = child2[0].copy()
        if Optimizer.structure == 'Defect':
            s1.extend(child1.bulki.copy())
            s2.extend(child2.bulki.copy())
        write_xyz(Optimizer.debugfile, s1, 'First Cx Individual - Post')
        write_xyz(Optimizer.debugfile, s2, 'Second Cx Individual - Post')

    return child1, child2
Ejemplo n.º 13
0
# Set up calculator
parcoff = '* * SiC.edip C Si' 
pair_coeff = [parcoff]
mass = ['1 12.011','2 28.0855']
parameters = { 'pair_style' : 'edip', 'pair_coeff' : pair_coeff , 'mass' : mass, 'newton': 'on' }
mincomd = '1e-8 1e-8 5000 10000'
parameters['minimize'] = mincomd
filesL = [ 'SiC.edip' ]
calc = LAMMPS(parameters=parameters, files=filesL)

# Read File
structure = read_xyz('indiv00.xyz',-1)

# Calculate Energy
structure.set_cell([13.092,13.092,13.092])
structure.set_pbc(True)
structure.set_calculator(calc)
OUT=structure.calc.calculate(structure)
totalsol=OUT['atoms']
totalsol.set_pbc(True)
en=OUT['thermo'][-1]['pe']
#Write Relaxed Structure
write_xyz('re-relaxed.xyz',totalsol,repr(en))
fe = en
for sym,u in [('C',-7.371),('Si',-5.3062)]:
	nc=len([atm for atm in structure if atm.symbol==sym])
	fe-= float(nc)*float(u)
print 'SiC Interstitial'
print '    Potential Energy = '+repr(en)
print '    Formation Energy = '+repr(fe)
Ejemplo n.º 14
0
            nchild1, nchild2 = cxtp(child1, child2, Optimizer)
            passflag = True
        except NameError, e:
            logger.error(
                "Error attempting to load back up cxTP Crossover.  Something very wrong!! {1}".format(e), exc_info=True
            )
            print "CXTP Name Error: ", e
        except Exception, e:
            logger.error("Error in cxtp Crossover {0}".format(e), exc_info=True)
            print "Exception: ", e
    if passflag:
        child1 = nchild1
        child2 = nchild2
        child1.energy = 0
        child2.energy = 0
        child1.fitness = 0
        child2.fitness = 0
        ch1hi = child1.history_index
        child1.history_index = "(" + repr(child1.index) + "+" + repr(child2.index) + ")"
        child2.history_index = "(" + repr(child2.index) + "+" + repr(child1.index) + ")"
    if debug:
        s1 = child1[0].copy()
        s2 = child2[0].copy()
        if Optimizer.structure == "Defect":
            s1.extend(child1.bulki.copy())
            s2.extend(child2.bulki.copy())
        write_xyz(Optimizer.debugfile, s1, "First Cx Individual - Post")
        write_xyz(Optimizer.debugfile, s2, "Second Cx Individual - Post")

    return child1, child2
Ejemplo n.º 15
0
    'pair_style': 'edip',
    'pair_coeff': pair_coeff,
    'mass': mass,
    'newton': 'on'
}
mincomd = '1e-8 1e-8 5000 10000'
parameters['minimize'] = mincomd
filesL = ['SiC.edip']
calc = LAMMPS(parameters=parameters, files=filesL)

# Read File
structure = read_xyz('indiv00.xyz', -1)

# Calculate Energy
structure.set_cell([13.092, 13.092, 13.092])
structure.set_pbc(True)
structure.set_calculator(calc)
OUT = structure.calc.calculate(structure)
totalsol = OUT['atoms']
totalsol.set_pbc(True)
en = OUT['thermo'][-1]['pe']
#Write Relaxed Structure
write_xyz('re-relaxed.xyz', totalsol, repr(en))
fe = en
for sym, u in [('C', -7.371), ('Si', -5.3062)]:
    nc = len([atm for atm in structure if atm.symbol == sym])
    fe -= float(nc) * float(u)
print 'SiC Interstitial'
print '    Potential Energy = ' + repr(en)
print '    Formation Energy = ' + repr(fe)
Ejemplo n.º 16
0
def find_defects(solid,
                 bulko,
                 rcutoff,
                 atomlistcheck=False,
                 trackvacs=False,
                 trackswaps=False,
                 debug=False,
                 dcheck=0.6):
    """Function to find interstitials, vacancies, and substitutional atoms (swaps) in a defected structure.
    Identifies species by comparison to perfect structure.
    Inputs:
        solid = ASE atoms class for defected structure
        bulko = ASE atoms class for perfect structure
        rcutoff = float value of distance to surrounding atoms to include
        atomlistcheck = False/list of atom types and concentrations according to atomlist format
        trackvacs = True/False whether or not to identify vacancies in defect
        trackswaps = True/False whether or not to identify substitutional defects
        debug = False/file object to write debug structures"""
    # Combine perfect and defect structures together
    b = bulko.copy()
    b.extend(solid)
    b.set_pbc(True)
    #Debug: Write solid and bulko to file
    if debug:
        print len(bulko)
        write_xyz(debug, b, 'Find Ints: Solid and Bulko')
    # Identify nearest neighbor atoms for each atom in perfect structure
    ntot = len(bulko)
    ctoff1 = [1.2 for one in b]
    nl = NeighborList(ctoff1, bothways=True, self_interaction=False)
    nl.update(b)
    slist = []
    blist = []
    wlist = []
    #Loop over each atom in perfect structure
    for one in range(ntot):
        indices, offsets = nl.get_neighbors(one)
        for index, d in zip(indices, offsets):
            index = int(index)
            if index >= ntot:
                pos = b[index].position + numpy.dot(d, bulko.get_cell())
                natm1 = Atom(position=pos)
                dist, dx, dy, dz = calc_dist(b[one], natm1)
                if dist <= dcheck:
                    #Assume atoms closer than 0.6 Angstroms to be equivalent
                    slist.append(index - ntot)
                    blist.append(one)
                    if b[one].symbol == b[index].symbol:
                        wlist.append(index - ntot)
    #Identify those atoms corresponding to interstitials, vacancies, and substitutions
    oslist = [atm.index for atm in solid if atm.index not in slist]
    vlist = [atm.index for atm in bulko if atm.index not in blist]
    swlist = [
        atm.index for atm in solid
        if atm.index not in wlist and atm.index not in oslist
    ]
    # Create Atoms objects for each identified defect
    ntot = len(solid)
    cluster = Atoms()
    for one in oslist:
        cluster.append(solid[one])
    vacant = Atoms()
    if trackvacs == True:
        for one in vlist:
            vacant.append(
                Atom(symbol=bulko[one].symbol, position=bulko[one].position))
            solid.append(Atom(symbol='X', position=bulko[one].position))
            oslist.append(len(solid) - 1)
        stro = 'Cluster Identified with length = {0}\nIdentified {1} vacancies\n'.format(
            len(cluster), len(vlist))
    swaps = Atoms()
    if trackswaps == True:
        for one in swlist:
            swaps.append(solid[one])
            oslist.append(one)
        stro = 'Cluster Identified with length = {0}\nIdentified {1} swaps\n'.format(
            len(cluster), len(swlist))
    else:
        stro = 'Cluster Identified with length = {0}\n'.format(len(cluster))
    #Debug: write cluster to file
    if debug:
        b = cluster.copy()
        write_xyz(debug, b, 'Find Ints: Cluster')
        debug.flush()
        print 'Found cluster size = ', len(b)
    # Identify atoms surrounding the identified defects in the defected structure
    box = Atoms()
    bulki = Atoms()
    if rcutoff != 0:
        if rcutoff > 2.0:
            cutoffs = [rcutoff for one in solid]
        else:
            cutoffs = [2.0 for one in solid]
        solid.set_pbc(True)
        nl = NeighborList(cutoffs, bothways=True, self_interaction=False)
        nl.update(solid)
        nbatmsd = []
        repinds = []
        for one in oslist:
            if one not in repinds:
                if one < ntot:
                    nbatmsd.append((0, one))
                    repinds.append(one)
        for one in oslist:
            indices, offsets = nl.get_neighbors(one)
            for index, d in zip(indices, offsets):
                index = int(index)
                if index not in repinds and index < ntot:
                    opos = copy.copy(solid[index].position)
                    solid[index].position = solid[index].position + numpy.dot(
                        d, solid.get_cell())
                    dist = solid.get_distance(one, index)
                    solid[index].position = opos
                    if dist <= rcutoff:
                        nbatmsd.append((dist, index))
                        repinds.append(index)
    else:
        nbatmsd = []
        repinds = []
        for one in oslist:
            if one not in repinds:
                if one < ntot:
                    nbatmsd.append((0, one))
                    repinds.append(one)
    nbatmsd = sorted(nbatmsd, key=lambda one: one[0], reverse=True)
    indices = []
    natomsbox = 0
    # Select only atoms closest to defects that satisfy concentrations specified by atomlist given in atomlistcheck
    if atomlistcheck:
        for sym, c, m, u in atomlistcheck:
            i = 0
            nbsym = [one for one in nbatmsd if solid[one[1]].symbol == sym]
            if len(nbsym) > c:
                while i < c:
                    a = nbsym.pop()
                    box.append(solid[a[1]])
                    indices.append(a[1])
                    i += 1
            else:
                for a in nbsym:
                    box.append(solid[a[1]])
                    indices.append(a[1])
                    i += 1
                if len(box) - natomsbox < c:
                    try:
                        while True:
                            for n in range(len(nbatmsd) - 1, -1, -1):
                                inds, offsets = nl.get_neighbors(nbatmsd[n][1])
                                for one, d in zip(inds, offsets):
                                    if len(box) - natomsbox < c:
                                        if one not in indices and one < ntot and solid[
                                                one].symbol == sym:
                                            opos = copy.copy(
                                                solid[one].position)
                                            solid[one].position = solid[
                                                one].position + numpy.dot(
                                                    d, solid.get_cell())
                                            dist = solid.get_distance(
                                                nbatmsd[n][1], one)
                                            solid[one].position = opos
                                            if dist <= rcutoff * 5.0:
                                                box.append(solid[one])
                                                indices.append(one)
                                    else:
                                        raise StopIteration()
                                for one, d in zip(inds, offsets):
                                    if len(box) - natomsbox < c:
                                        if one not in indices and one < ntot and solid[
                                                one].symbol == sym:
                                            opos = copy.copy(
                                                solid[one].position)
                                            solid[one].position = solid[
                                                one].position + numpy.dot(
                                                    d, solid.get_cell())
                                            dist = solid.get_distance(
                                                nbatmsd[n][1], one)
                                            solid[one].position = opos
                                            box.append(solid[one])
                                            indices.append(one)
                                    else:
                                        raise StopIteration()
                    except StopIteration:
                        pass
            natomsbox = len(box)
        #Double check for sanity
        for sym, c, m, u in atomlistcheck:
            symsbox = [one for one in box if one.symbol == sym]
            if len(symsbox) != c:
                stro += 'WARNING!!!! : FAILURE IN FIND_DEFECTS TO MATCH PROVIDED ATOMLIST. DEBUG!!!!\n'
    # If atomlistcheck is False then use all the atoms in the given cutoff distance
    else:
        for a in nbatmsd:
            box.append(solid[a[1]])
            indices.append(a[1])
    # Add remaining atoms in defect to defected bulk atoms object
    for one in range(len(solid)):
        if one not in indices and one < ntot:
            bulki.append(solid[one])
    #Check for accidental vacancy admissions
    #checklist=[atm for atm in box if atm.symbol=='X']
    #checklist.extend([atm for atm in bulki if atm.symbol=='X'])
    #Set up new individual
    indiv = box.copy()
    bulki.set_cell(bulko.get_cell())
    indiv.set_cell(bulko.get_cell())
    bulki.set_pbc(True)
    indiv.set_pbc(True)
    stro += 'Atomlist check = {0}\n'.format(atomlistcheck)
    stro += 'Bulko = {0}\n'.format(bulko)
    stro += 'New individual ({0} atoms) : {1}\n'.format(len(indiv), indiv)
    stro += 'New bulki ({0} atoms) : {1}\n'.format(len(bulki), bulki)
    #Debug: write new indiv to file
    if debug:
        b = indiv.copy()
        write_xyz(debug, b, 'Find Ints: New Individual')
        #Debug: write new bulki to file
        b = bulki.copy()
        write_xyz(debug, b, 'Find Ints: New Bulki')
        debug.flush()
        print len(bulko)

    return indiv, bulki, vacant, swaps, stro
Ejemplo n.º 17
0
def find_defects(solid, bulko, rcutoff, atomlistcheck=False, trackvacs=False, trackswaps=False, debug=False, dcheck = 0.6):
    """Function to find interstitials, vacancies, and substitutional atoms (swaps) in a defected structure.
    Identifies species by comparison to perfect structure.
    Inputs:
        solid = ASE atoms class for defected structure
        bulko = ASE atoms class for perfect structure
        rcutoff = float value of distance to surrounding atoms to include
        atomlistcheck = False/list of atom types and concentrations according to atomlist format
        trackvacs = True/False whether or not to identify vacancies in defect
        trackswaps = True/False whether or not to identify substitutional defects
        debug = False/file object to write debug structures"""
    # Combine perfect and defect structures together
    b = bulko.copy()
    b.extend(solid)
    b.set_pbc(True)
    #Debug: Write solid and bulko to file
    if debug:
        print len(bulko)
        write_xyz(debug,b,'Find Ints: Solid and Bulko')
    # Identify nearest neighbor atoms for each atom in perfect structure
    ntot = len(bulko)
    ctoff1 = [1.2 for one in b]
    nl = NeighborList(ctoff1, bothways=True, self_interaction=False)
    nl.update(b)
    slist = []
    blist = []
    wlist = []
    #Loop over each atom in perfect structure
    for one in range(ntot):
        indices, offsets = nl.get_neighbors(one)
        for index, d in zip(indices,offsets):
            index = int(index)
            if index >= ntot:
                pos = b[index].position + numpy.dot(d,bulko.get_cell())
                natm1 = Atom(position=pos)
                dist, dx, dy, dz = calc_dist(b[one],natm1)
                if dist <= dcheck:
                    #Assume atoms closer than 0.6 Angstroms to be equivalent
                    slist.append(index-ntot)
                    blist.append(one)
                    if b[one].symbol == b[index].symbol:
                        wlist.append(index-ntot)
    #Identify those atoms corresponding to interstitials, vacancies, and substitutions
    oslist = [atm.index for atm in solid if atm.index not in slist]
    vlist = [atm.index for atm in bulko if atm.index not in blist]
    swlist = [atm.index for atm in solid if atm.index not in wlist and atm.index not in oslist]
    # Create Atoms objects for each identified defect
    ntot = len(solid)
    cluster = Atoms()
    for one in oslist:
        cluster.append(solid[one])
    vacant = Atoms()
    if trackvacs==True:
        for one in vlist:
            vacant.append(Atom(symbol=bulko[one].symbol, position=bulko[one].position))
            solid.append(Atom(symbol='X', position=bulko[one].position))
            oslist.append(len(solid)-1)
        stro = 'Cluster Identified with length = {0}\nIdentified {1} vacancies\n'.format(len(cluster),len(vlist))
    swaps = Atoms()
    if trackswaps==True:
        for one in swlist:
            swaps.append(solid[one])
            oslist.append(one)
        stro = 'Cluster Identified with length = {0}\nIdentified {1} swaps\n'.format(len(cluster),len(swlist))
    else:
        stro = 'Cluster Identified with length = {0}\n'.format(len(cluster))
    #Debug: write cluster to file
    if debug:
        b = cluster.copy()
        write_xyz(debug,b,'Find Ints: Cluster')
        debug.flush()
        print 'Found cluster size = ',len(b)
    # Identify atoms surrounding the identified defects in the defected structure
    box=Atoms()
    bulki=Atoms()
    if rcutoff != 0:
        if rcutoff > 2.0:
            cutoffs = [rcutoff for one in solid]
        else:
            cutoffs = [2.0 for one in solid]
        solid.set_pbc(True)
        nl = NeighborList(cutoffs,bothways=True,self_interaction=False)
        nl.update(solid)
        nbatmsd = []
        repinds = []
        for one in oslist:
            if one not in repinds:
                if one < ntot:
                    nbatmsd.append((0,one))
                    repinds.append(one)
            indices, offsets = nl.get_neighbors(one)
            for index,d in zip(indices,offsets):
                index = int(index)
                if index not in repinds and index < ntot:
                    opos = copy.copy(solid[index].position)
                    solid[index].position = solid[index].position + numpy.dot(d,solid.get_cell())
                    dist = solid.get_distance(one,index)
                    solid[index].position = opos
                    if dist <= rcutoff:
                        nbatmsd.append((dist,index))
                        repinds.append(index)
    else:
        nbatmsd = []
        repinds = []
        for one in oslist:
            if one not in repinds:
                if one < ntot:
                    nbatmsd.append((0,one))
                    repinds.append(one)
    nbatmsd=sorted(nbatmsd, key=lambda one:one[0], reverse=True)
    indices=[]
    i=0
    # Select only atoms closest to defects that satisfy concentrations specified by atomlist given in atomlistcheck
    if atomlistcheck:
        natomsbox=sum([c for sym,c,m,u in atomlistcheck])
        if len(nbatmsd) > natomsbox:
            while i<natomsbox:
                a=nbatmsd.pop()
                box.append(solid[a[1]])
                indices.append(a[1])
                i+=1
        elif len(nbatmsd) <= natomsbox:
            for a in nbatmsd:
                box.append(solid[a[1]])
                indices.append(a[1])
                i+=1
            if len(box) < natomsbox:
                try:
                    while True:
                        for n in range(len(nbatmsd)-1,-1,-1):
                            inds, offsets=nl.get_neighbors(nbatmsd[n][1])
                            for one,d in zip(inds,offsets):
                                if len(box) < natomsbox:
                                    if one not in indices and one < ntot:
                                        opos = copy.copy(solid[one].position)
                                        solid[one].position = solid[one].position + numpy.dot(d,solid.get_cell())
                                        dist = solid.get_distance(nbatmsd[n][1],one)
                                        solid[one].position = opos
                                        if dist <= rcutoff*5.0:
                                            box.append(solid[one])
                                            indices.append(one)
                                else:
                                    raise StopIteration()
                            for one,d in zip(inds,offsets):
                                if len(box) < natomsbox:
                                    if one not in indices and one < ntot:
                                        opos = copy.copy(solid[one].position)
                                        solid[one].position = solid[one].position + numpy.dot(d,solid.get_cell())
                                        dist = solid.get_distance(nbatmsd[n][1],one)
                                        solid[one].position = opos
                                        box.append(solid[one])
                                        indices.append(one)
                                else:
                                    raise StopIteration()
                except StopIteration:
                    pass
    # If atomlistcheck is False then use all the atoms in the given cutoff distance
    else:
        for a in nbatmsd:
            box.append(solid[a[1]])
            indices.append(a[1])
    # Add remaining atoms in defect to defected bulk atoms object
    for one in range(len(solid)):
        if one not in indices and one < ntot:
            bulki.append(solid[one])
    #Check for accidental vacancy admissions
    #checklist=[atm for atm in box if atm.symbol=='X']
    #checklist.extend([atm for atm in bulki if atm.symbol=='X'])
    #Set up new individual
    indiv=box.copy()
    bulki.set_cell(bulko.get_cell())
    indiv.set_cell(bulko.get_cell())
    bulki.set_pbc(True)
    indiv.set_pbc(True)
    stro+='New individual ({0} atoms) : {1}\n'.format(len(indiv), indiv)
    stro+='New bulki ({0} atoms) : {1}\n'.format(len(bulki), bulki)
    #Debug: write new indiv to file
    if debug:
        b=indiv.copy()
        write_xyz(debug,b,'Find Ints: New Individual')
        #Debug: write new bulki to file
        b=bulki.copy()
        write_xyz(debug,b,'Find Ints: New Bulki')
        debug.flush()
        print len(bulko)
    
    return indiv,bulki,vacant,swaps,stro
Ejemplo n.º 18
0
def BestInds(pop, bests, Optimizer, writefile=False, fname=None):
    """Function to keep track of the best individuals throughout an optimization
    Inputs:
        pop = list of Individual class structures to be compared
        bests = list of previously obtained best structures
        Optimizer = Optimizer class structure that contains key parameters
        writefile = True/False boolean to tell function whether or not to output structures
        fname = filename to output structures
    Outputs:
        bests = list of Individual class structures updated with new options
    """
    #logger = initialize_logger(Optimizer.loggername)
    logger = logging.getLogger(Optimizer.loggername)
    logger.info(
        'best_inds_list recieved population with length = {0} and best list with length = {1} for generation {2}'
        .format(len(pop), len(bests), Optimizer.generation))
    pop = sorted(pop, key=attrgetter('fitness'))
    tol = Optimizer.demin
    if len(bests) != 0:
        bfits = [ind.fitness for ind in bests]
        #Identify the fitnesses in the population
        popfits = [ind.fitness for ind in pop]
        #Initialize a list for individuals to not be added to best list
        indices = []
        for i in range(len(popfits)):
            for j in range(len(bfits)):
                if popfits[i] == bfits[j]:
                    indices.append(i)
                if popfits[i] < bfits[j]:
                    diff = abs(bfits[j] - popfits[i])
                    diff2 = abs(bfits[j - 1] - popfits[i])
                    if diff > tol:
                        if diff2 > tol:
                            if i not in indices:
                                bests.append(pop[i])
                                logger.info(
                                    'Best list found new structure for List HI = {0}'
                                    .format(pop[i].history_index))
                                indices.append(i)
                                b = bfits[0:j]
                                b.append(pop[i].fitness)
                                b.extend(bfits[j::])
                                bfits = b
                        else:
                            indices.append(i)
        bests = sorted(bests, key=attrgetter('fitness'))
        if len(bests) < Optimizer.number_of_bests:
            bmax = bests[len(bests) - 1].fitness
            for i in range(len(popfits)):
                if popfits[i] > bmax:
                    diff = abs(popfits[i] - bmax)
                    if diff > tol:
                        bests.append(pop[i])
                        logger.info(
                            'Appending best list with lower energy structure')
                        bmax = pop[i].fitness
        else:
            logger.info('Removing extra {0} structures from best list'.format(
                len(bests) - Optimizer.number_of_bests))
            bests = bests[0:Optimizer.number_of_bests]
        bfits = [ind.fitness for ind in bests]
    else:
        bests = []
        bfits = []
        for one in pop:
            fit = one.fitness
            if len(bfits) == 0:
                bests.append(one)
                logger.info(
                    'Adding new structure to best list HI = {0}'.format(
                        one.history_index))
                bfits.append(fit)
            else:
                diff = abs(bfits[-1] - fit)
                if diff > tol:
                    bests.append(one)
                    bfits.append(fit)
        if len(bests) > Optimizer.number_of_bests:
            logger.info('Removing extra {0} structures from best list'.format(
                len(bests) - Optimizer.number_of_bests))
            bests = bests[0:Optimizer.number_of_bests]
    if writefile == True:
        if fname == None:
            try:
                rank = MPI.COMM_WORLD.Get_rank()
            except:
                rank = 0
            path = os.path.join(os.getcwd(),
                                '{0}-rank{1}'.format(Optimizer.filename, rank))
            logger.info('Writing Best lists to {0}'.format(path))
            fxyzname = os.path.join(path,
                                    'Bests-{0}.xyz'.format(Optimizer.filename))
            ffitname = os.path.join(
                path, 'Bests-fitnesses-{0}.txt'.format(Optimizer.filename))
        else:
            fxyzname = '{0}.xyz'.format(fname)
            ffitname = '{0}-fitnesses.txt'.format(fname)
        bestfile = open(fxyzname, 'w')
        bestfitfile = open(ffitname, 'w')
        for one in bests:
            if Optimizer.structure == 'Defect':
                cbulk = Atoms()
                cbulk.extend(one[0])
                cbulk.extend(one.bulki)
                write_xyz(bestfile, cbulk, one.energy)
            else:
                write_xyz(bestfile, one[0], one.energy)
            bestfitfile.write(repr(one.fitness) + '\n')
        bestfile.close()
        bestfitfile.close()
    return bests
Ejemplo n.º 19
0
def write_individual(individ, indivfile):
    """Function to write the data of an individual class object to a flat file
    Input:
        individ = Individual class object to be written
        indivfile = String or fileobject for file to be written to 
    Output:
        No output returned.  Information is written to file
    """
    if isinstance(indivfile, str):
        indivfile = open(indivfile, 'a')
    #Write break
    indivfile.write('----------\n')
    #Write structure information
    indivfile.write('Structure information\n')
    write_xyz(indivfile, individ[0])
    indivfile.write('structure cell = {0}\n'.format(get_atom_cell(individ[0])))
    #Write additional information
    indivfile.write('fitness = {0}\n'.format(individ.fitness))
    indivfile.write('index = {0}\n'.format(individ.index))
    indivfile.write('history_index = {0}\n'.format(individ.index))
    indivfile.write('energy = {0}\n'.format(individ.energy))
    indivfile.write('tenergymx = {0}\n'.format(individ.tenergymx))
    indivfile.write('tenergymin = {0}\n'.format(individ.tenergymin))
    indivfile.write('pressure = {0}\n'.format(individ.pressure))
    indivfile.write('volume = {0}\n'.format(individ.volume))
    indivfile.write('force = {0}\n'.format(individ.force))
    indivfile.write('purebulkenpa = {0}\n'.format(individ.purebulkenpa))
    indivfile.write('natomsbulk = {0}\n'.format(individ.natomsbulk))
    indivfile.write('fingerprint = {0}\n'.format(individ.fingerprint))
    indivfile.write('swaplist = {0}\n'.format(individ.swaplist))
    #Write additional structure information
    indivfile.write('bulki\n')
    write_xyz(indivfile, individ.bulki)
    indivfile.write('bulki cell = {0}\n'.format(get_atom_cell(individ.bulki)))
    indivfile.write('bulko\n')
    write_xyz(indivfile, individ.bulko)
    indivfile.write('bulko cell = {0}\n'.format(get_atom_cell(individ.bulko)))
    indivfile.write('box\n')
    write_xyz(indivfile, individ.box)
    indivfile.write('box cell = {0}\n'.format(get_atom_cell(individ.box)))
    indivfile.write('vacancies\n')
    write_xyz(indivfile, individ.vacancies)
    indivfile.write('vacancies cell = {0}\n'.format(
        get_atom_cell(individ.vacancies)))
    indivfile.write('swaps\n')
    write_xyz(indivfile, individ.swaps)
    indivfile.write('swaps cell = {0}\n'.format(get_atom_cell(individ.swaps)))
    indivfile.write('Finish')
    indivfile.close()
    return
Ejemplo n.º 20
0
def formationenergy(indiv, Optimizer):
    """Function to calculate formation energy fitness of individual.
    Input:
        indiv = structopt Individual class object to be evaluated
        Optimizer = structopt Optimizer class object
    Output:
        indiv = structopt Individual class object with new fitness.
    """
    if Optimizer.structure != 'Defect':
        if Optimizer.generation <1:
            print 'WARNING: Formation Energy fitness calculator only available for Defect structure simulation.'
            print '     Using total energy fitness calculator instead'
        indiv = totalenfit(indiv,Optimizer)
        stro = ''
    else:
        logger = logging.getLogger(Optimizer.loggername)
        #logger = initialize_logger(Optimizer.loggername)
        starting = indiv.duplicate()
        cwd = os.getcwd()
        try:
            outs = eval_energy(Optimizer,indiv)
        except Exception, e:
            logger.warn('Error in energy evaluation: {0}'.format(e), exc_info=True)
            stro = 'ERROR: Problem in Energy Evaluation'
            print stro
            print e
            stro += '\n' + repr(e)
            os.chdir(cwd)
            f=open('problem-structures.xyz','a')
            totalsol = indiv[0].copy()
            totalsol.extend(indiv.bulki)
            write_xyz(f,totalsol,data='Starting structure hindex={0}'.format(indiv.history_index))
            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.energy = outs[0]
        stro=outs[3]
        indiv.bulki = outs[1]
        #fit = (indiv.purebulkenpa*(indiv[0].get_number_of_atoms()+indiv.bulki.get_number_of_atoms()) - indiv.energy)/(indiv[0].get_number_of_atoms()+indiv.bulki.get_number_of_atoms()-indiv.natomsbulk)
        solid=Atoms()
        solid.extend(indiv[0])
        solid.extend(indiv.bulki)
        fit=indiv.energy
        passflag = True
        if abs(fit) > Optimizer.energy_cutoff_factor*(len(indiv[0])+len(indiv.bulki)):
            fit=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'
            passflag=False
        if math.isnan(fit):
            logger.warn('Found NAN energy structure HI={0}'.format(indiv.history_index))
            fit=10000
            passflag=False
            indiv.energy = 10000
        if passflag:
            for sym,c,m,u in Optimizer.atomlist:
                nc=len([atm for atm in solid if atm.symbol==sym])
                fit-= float(nc)*float(u)
        indiv.fitness=fit
Ejemplo n.º 21
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
Ejemplo n.º 22
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
Ejemplo n.º 23
0
def BestInds(pop, bests, Optimizer, writefile=False, fname=None):
    """Function to keep track of the best individuals throughout an optimization
    Inputs:
        pop = list of Individual class structures to be compared
        bests = list of previously obtained best structures
        Optimizer = Optimizer class structure that contains key parameters
        writefile = True/False boolean to tell function whether or not to output structures
        fname = filename to output structures
    Outputs:
        bests = list of Individual class structures updated with new options
    """
    #logger = initialize_logger(Optimizer.loggername)
    logger = logging.getLogger(Optimizer.loggername)
    logger.info('best_inds_list recieved population with length = {0} and best list with length = {1} for generation {2}'.format(
        len(pop),len(bests),Optimizer.generation))
    pop = sorted(pop, key=attrgetter('fitness'))
    tol=Optimizer.demin
    if len(bests)!=0:
        bfits=[ind.fitness for ind in bests]
        #Identify the fitnesses in the population
        popfits=[ind.fitness for ind in pop]
        #Initialize a list for individuals to not be added to best list
        indices=[]
        for i in range(len(popfits)):
            for j in range(len(bfits)):
                if popfits[i]==bfits[j]:
                    indices.append(i)
                if popfits[i] < bfits[j]:
                    diff = abs(bfits[j] - popfits[i])
                    diff2 = abs(bfits[j-1] - popfits[i])
                    if diff > tol:
                        if diff2 > tol:
                            if i not in indices:
                                bests.append(pop[i])
                                logger.info('Best list found new structure for List HI = {0}'.format(pop[i].history_index))
                                indices.append(i)
                                b=bfits[0:j]
                                b.append(pop[i].fitness)
                                b.extend(bfits[j::])
                                bfits=b
                        else:
                            indices.append(i)
        bests = sorted(bests, key=attrgetter('fitness'))
        if len(bests) < Optimizer.number_of_bests:
            bmax = bests[len(bests)-1].fitness
            for i in range(len(popfits)):
                if popfits[i] > bmax:
                    diff = abs(popfits[i]-bmax)
                    if diff > tol:
                        bests.append(pop[i])
                        logger.info('Appending best list with lower energy structure')
                        bmax = pop[i].fitness
        else:
            logger.info('Removing extra {0} structures from best list'.format(len(bests)-Optimizer.number_of_bests))
            bests = bests[0:Optimizer.number_of_bests]
        bfits=[ind.fitness for ind in bests]
    else:
        bests = []
        bfits = []
        for one in pop:
            fit = one.fitness
            if len(bfits) == 0:
                bests.append(one)
                logger.info('Adding new structure to best list HI = {0}'.format(one.history_index))
                bfits.append(fit)
            else:
                diff = abs(bfits[-1]-fit)
                if diff > tol:
                    bests.append(one)
                    bfits.append(fit)
        if len(bests) > Optimizer.number_of_bests:
            logger.info('Removing extra {0} structures from best list'.format(len(bests)-Optimizer.number_of_bests))
            bests = bests[0:Optimizer.number_of_bests]
    if Optimizer.generation % 10 == 0:
      if writefile==True:
        if fname==None:
            try:
                rank = MPI.COMM_WORLD.Get_rank()
            except:
                rank = 0
            path = os.path.join(os.getcwd(),'{0}-rank{1}'.format(Optimizer.filename,rank))
            logger.info('Writing Best lists to {0}'.format(path))
            fxyzname=os.path.join(path,'Bests-{0}.xyz'.format(Optimizer.filename))
            ffitname=os.path.join(path,'Bests-fitnesses-{0}.txt'.format(Optimizer.filename))
        else:
            fxyzname='{0}.xyz'.format(fname)
            ffitname='{0}-fitnesses.txt'.format(fname)
        bestfile=open(fxyzname,'w')
        bestfitfile=open(ffitname,'w')
        for one in bests:
            if Optimizer.structure=='Defect':
                cbulk=Atoms()
                cbulk.extend(one[0])
                cbulk.extend(one.bulki)
                write_xyz(bestfile,cbulk,one.energy)
            else:
                write_xyz(bestfile,one[0],one.energy)
            bestfitfile.write(repr(one.fitness)+'\n')
        bestfile.close()
        bestfitfile.close()
    return bests