Example #1
0
    def __init__(self, filename):
        atoms = ase.io.read(filename, format='vasp')
        cell = atoms.get_cell()
        symb = atoms.get_atomic_numbers()

        cutoffs = np.ones(
            (len(atoms)
             )) * 1.35  # radius around each atom (half the max bondlength)
        nl = NeighborList(cutoffs, 0., self_interaction=False, bothways=False)
        nl.update(atoms)

        std_len = 2.35805097505

        # Loop over atoms
        bond_no = 0
        bonds = np.zeros((nl.nneighbors, 4))

        for atom1idx, (indices, offsets, atom1pos) in enumerate(
                zip(nl.neighbors, nl.displacements, nl.positions)):
            # Loop over bonds
            for atom2idx, offset in zip(indices, offsets):
                #if symb[atom1idx] == symb[atom2idx] == 'Si':
                atom2pos = nl.positions[atom2idx] + np.dot(offset, cell)
                #print "pos[%i] = %.2f %.2f %.2f" % (atom1idx, atom1pos[0],atom1pos[1],atom1pos[2])
                #print "pos[%i] = %.2f %.2f %.2f" % (atom2idx, atom2pos[0],atom2pos[1],atom2pos[2])
                bond = atom2pos - atom1pos
                bond_center = atom1pos + bond / 2.
                bond_z = bond_center[2]
                bondlength = np.sqrt(np.dot(bond, bond))
                bonds[bond_no] = [
                    bond_z, bondlength, symb[atom1idx], symb[atom2idx]
                ]
                bond_no += 1
        self.bonds = bonds
        print bonds
Example #2
0
def find_tip_coordination(a, bondlength=2.6, bulk_nn=4):
    """
    Find position of tip in crack cluster from coordination
    """
    nl = NeighborList([bondlength / 2.0] * len(a),
                      skin=0.0,
                      self_interaction=False,
                      bothways=True)
    nl.update(a)
    nn = np.array([len(nl.get_neighbors(i)[0]) for i in range(len(a))])
    a.set_array('n_neighb', nn)
    g = a.get_array('groups')

    y = a.positions[:, 1]
    above = (nn < bulk_nn) & (g != 0) & (y > a.cell[1, 1] / 2.0)
    below = (nn < bulk_nn) & (g != 0) & (y < a.cell[1, 1] / 2.0)

    a.set_array('above', above)
    a.set_array('below', below)

    bond1 = np.asscalar(above.nonzero()[0][a.positions[above, 0].argmax()])
    bond2 = np.asscalar(below.nonzero()[0][a.positions[below, 0].argmax()])

    # These need to be ints, otherwise they are no JSON serializable.
    a.info['bond1'] = bond1
    a.info['bond2'] = bond2

    return bond1, bond2
Example #3
0
    def relax(self, individual):
        """Relaxes the individual using a hard-sphere cutoff method.
        Args:
            individual (Individual):  the individual to relax
        """
        rank = gparameters.mpi.rank
        print("Relaxing individual {} on rank {} with hard-sphere cutoff method".format(individual.id, rank))
        radii = [2.0 for atom in individual]
        nl = NeighborList(radii, bothways=True, self_interaction=False)
        nl.update(individual)

        ntries = 0
        modified = True
        while modified and ntries < 100:
            modified = False
            for atom in individual:
                indices, offsets = nl.get_neighbors(atom.index)
                for neigh in indices:
                    if individual.get_distance(atom.index, neigh) < self.cutoff:
                        individual.set_distance(atom.index, neigh, self.cutoff, fix=0.5)
                        modified = True
            nl.update(individual)
            individual.wrap()
            ntries += 1
        if ntries == 100:
            print("WARNING! Iterated through the hard-sphere cutoff relaxation 100 times and it still did not converge!")
Example #4
0
    def update(self, atoms):
        # check all the elements are available in the potential
        self.Nelements = len(self.elements)
        elements = np.unique(atoms.get_chemical_symbols())
        unavailable = np.logical_not(
            np.array([item in self.elements for item in elements]))

        if np.any(unavailable):
            raise RuntimeError('These elements are not in the potential: %s' %
                               elements[unavailable])

        # cutoffs need to be a vector for NeighborList
        cutoffs = self.cutoff * np.ones(len(atoms))

        # convert the elements to an index of the position
        # in the eam format
        self.index = np.array(
            [self.elements.index(el) for el in atoms.get_chemical_symbols()])
        self.pbc = atoms.get_pbc()

        # since we need the contribution of all neighbors to the
        # local electron density we cannot just calculate and use
        # one way neighbors
        self.neighbors = NeighborList(cutoffs,
                                      skin=self.parameters.skin,
                                      self_interaction=False,
                                      bothways=True)
        self.neighbors.update(atoms)
def calculate_image_center(atoms, watchindex, pdirs):
    """Calculates the center of the image in the pdir basis coordinates."""

    # The first moment of the image around the center atom is calculated.
    atoms = atoms.copy()
    from ase.calculators.neighborlist import NeighborList
    _nl = NeighborList(cutoffs=([6.5 / 2.] * len(atoms)),
                       self_interaction=False,
                       bothways=True,
                       skin=0.)
    _nl.update(atoms)

    position = atoms.positions[watchindex]

    # Step 1: Calculating neighbors of atom.
    n_indices, n_offsets = _nl.get_neighbors(watchindex)
    Rs = [atoms.positions[n_index] +
          np.dot(n_offset, atoms.get_cell()) - position
          for n_index, n_offset in zip(n_indices, n_offsets)]

    xtilde = 0.
    ytilde = 0.
    ztilde = 0.
    for rs in Rs:
        xtilde += rs[0] * np.dot([1, 0, 0], pdirs[0])
        xtilde += rs[1] * np.dot([0, 1, 0], pdirs[0])
        xtilde += rs[2] * np.dot([0, 0, 1], pdirs[0])
        ytilde += rs[0] * np.dot([1, 0, 0], pdirs[1])
        ytilde += rs[1] * np.dot([0, 1, 0], pdirs[1])
        ytilde += rs[2] * np.dot([0, 0, 1], pdirs[1])
        ztilde += rs[0] * np.dot([1, 0, 0], pdirs[2])
        ztilde += rs[1] * np.dot([0, 1, 0], pdirs[2])
        ztilde += rs[2] * np.dot([0, 0, 1], pdirs[2])

    return xtilde, ytilde, ztilde
Example #6
0
File: pov.py Project: lqcata/ase
def get_bondpairs(atoms, radius=1.1):
    """Get all pairs of bonding atoms

    Return all pairs of atoms which are closer than radius times the
    sum of their respective covalent radii.  The pairs are returned as
    tuples::

      (a, b, (i1, i2, i3))

    so that atoms a bonds to atom b displaced by the vector::

        _     _     _
      i c + i c + i c ,
       1 1   2 2   3 3

    where c1, c2 and c3 are the unit cell vectors and i1, i2, i3 are
    integers."""
    
    from ase.data import covalent_radii
    from ase.calculators.neighborlist import NeighborList
    cutoffs = radius * covalent_radii[atoms.numbers]
    nl = NeighborList(cutoffs=cutoffs, self_interaction=False)
    nl.update(atoms)
    bondpairs = []
    for a in range(len(atoms)):
        indices, offsets = nl.get_neighbors(a)
        bondpairs.extend([(a, a2, offset)
                          for a2, offset in zip(indices, offsets)])
    return bondpairs
def get_fingerprints(atoms):
    elements =['O','Ru']
    Gs = make_symmetry_functions(elements)
    fp = np.zeros([2, len(Gs['O'])])
    cutoff ={'name': 'Cosine', 'kwargs': {'Rc': 6.5}}
    cutoff_globle = 6.5
    _nl = NeighborList(cutoffs=([cutoff_globle / 2.] *
                                len(atoms)),
                       self_interaction=False,
                       bothways=True,
                       skin=0.)
    _nl.update(atoms)

    amp_obj = FingerprintCalculator(neighborlist=_nl, Gs=Gs, cutoff=cutoff,fortran=False)
    amp_obj.initialize(fortran=False,atoms=atoms)
    n=0
    fingerprint = []
    for index in range(12,14):
        symbol = atoms[index].symbol
        neighborindices, neighboroffsets = _nl.get_neighbors(index)
        neighborsymbols = [atoms[_].symbol for _ in neighborindices]
        neighborpositions = [atoms.positions[neighbor] + np.dot(offset, atoms.cell)
                             for (neighbor, offset) in zip(neighborindices,
                                                           neighboroffsets)]
        indexfp = amp_obj.get_fingerprint(
            index, symbol, neighborsymbols, neighborpositions)
        fp[n] = indexfp[1]
        n = n+1
    return fp
Example #8
0
    def bind(self, frame):
        if not self.ui.get_widget('/MenuBar/ViewMenu/ShowBonds').get_active():
            self.bonds = np.empty((0, 5), int)
            return

        from ase.atoms import Atoms
        from ase.calculators.neighborlist import NeighborList
        nl = NeighborList(self.images.r * 1.5, skin=0, self_interaction=False)
        nl.update(
            Atoms(positions=self.images.P[frame],
                  cell=(self.images.repeat[:, np.newaxis] *
                        self.images.A[frame]),
                  pbc=self.images.pbc))
        nb = nl.nneighbors + nl.npbcneighbors
        self.bonds = np.empty((nb, 5), int)
        if nb == 0:
            return

        n1 = 0
        for a in range(self.images.natoms):
            indices, offsets = nl.get_neighbors(a)
            n2 = n1 + len(indices)
            self.bonds[n1:n2, 0] = a
            self.bonds[n1:n2, 1] = indices
            self.bonds[n1:n2, 2:] = offsets
            n1 = n2

        i = self.bonds[:n2, 2:].any(1)
        self.bonds[n2:, 0] = self.bonds[i, 1]
        self.bonds[n2:, 1] = self.bonds[i, 0]
        self.bonds[n2:, 2:] = -self.bonds[i, 2:]
Example #9
0
File: opls.py Project: grhawk/ASE
 def update_neighbor_list(self, atoms):
     cut = 0.5 * max(self.data['cutoffs'].values())
     self.nl = NeighborList([cut] * len(atoms),
                            skin=0,
                            bothways=True,
                            self_interaction=False)
     self.nl.update(atoms)
     self.atoms = atoms
Example #10
0
    def initialize(self, atoms):
        self.par = {}
        self.rc = 0.0
        self.numbers = atoms.get_atomic_numbers()
        maxseq = 0.0
        seen = {}
        for Z in self.numbers:
            if Z not in seen:
                seen[Z] = True
                ss = parameters[chemical_symbols[Z]][1] * Bohr
                if maxseq < ss:
                    maxseq = ss
        rc = self.rc = beta * maxseq * 0.5 * (sqrt(3) + sqrt(4))
        rr = rc * 2 * sqrt(4) / (sqrt(3) + sqrt(4))
        self.acut = np.log(9999.0) / (rr - rc)
        for Z in self.numbers:
            if Z not in self.par:
                p = parameters[chemical_symbols[Z]]
                s0 = p[1] * Bohr
                eta2 = p[3] / Bohr
                kappa = p[4] / Bohr
                x = eta2 * beta * s0
                gamma1 = 0.0
                gamma2 = 0.0
                for i, n in enumerate([12, 6, 24]):
                    r = s0 * beta * sqrt(i + 1)
                    x = n / (12 * (1.0 + exp(self.acut * (r - rc))))
                    gamma1 += x * exp(-eta2 * (r - beta * s0))
                    gamma2 += x * exp(-kappa / beta * (r - beta * s0))

                self.par[Z] = {'E0': p[0],
                               's0': s0,
                               'V0': p[2],
                               'eta2': eta2,
                               'kappa': kappa,
                               'lambda': p[5] / Bohr,
                               'n0': p[6] / Bohr**3,
                               'rc': rc,
                               'gamma1': gamma1,
                               'gamma2': gamma2}
                #if rc + 0.5 > self.rc:
                #    self.rc = rc + 0.5

        self.ksi = {}
        for s1, p1 in self.par.items():
            self.ksi[s1] = {}
            for s2, p2 in self.par.items():
                #self.ksi[s1][s2] = (p2['n0'] / p1['n0'] *
                #                    exp(eta1 * (p1['s0'] - p2['s0'])))
                self.ksi[s1][s2] = p2['n0'] / p1['n0']
                
        self.forces = np.empty((len(atoms), 3))
        self.sigma1 = np.empty(len(atoms))
        self.deds = np.empty(len(atoms))
                    
        self.nl = NeighborList([0.5 * self.rc + 0.25] * len(atoms),
                               self_interaction=False)
Example #11
0
    def update(self, atoms):

        if (self.neighbors is None) or (len(self.neighbors.cutoffs) !=
                                        len(atoms)):
            cutoffs = self.cutoff * np.ones(len(atoms))
            self.neighbors = NeighborList(cutoffs,
                                          self_interaction=False,
                                          bothways=True)
        self.neighbors.update(atoms)
Example #12
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=all_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        natoms = len(self.atoms)

        sigma = self.parameters.sigma
        epsilon = self.parameters.epsilon
        rc = self.parameters.rc
        if rc is None:
            rc = 3 * sigma

        if 'numbers' in system_changes:
            self.nl = NeighborList([rc / 2] * natoms, self_interaction=False)

        self.nl.update(self.atoms)

        positions = self.atoms.positions
        cell = self.atoms.cell

        e0 = 4 * epsilon * ((sigma / rc)**12 - (sigma / rc)**6)

        energy = 0.0
        forces = np.zeros((natoms, 3))
        stress = np.zeros((3, 3))

        for a1 in range(natoms):
            neighbors, offsets = self.nl.get_neighbors(a1)
            cells = np.dot(offsets, cell)
            d = positions[neighbors] + cells - positions[a1]
            r2 = (d**2).sum(1)
            c6 = (sigma**2 / r2)**3
            c6[r2 > rc**2] = 0.0
            energy -= e0 * (c6 != 0.0).sum()
            c12 = c6**2
            energy += 4 * epsilon * (c12 - c6).sum()
            f = (24 * epsilon * (2 * c12 - c6) / r2)[:, np.newaxis] * d
            #print d
            #print r2**.5
            #print offsets
            #print f
            #print neighbors
            forces[a1] -= f.sum(axis=0)
            for a2, f2 in zip(neighbors, f):
                forces[a2] += f2
            stress += np.dot(f.T, d)

        #stress = np.dot(stress, cell)
        stress += stress.T.copy()
        stress *= -0.5 / self.atoms.get_volume()

        self.results['energy'] = energy
        self.results['forces'] = forces
        self.results['stress'] = stress.flat[[0, 4, 8, 5, 2, 1]]
Example #13
0
def vacancy_energy(bulk, remove_index=0):
    Nat = bulk.get_number_of_atoms()
    vac = bulk.copy()
    vac.set_calculator(bulk.get_calculator())

    nl = NeighborList([a0*sqrt(3.0)/4*0.6]*len(bulk), self_interaction=False, bothways=True)
    nl.update(bulk)
    indices, offsets = nl.get_neighbors(remove_index)
    offset_factor=0.13
    for i, offset in zip(indices, offsets):
       ri = vac.positions[remove_index] - (vac.positions[i] + dot(offset, vac.get_cell()))
       vac.positions[i] += offset_factor*ri
       offset_factor += 0.01

    del vac[remove_index] # remove an atom to introduce a vacancy

    # perturb positions
    vac.rattle(0.1)

    ##
    try:
        model.calculator.set(local_gap_error='local_gap_error')
        vac.get_potential_energy()
        unrelaxed_local_gap_error_max = amax(model.calculator.results['local_gap_error'])
        unrelaxed_local_gap_error_sum = sum(model.calculator.results['local_gap_error'])
    except:
        unrelaxed_local_gap_error_max = None
        unrelaxed_local_gap_error_sum = None
    if isinstance(model, Potential):
        model.calculator.set(local_gap_error='')

    # relax atom positions, holding cell fixed
    vac = relax_atoms(vac, tol=fmax, traj_file="model-"+model.name+"-test-vacancy-energy.opt.xyz")

    vac.write("model-"+model.name+"test-vacancy-energy-relaxed.xyz")

    ##
    try:
        model.calculator.set(local_gap_error='local_gap_error')
        vac.get_potential_energy()
        relaxed_local_gap_error_max = amax(model.calculator.results['local_gap_error'])
        relaxed_local_gap_error_sum = sum(model.calculator.results['local_gap_error'])
    except:
        relaxed_local_gap_error_max = None
        relaxed_local_gap_error_sum = None
    if isinstance(model, Potential):
        model.calculator.set(local_gap_error='')
    ##

    # compute vacancy formation energy as difference of bulk and vac energies
    print 'bulk cell energy', bulk_energy
    print 'vacancy cell energy', vac.get_potential_energy()
    e_form = vac.get_potential_energy() - bulk_energy*vac.get_number_of_atoms()/bulk.get_number_of_atoms()
    print 'vacancy formation energy', e_form
    return (e_form, unrelaxed_local_gap_error_max, unrelaxed_local_gap_error_sum, relaxed_local_gap_error_max, relaxed_local_gap_error_sum)
Example #14
0
 def buildNeighborList(self):
     atoms = self.atoms
     nl = NeighborList([0.8 for atom in atoms],
                       self_interaction=False,
                       bothways=True)
     nl.update(atoms)
     self.nl = nl
     neigh = []
     for i in range(self.natom):
         neigh.append(self.sort_nei(i))
         # print neigh[i]
     self.neigh = neigh
Example #15
0
    def find_connected(self, index, dmax=None, scale=1.5):
        """Find the atoms connected to self[index] and return them.

        If dmax is not None:
        Atoms are defined to be connected if they are nearer than dmax
        to each other.

        If dmax is None:
        Atoms are defined to be connected if they are nearer than the
        sum of their covalent radii * scale to each other.

        """

        # set neighbor lists
        neighborlist = []
        if dmax is None:
            # define neighbors according to covalent radii
            radii = scale * covalent_radii[self.get_atomic_numbers()]
            for atom in self:
                positions = self.positions - atom.position
                distances = np.sqrt(np.sum(positions**2, axis=1))
                radius = scale * covalent_radii[atom.get_atomic_number()]
                neighborlist.append(np.where(distances < radii + radius)[0])
        else:
            # define neighbors according to distance
            nl = NeighborList([0.5 * dmax] * len(self), skin=0)
            nl.update(self)
            for i, atom in enumerate(self):
                neighborlist.append(list(nl.get_neighbors(i)[0]))

        connected = list(neighborlist[index])
        isolated = False
        while not isolated:
            isolated = True
            for i in connected:
                for j in neighborlist[i]:
                    if j in connected:
                        pass
                    else:
                        connected.append(j)
                        isolated = False 
 
        atoms = Cluster()
        for i in connected:
            atoms.append(self[i])

        return atoms
Example #16
0
 def testNeighborlist(self):
     atoms = read('range', format='lammps')
     atoms.set_pbc((1, 1, 1))
     nl = NeighborList([0.8 for atom in atoms],
                       self_interaction=False,
                       bothways=True)
     nl.update(atoms)
     ang = []
     for i in xrange(3):
         indices, offsets = nl.get_neighbors(i)
         angs = []
         for j, offset in zip(indices, offsets):
             pos = atoms.positions[j] + dot(
                 offset, atoms.get_cell()) - atoms.positions[i]
             ang1 = atan2(pos[1], pos[0]) + pi
             angs.append((j, ang1))
         newangs = sorted(angs, key=lambda d: d[1])
         print newangs
Example #17
0
def check_min_dist(totalsol, type='Defect', nat=None, min_len=0.7, STR=''):
    if type == 'Defect' or type == 'Crystal' or type == 'Surface':
        if nat == None:
            nat = len(totalsol)
        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)
    elif type == 'Cluster':
        for i in range(len(totalsol)):
            for j in range(len(totalsol)):
                if i != j:
                    d = totalsol.get_distance(i, j)
                    if d < min_len:
                        totalsol.set_distance(i, j, min_len, fix=0.5)
                        STR += '--- WARNING: Atoms too close (<0.7A) - Implement Move ---\n'
    else:
        print 'WARNING: In Check_Min_Dist in EvalEnergy: Structure Type not recognized'
    return totalsol, STR
Example #18
0
    def find_connected(self, index, dmax=None, scale=1.5):
        """Find the atoms connected to self[index] and return them.

        If dmax is not None:
        Atoms are defined to be connected if they are nearer than dmax
        to each other.

        If dmax is None:
        Atoms are defined to be connected if they are nearer than the
        sum of their covalent radii * scale to each other.

        """

        if index < 0:
            index = len(self) + index

        # set neighbor lists
        if dmax is None:
            # define neighbors according to covalent radii
            radii = scale * covalent_radii[self.get_atomic_numbers()]
        else:
            # define neighbors according to distance
            radii = [0.5 * dmax] * len(self)
        nl = NeighborList(radii, skin=0, self_interaction=False, bothways=True)
        nl.update(self)

        connected = [index] + list(nl.get_neighbors(index)[0])
        isolated = False
        while not isolated:
            isolated = True
            for i in connected:
                for j in nl.get_neighbors(i)[0]:
                    if j in connected:
                        pass
                    else:
                        connected.append(j)
                        isolated = False

        atoms = Cluster()
        for i in connected:
            atoms.append(self[i])

        return atoms
Example #19
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:
Example #20
0
print 'bulk reference len=%d cell=%r' % (len(bulk), bulk.cell)

bulk *= (N, N, N)
bulk.set_calculator(model.calculator)
e_bulk_per_atom = bulk.get_potential_energy() / len(bulk)
print 'e_bulk_per_atom', e_bulk_per_atom

if remove_index == 'center':
    half_cell = np.diag(bulk.cell) / 2.
    remove_index = ((bulk.positions - half_cell)**2).sum(axis=1).argmin()

initial = bulk.copy()
orig_pos = initial.get_positions()[remove_index, :]

nl = NeighborList([a0 * sqrt(3.0) / 4 * 0.6] * len(initial),
                  self_interaction=False,
                  bothways=True)
nl.update(initial)
indices, offsets = nl.get_neighbors(remove_index)
remove_index_f = None
initial.arrays['ind'] = array([i for i in range(len(initial))])
offset_factor = 0.13
for i, offset in zip(indices, offsets):
    ri = initial.positions[remove_index] - (initial.positions[i] +
                                            dot(offset, initial.get_cell()))
    if remove_index_f is None:
        remove_index_f = i
    print "initial offset ", i, offset_factor, ri
    initial.positions[i] += offset_factor * ri
    offset_factor += 0.01
Example #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
Example #22
0
C[5, 5] = 47.5 * GPa

# Surface energy computed with DFT (PBE-GGA)
surface_energy = 0.161 * (J / m**2) * 10

a = atoms.copy()
b = a * [nx, 1, 1]
b.center()
b.positions[:, 0] += 0.5
b.set_scaled_positions(b.get_scaled_positions())

mask = ((b.positions[:, 0] > 0.) & (b.positions[:, 0] < 2 * a.cell[0, 0]) &
        (b.positions[:, 1] < (a.cell[1, 1] / 2.0 + final_height / 2.0)) &
        (b.positions[:, 1] > (a.cell[1, 1] / 2.0 - final_height / 2.0)))

nl = NeighborList([1.0] * len(b), self_interaction=False, bothways=True)
nl.update(b)

term = Atoms()

if tetra:
    for i in range(len(b)):
        if not mask[i]:
            continue
        indices, offsets = nl.get_neighbors(i)
        if b.numbers[i] == 8 and mask[indices].sum() == 0:
            mask[i] = False
        if b.numbers[i] == 14:
            # complete tetrahedra
            for (j, o) in zip(indices, offsets):
                if b.numbers[j] == 8:
Example #23
0
def swap_int_local(indiv, Optimizer):
    """Move function to perform n atom structure swap based on swaplist for cluster in local region
    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
    Optimizer.output.write('Local Cluster Swap Mutation performed on individual\n')
    Optimizer.output.write('Index = '+repr(indiv.index)+'\n')
    # Identify the local atoms available for swapping
    atmsst = indiv[0].copy()
    nat = len(atmsst)
    totalsol = atmsst.copy()
    if Optimizer.structure=='Defect':
        totalsol.extend(indiv.bulki.copy())
        ctoff = [Optimizer.sf for one in totalsol]
    else:
        ctoff = [1.5 for one in totalsol]
    nl = NeighborList(ctoff, bothways=True, self_interaction=False)
    nl.update(totalsol)
    cluster = Atoms()
    indices = [] #store indices of the atoms for later
    for i in range(nat):
        indices1, offsets = nl.get_neighbors(i)
        for index, d in zip(indices1,offsets):
            index = int(index)
            #Make sure to prevent repeats of the same atom
            if index not in indices:
                pos = totalsol[index].position + numpy.dot(d,totalsol.get_cell())
                cluster.append(Atom(symbol=totalsol[index].symbol,position=pos))
                indices.append(index)
    # Identify Number of atoms to swap
    swapmax=sum([c for sym,c in indiv.swaplist])
    if swapmax >1:
        natomsswap=random.randint(1,swapmax)
    elif swapmax==1:
        natomsswap=1
    else:
        Optimizer.output.write('Maximum number of swaps is '+repr(swapmax)+'. Unable to perform mutation')
        natomsswap=0
    if len(indiv.swaplist)==1:
        Optimizer.output.write('WARNING: Swap Mutation attempted on single atom structure system\n')
        natomsswap=0
    Optimizer.output.write('Number of swaps = '+repr(natomsswap)+'\n')
    # Identify symbols that can be swapped
    syms=[sym for sym,c in indiv.swaplist]
    slist = copy.deepcopy(indiv.swaplist)
    if debug: print 'Starting swaplist = '+repr(indiv.swaplist)
    #Sanity check
    sanch = [[sym,0] for sym in syms]
    for i in range(len(sanch)):
        nc = len([atm for atm in cluster if atm.symbol==sanch[i][0]])
        nc += [c for sym,c in slist if sym==sanch[i][0]][0]
        sanch[i][1]=nc
    # Swap Atoms
    for i in range(natomsswap):
        while True:
            at1 = random.choice(cluster)
            osym = at1.symbol
            nsyml=[sym for sym,c in slist if sym != osym and c > 0]
            if len(nsyml) > 0:
                break
        nsym = random.choice(nsyml)
        cluster[at1.index].symbol = nsym
        Optimizer.output.write('Swapped '+nsym+' atom with '+osym+'\n')
        for i in range(len(slist)):
            if slist[i][0]==nsym:
                slist[i][1]-=1
            elif slist[i][0]==osym:
                slist[i][1]+=1
    # Apply the new swap to the actual atoms in the structure
    for i in range(len(indices)):
        totalsol[indices[i]].symbol = cluster[i].symbol
    # Separate out bulk from defects
    indiv[0] = totalsol[0:nat]
    if Optimizer.structure=='Defect':
        indiv.bulki = totalsol[nat::]
    # Update new swaplist
    indiv.swaplist = slist
    #Sanity check
    sanchn = [[sym,0] for sym in syms]
    for i in range(len(sanchn)):
        nc = len([atm for atm in cluster if atm.symbol==sanchn[i][0]])
        nc += [c for sym,c in slist if sym==sanchn[i][0]][0]
        sanchn[i][1]=nc
    if debug:
        for i in range(len(sanch)):
            print 'INTSWAP: Starting Atom structure '+repr(sanch[i][0])+' = '+repr(sanch[i][1])
            print 'INTSWAP: After Mutation Atom structure '+repr(sanchn[i][0])+' = '+repr(sanchn[i][1])
    Optimizer.output.write(repr(indiv[0])+'\n')
    muttype='SCL'+repr(natomsswap)
    if indiv.energy==0:
        indiv.history_index=indiv.history_index+'m'+muttype
    else:
        indiv.history_index=repr(indiv.index)+'m'+muttype
    return indiv
Example #24
0
def check_min_dist(Optimizer, totalsol, type='Defect', nat=None, min_len=0.7, STR=''):
    if type=='Defect' or type=='Crystal' or type=='Surface':
        if nat==None:
            nat=len(totalsol)
        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)
    elif type=='Cluster':
        rank = MPI.COMM_WORLD.Get_rank()
        logger = logging.getLogger(Optimizer.loggername)
        R = totalsol.arrays['positions']
        tol = 0.01
        epsilon = 0.05
        fix = 0.5
        if Optimizer.forcing == 'EllipoidShape' or Optimizer.forcing == 'FreeNatom': 
          com = totalsol.get_center_of_mass()       
          cmax = numpy.maximum.reduce(R)
          cmin = numpy.minimum.reduce(R)
          rmax= (cmax-cmin)/2.0 
          if Optimizer.forcing == 'FreeNatom':
             rcutoff = 44.0
             cutoff = [44.0,44.0,20.0]        
          else:
             rcutoff = 11.0
             cutoff = [12.0,12.0,12.0]        
          rcutoff = 44.0
          cutoff = [44.0,44.0,20.0]        
          #check if atoms are isolated outside of cluster
          cutoffs=[3.0 for one in totalsol]
          nl=NeighborList(cutoffs,bothways=True,self_interaction=False)
          nl.update(totalsol)
          for i in range(len(totalsol)):
             indices, offsets=nl.get_neighbors(i)
             D = R[i]-com
             radius = (numpy.dot(D,D))**0.5 #numpy.linalg.norm(D)
             if len(indices) < 12 or radius > rcutoff :
                # logger.info('M:move atoms back when indice {0} or radius {1}'.format(len(indices),radius))
                # R[i] = [com[j] + D[j]/radius*rcutoff for j in range(3)]
                theta=math.radians(random.uniform(0,360))
                phi=math.radians(random.uniform(0,180))
                R[i][0] = com[0] + (rmax[0]+2.5)*math.sin(theta)*math.cos(phi) #allow atoms expend by 2.5 ang
                R[i][1] = com[1] + (rmax[1]+2.5)*math.sin(theta)*math.sin(phi)
                R[i][2] = com[2] + rmax[2]*math.cos(theta)
                # logger.info('M:move atoms back new pos {0} {1} {2}'.format(rmax[0]*math.sin(theta)*math.cos(phi),rmax[1]*math.sin(theta)*math.sin(phi),rmax[2]*math.cos(theta)))
               
          # check if atoms are within cluster region 
          for i in range(0,len(totalsol)):
            # D = R[i]-com
            for j in range(3):                 
               if D[j] > cutoff[j] or D[j] < -cutoff[j]:
         #         logger.info('M:before move R {0} & com {1}'.format(R[i][j],com[j]))
                  #if rank==0:
                  #   print "before:",j,R[i][j],com[j] 
                  R[i][j] = com[j]+numpy.sign(D[j])*cutoff[j]*random.random()
         #         logger.info('M:after move R {0} '.format(R[i][j]))
                  #if rank==0:
                  #   print "after:",R[i][j]
              #    STR+='--- WARNING: Atoms too far along x-y (>44A) - Implement Move ---\n'          
                  D = R[i]-com
        #    radius = (numpy.dot(D,D))**0.5 #numpy.linalg.norm(D)
             #  STR+='--- WARNING: Atoms too far (>56A) - Implement Move ---\n'          
              

        closelist = numpy.arange(len(totalsol))
        iter = 0
        while len(closelist) > 0 and iter<2:
          iter+=1 
         # checklist = numpy.copy(closelist)
          closelist = []  
          dist=scipy.spatial.distance.cdist(R,R)       
          numpy.fill_diagonal(dist,1.0)
          smalldist = numpy.where(dist < min_len-tol)
         # for i in checklist:
            # for j in range(i+1,len(totalsol)):
         #    if len(checklist) == len(totalsol):
         #       jstart = i+1
         #    else:
         #       jstart = 0
         #    for j in range(jstart,len(totalsol)):
         #       if i != j and dist[i][j] < min_len:
             #       d=totalsol.get_distance(i,j)
             #       if d < min_len:
             #           totalsol.set_distance(i,j,min_len,fix=0.5)
                    # d = (D[0]*D[0]+D[1]*D[1]+D[2]*D[2])**0.5
          for ind in range(len(smalldist[0])):
                   i = smalldist[0][ind]
                   j = smalldist[1][ind]
                   if i < j and dist[i][j] < min_len-tol:   
                        closelist.append(i)
                        closelist.append(j)
                        if dist[i][j] > epsilon:
                      	  x = 1.0 - min_len / dist[i][j]
                          D = R[j]-R[i]
                         # print "node:",rank,"x",x,R[i],R[j],D, dist[i][j]
                       	  R[i] += (x * fix) * D
                          R[j] -= (x * (1.0 - fix)) * D
                        else:
                          R[i] += [0.2, 0.0, 0.0]
                          R[j] -= [0.2, 0.0, 0.0] 
                        R2P = [R[i],R[j]]
                        dist2P=scipy.spatial.distance.cdist(R2P,R)       
                        dist[i] = dist2P[0]
                        dist[j] = dist2P[1]
                        for k in range(len(R)):
                            dist[k][i] = dist[i][k]
                            dist[k][j] = dist[j][k]
                      #  STR+='--- WARNING: Atoms too close (<0.7A) - Implement Move ---\n'
          closelist=list(set(closelist))
          closelist.sort()
          if len(closelist) != 0: 
             logger.info('M:iter {0}, closelist size {1}'.format(iter,len(closelist)))
         #    print "rank", rank, closelist
    else:
        print 'WARNING: In Check_Min_Dist in EvalEnergy: Structure Type not recognized'
    return totalsol, STR
Example #25
0
    d = 0.0
    for a in range(len(atoms)):
        i, offsets = nl.get_neighbors(a)
        for j in i:
            c[j] += 1
        c[a] += len(i)
        d += (((R[i] + np.dot(offsets, cell) - R[a])**2).sum(1)**0.5).sum()
    return d, c

for sorted in [False, True]:
    for p1 in range(2):
        for p2 in range(2):
            for p3 in range(2):
                print p1, p2, p3
                atoms.set_pbc((p1, p2, p3))
                nl = NeighborList(atoms.numbers * 0.2 + 0.5,
                                  skin=0.0, sorted=sorted)
                nl.update(atoms)
                d, c = count(nl, atoms)
                atoms2 = atoms.repeat((p1 + 1, p2 + 1, p3 + 1))
                nl2 = NeighborList(atoms2.numbers * 0.2 + 0.5,
                                   skin=0.0, sorted=sorted)
                nl2.update(atoms2)
                d2, c2 = count(nl2, atoms2)
                c2.shape = (-1, 10)
                dd = d * (p1 + 1) * (p2 + 1) * (p3 + 1) - d2
                print dd
                print c2 - c
                assert abs(dd) < 1e-10
                assert not (c2 - c).any()

h2 = Atoms('H2', positions=[(0, 0, 0), (0, 0, 1)])
Example #26
0
 def __init__(self, cutoff_a, cell_cv, pbc_c, self_interaction):
     self.neighbors = NeighborList(cutoff_a,
                                   skin=0,
                                   sorted=True,
                                   self_interaction=self_interaction)
     self.atoms = Atoms('X%d' % len(cutoff_a), cell=cell_cv, pbc=pbc_c)
Example #27
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
Example #28
0
def newoverlap(wfs, spos_ac):
    assert wfs.ksl.block_comm.size == wfs.gd.comm.size * wfs.bd.comm.size
    even_part = EvenPartitioning(
        wfs.gd.comm,  #wfs.ksl.block_comm,
        len(wfs.atom_partition.rank_a))
    atom_partition = even_part.as_atom_partition()

    tci = wfs.tci

    gd = wfs.gd
    kd = wfs.kd
    nq = len(kd.ibzk_qc)

    # New neighbor list because we want it "both ways", heh.  Or do we?
    neighbors = NeighborList(tci.cutoff_a,
                             skin=0,
                             sorted=True,
                             self_interaction=True,
                             bothways=False)
    atoms = Atoms('X%d' % len(tci.cutoff_a), cell=gd.cell_cv, pbc=gd.pbc_c)
    atoms.set_scaled_positions(spos_ac)
    neighbors.update(atoms)

    # XXX
    pcutoff_a = []
    phicutoff_a = []
    for setup in wfs.setups:
        if setup.pt_j:
            pcutoff = max([pt.get_cutoff() for pt in setup.pt_j])
        else:
            pcutoff = 0.0
        if setup.phit_j:
            phicutoff = max([phit.get_cutoff() for phit in setup.phit_j])
        else:
            phicutoff = 0.0
        pcutoff_a.append(pcutoff)
        phicutoff_a.append(phicutoff)

    # Calculate the projector--basis function overlaps:
    #
    #    a1        ~a1
    #   P      = < p   | Phi   > ,
    #    i mu       i       mu
    #
    # i.e. projector is on a1 and basis function is on what we will call a2.

    overlapcalc = TwoCenterIntegralCalculator(wfs.kd.ibzk_qc, derivative=False)

    P_aaqim = {}  # keys: (a1, a2).  Values: matrix blocks
    dists_and_offsets = DistsAndOffsets(neighbors, spos_ac, gd.cell_cv)

    #ng = 2**extra_parameters.get('log2ng', 10)
    #transformer = FourierTransformer(rcmax, ng)
    #tsoc = TwoSiteOverlapCalculator(transformer)
    #msoc = ManySiteOverlapCalculator(tsoc, I_a, I_a)

    msoc = wfs.tci.msoc

    phit_Ij = [setup.phit_j for setup in tci.setups_I]
    l_Ij = []
    for phit_j in phit_Ij:
        l_Ij.append([phit.get_angular_momentum_number() for phit in phit_j])

    pt_l_Ij = [setup.l_j for setup in tci.setups_I]
    pt_Ij = [setup.pt_j for setup in tci.setups_I]
    phit_Ijq = msoc.transform(phit_Ij)
    pt_Ijq = msoc.transform(pt_Ij)

    #self.Theta_expansions = msoc.calculate_expansions(l_Ij, phit_Ijq,
    #                                                  l_Ij, phit_Ijq)
    #self.T_expansions = msoc.calculate_kinetic_expansions(l_Ij, phit_Ijq)
    P_expansions = msoc.calculate_expansions(pt_l_Ij, pt_Ijq, l_Ij, phit_Ijq)
    P_neighbors_a = {}

    for a1 in atom_partition.my_indices:
        for a2 in range(len(wfs.setups)):
            R_ca_and_offset_a = dists_and_offsets.get(a1, a2)
            if R_ca_and_offset_a is None:  # No overlap between a1 and a2
                continue

            maxdistance = pcutoff_a[a1] + phicutoff_a[a2]
            expansion = P_expansions.get(a1, a2)
            P_qim = expansion.zeros((nq, ), dtype=wfs.dtype)
            disp = None
            for R_c, offset in R_ca_and_offset_a:
                r = np.linalg.norm(R_c)
                if r > maxdistance:
                    continue

                # Below lines are meant to make use of symmetry.  Will not
                # be relevant for P.
                #remainder = (a1 + a2) % 2
                #if a1 < a2 and not remainder:
                #    continue
                # if a1 > a2 and remainder:
                #    continue

                phases = overlapcalc.phaseclass(overlapcalc.ibzk_qc, offset)
                disp = AtomicDisplacement(None, a1, a2, R_c, offset, phases)
                disp.evaluate_overlap(expansion, P_qim)

            if disp is not None:  # there was at least one non-zero overlap
                assert (a1, a2) not in P_aaqim
                P_aaqim[(a1, a2)] = P_qim
                P_neighbors_a.setdefault(a1, []).append(a2)

    Pkeys = P_aaqim.keys()
    Pkeys.sort()

    def get_M1M2(a):
        M1 = wfs.setups.M_a[a]
        M2 = M1 + wfs.setups[a].nao
        return M1, M2

    oldstyle_P_aqMi = None
    if 0:  #wfs.world.size == 1:
        oldstyle_P_aqMi = {}
        for a, setup in enumerate(wfs.setups):
            oldstyle_P_aqMi[a] = np.zeros((nq, wfs.setups.nao, setup.ni),
                                          dtype=wfs.dtype)
        print([(s.ni, s.nao) for s in wfs.setups])
        for a1, a2 in Pkeys:
            M1, M2 = get_M1M2(a2)
            Pconj_qmi = P_aaqim[(a1, a2)].transpose(0, 2, 1).conjugate()
            oldstyle_P_aqMi[a1][:, M1:M2, :] = Pconj_qmi

    # XXX mind distribution

    return P_neighbors_a, P_aaqim, oldstyle_P_aqMi
Example #29
0
def newclus(ind1, ind2, Optimizer):
    """Select a box in the cluster configuration"""
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write('Box Cluster Cx between individual ' +
                           repr(ind1.index) + ' and individual ' +
                           repr(ind2.index) + '\n')

    #Perserve starting conditions of individual
    solid1 = ind1[0].copy()
    solid2 = ind2[0].copy()
    cello1 = ind1[0].get_cell()
    cello2 = ind2[0].get_cell()
    cell1 = numpy.maximum.reduce(solid1.get_positions())
    cell1m = numpy.minimum.reduce(solid1.get_positions())
    cell2 = numpy.maximum.reduce(solid2.get_positions())
    cell2m = numpy.minimum.reduce(solid2.get_positions())
    cell = numpy.minimum(cell1, cell2)
    pbc1 = solid1.get_pbc()
    pbc2 = solid2.get_pbc()
    #Get starting concentrations and number of atoms
    nat1 = len(solid1)
    nat2 = len(solid2)

    # Pick a origin point for box in the cell
    pt1 = random.choice(solid1)
    pt1f = [(pt1.position[i] - cell1m[i]) / cell1[i] for i in range(3)]
    pt2 = [pt1f[i] * cell2[i] + cell2m[i] for i in range(3)]
    solid2.append(Atom(position=pt2))
    pt2 = solid2[len(solid2) - 1]
    #Find max neighborsize of circle cut
    r = random.uniform(0, min(nat1, nat2) / 5.0)
    if debug:
        print 'DEBUG CX: Point one =', pt1.position
        print 'DEBUG CX: Point two =', pt2.position
    #Find atoms within sphere of neighborsize r for both individuals
    #Make sure that crossover is only selection of atoms not all
    while True:
        ctoff = [r for on in solid1]
        nl = NeighborList(ctoff, bothways=True, self_interaction=False)
        nl.update(solid1)
        indices1, offsets = nl.get_neighbors(pt1.index)
        if len(indices1) == 0:
            r = r * 1.2
        elif len(indices1) < nat1 * .75:
            break
        else:
            r = r * 0.8
    if debug:
        print 'Neighborsize of box = ' + repr(
            r) + '\nPosition in solid1 = ' + repr(
                pt1.position) + '\nPosition in solid2 = ' + repr(pt2.position)
    group1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    group1.append(pt1)
    indices1a = [pt1.index]
    for index, d in zip(indices1, offsets):
        if index not in indices1a:
            index = int(index)
            pos = solid1[index].position + numpy.dot(d, solid1.get_cell())
            group1.append(Atom(symbol=solid1[index].symbol, position=pos))
            indices1a.append(index)
    indices1 = indices1a
    ctoff = [r for on in solid2]
    nl = NeighborList(ctoff, bothways=True, self_interaction=False)
    nl.update(solid2)
    indices2, offsets = nl.get_neighbors(pt2.index)
    group2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc())
    indices2a = []
    for index, d in zip(indices2, offsets):
        if index not in indices2a:
            index = int(index)
            pos = solid2[index].position + numpy.dot(d, solid2.get_cell())
            group2.append(Atom(symbol=solid2[index].symbol, position=pos))
            indices2a.append(index)
    indices2 = indices2a
    if len(indices2) == 0:
        for one in group1:
            while True:
                sel = random.choice(solid2)
                if sel.symbol == one.symbol:
                    if sel.index not in indices2:
                        group2.append(sel)
                        indices2.append(sel.index)
                        break

    if Optimizer.forcing == 'Concentration':
        symlist = list(set(group1.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]
        indices2n.append(pt2.index)
        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=solid2.get_cell(), pbc=solid2.get_pbc())
    for one in solid2:
        if one.index not in indices2:
            other2.append(one)
    other1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    for one in solid1:
        if one.index not in indices1:
            other1.append(one)

    #Exchange atoms in sphere and build new solids
    nsolid1 = other1.copy()
    nsolid1.extend(group2.copy())
    nsolid2 = other2.copy()
    nsolid2.extend(group1.copy())

    #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:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            nc += len([atm for atm in ind1.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
            oc += len([atm for atm in ind1.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid1 contains ' + repr(nc) +
                               ' ' + repr(sym) + ' atoms\n')
        if debug:
            print 'DEBUG CX: New solid1 contains ' + repr(nc) + ' ' + repr(
                sym) + ' atoms'
        if oc != nc:
            #pdb.set_trace()
            print 'CX: Issue in maintaining atom concentration\n Dropping new individual'
            Optimizer.output.write(
                'CX: Issue in maintaining atom concentration\n Dropping new individual 1\n'
            )
            nsolid1 = solid1
    for sym, c, m, u in Optimizer.atomlist:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            nc += len([atm for atm in ind2.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
            oc += len([atm for atm in ind2.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid2 contains ' + repr(nc) +
                               ' ' + repr(sym) + ' atoms\n')
        if debug:
            print 'DEBUG CX: New solid2 contains ' + repr(nc) + ' ' + repr(
                sym) + ' atoms'
        if oc != nc:
            #pdb.set_trace()
            print 'CX: Issue in maintaining atom concentration\n Dropping new individual'
            Optimizer.output.write(
                'CX: Issue in maintaining atom concentration\n Dropping new individual 2\n'
            )
            solid2.pop()
            nsolid2 = solid2
    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(cello1)
    nsolid2.set_cell(cello2)
    nsolid1.set_pbc(pbc1)
    nsolid2.set_pbc(pbc2)

    ind1[0] = nsolid1.copy()
    ind2[0] = nsolid2.copy()

    return ind1, ind2
Example #30
0
def fss_bcc(indiv, Optimizer):
    defected = indiv[0].copy()
    defected.extend(indiv.bulki)
    #Identify nearest neighbor cutoff distance
    nndists = []
    for i in range(5):
        one = random.choice(defected)
        distances = [defected.get_distance(one.index, j) for j in range(len(defected)) if j != one.index]
        distances.sort()
        nndists.extend(distances[0:3])
    nndist = sum(nndists)/len(nndists)
    cutoff = nndist*0.6
    #Create nearest neighbor list from cutoff distance
    ctflist = [cutoff for one in defected]
    nl = NeighborList(ctflist, bothways=True, self_interaction=False)
    nl.update(defected)
    #Identify most common number of nearest neighbors for each atom
    nneigh = []
    for one in defected:
        indices, offsets = nl.get_neighbors(one.index)
        nneigh.append(len(indices))
    avn = mode(nneigh)
    #Identify those atoms that have a different number of nearest neighbors
    defs = [i for i in range(len(nneigh)) if nneigh[i] != avn[0][0]]
    #Create new structure from translated defected atoms
    defsat = Atoms(pbc = defected.get_pbc(), cell=defected.get_cell())
    for i in defs:
        defsat.append(defected[i])
    #Identify center of mass of defected group and translate to center of cell
    cop = position_average(defsat)
    ndefsat = shift_atoms(defsat, cop)
    ndefected = shift_atoms(defected, cop)
    #Identify bounds of defected portion of structure
    maxpos = max(numpy.maximum.reduce(ndefsat.positions))
    minpos = min(numpy.minimum.reduce(ndefsat.positions))
    #Identify size of structure that will encompass defected structure
    osc = copy.deepcopy(Optimizer.supercell)
    latcont = numpy.maximum.reduce(ndefsat.get_cell())[0]/osc[0]
    deltapos = abs(maxpos-minpos)
    newsupercell = round(deltapos/latcont)+1
    bxlen = newsupercell*latcont
    #Identify those atoms within a box of encompassing length centered at the center of the cell
    tol = .1
    cell = numpy.maximum.reduce(ndefsat.get_cell())
    boxlow = [cell[i]/2.0-bxlen/2.0-tol for i in range(3)]
    boxhigh = [cell[i]/2.0+bxlen/2.0+tol for i in range(3)]
    atlist = []
    otherlist = []
    for one in ndefected:
        pos = one.position
        if boxlow[0] < pos[0] < boxhigh[0]:
            if boxlow[1] < pos[1] < boxhigh[1]:
                if boxlow[2] < pos[2] < boxhigh[2]:
                    atlist.append(one)
                else:
                    otherlist.append(one)
            else:
                otherlist.append(one)
        else:
            otherlist.append(one)
    ncell = [bxlen,bxlen,bxlen]
    #Create a new atoms object from the atoms within the box
    ssats = Atoms(pbc = True, cell=ncell)
    for one in atlist:
        ssats.append(one)
    #Attach a calculator for the atoms
    ssats.set_calculator(Optimizer.calc)
    #Calculate the energy
    out = REE(ssats)