def test_supercell():
    atoms = Atoms(numbers=range(10),
                  cell=[(0.2, 1.2, 1.4), (1.4, 0.1, 1.6), (1.3, 2.0, -0.1)])
    atoms.set_scaled_positions(3 * random.random((10, 3)) - 1)

    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
                    assert abs(dd) < 1e-10
                    assert not (c2 - c).any()
def test_H2():
    h2 = Atoms('H2', positions=[(0, 0, 0), (0, 0, 1)])
    nl = NeighborList([0.5, 0.5],
                      skin=0.1,
                      sorted=True,
                      self_interaction=False)
    nl2 = NeighborList([0.5, 0.5],
                       skin=0.1,
                       sorted=True,
                       self_interaction=False,
                       primitive=NewPrimitiveNeighborList)
    assert nl2.update(h2)
    assert nl.update(h2)
    assert not nl.update(h2)
    assert (nl.get_neighbors(0)[0] == [1]).all()
    m = np.zeros((2, 2))
    m[0, 1] = 1
    assert np.array_equal(nl.get_connectivity_matrix(sparse=False), m)
    assert np.array_equal(nl.get_connectivity_matrix(sparse=True).todense(), m)
    assert np.array_equal(nl.get_connectivity_matrix().todense(),
                          nl2.get_connectivity_matrix().todense())

    h2[1].z += 0.09
    assert not nl.update(h2)
    assert (nl.get_neighbors(0)[0] == [1]).all()

    h2[1].z += 0.09
    assert nl.update(h2)
    assert (nl.get_neighbors(0)[0] == []).all()
    assert nl.nupdates == 2
Exemple #3
0
 def gfx_queue_bonds(self):
     fa = self.get_frame_atoms()
     ra = fa.repeat(
         (int(self.repeatx.get_value()), int(self.repeaty.get_value()),
          int(self.repeatz.get_value())))
     if not 'nlist' in fa.__dict__:
         cutoffs = [1.5 * elements[i.symbol]['radius'] for i in ra]
         fa.nlist = NeighborList(cutoffs,
                                 skin=0,
                                 self_interaction=False,
                                 bothways=True)
     if len(fa.nlist.nl.cutoffs) != len(ra):
         cutoffs = [1.5 * elements[i.symbol]['radius'] for i in ra]
         fa.nlist = NeighborList(cutoffs,
                                 skin=0,
                                 self_interaction=False,
                                 bothways=True)
     fa.nlist.update(ra)
     for a in range(len(ra)):
         element = elements[ra[a].symbol]
         indices, offsets = fa.nlist.get_neighbors(a)
         for i, o in zip(indices, offsets):
             r = ra.positions[i] + np.dot(o, ra.get_cell())
             v = r - ra.positions[a]
             vm = np.linalg.norm(v)
             vunit = v / vm
             rad = 0.5 * element['radius'] * self.radiusbutton.get_value()
             p1 = ra.positions[a] + vunit * rad
             p2 = ra.positions[a] + v * 0.5
             self.gfx_queue_line(p1,
                                 p2, [c * 0.85 for c in element['color']],
                                 width=self.bond_width)
def test_fcc():
    x = bulk('X', 'fcc', a=2**0.5)

    nl = NeighborList([0.5], skin=0.01, bothways=True, self_interaction=False)
    nl.update(x)
    assert len(nl.get_neighbors(0)[0]) == 12

    nl = NeighborList([0.5] * 27,
                      skin=0.01,
                      bothways=True,
                      self_interaction=False)
    nl.update(x * (3, 3, 3))
    for a in range(27):
        assert len(nl.get_neighbors(a)[0]) == 12
    assert not np.any(nl.get_neighbors(13)[1])

    c = 0.0058
    for NeighborListClass in [PrimitiveNeighborList, NewPrimitiveNeighborList]:
        nl = NeighborListClass([c, c],
                               skin=0.0,
                               sorted=True,
                               self_interaction=False,
                               use_scaled_positions=True)
        nl.update([True, True, True],
                  np.eye(3) * 7.56, np.array([[0, 0, 0], [0, 0, 0.99875]]))
        n0, d0 = nl.get_neighbors(0)
        n1, d1 = nl.get_neighbors(1)
        # != is xor
        assert (np.all(n0 == [0]) and np.all(d0 == [0, 0, 1])) != \
            (np.all(n1 == [1]) and np.all(d1 == [0, 0, -1]))
Exemple #5
0
def add_cap_ox(clust):
    # TODO: fix bug where adds multiple oxygen's to the same place
    """
    Args:
        clust:
    """
    nl = NeighborList(natural_cutoffs(clust),
                      bothways=True,
                      self_interaction=False)
    nl.update(clust)
    new_clust = clust
    cap_inds = get_cap_si(clust)
    for ind in cap_inds:
        while len(nl.get_neighbors(ind)[0]) < 4:
            neighb = nl.get_neighbors(ind)[0][
                -1]  # last index in the list of neighbor indicies
            direction = clust.get_positions()[ind] - clust.get_positions()[
                neighb]  # vector pointing from neighbor to Si
            ox_pos = clust.get_positions(
            )[ind] + 1.6 * direction / np.linalg.norm(direction)
            new_ox = Atom('O', position=ox_pos)
            new_clust.append(new_ox)
            nl = NeighborList(natural_cutoffs(clust),
                              bothways=True,
                              self_interaction=False)
            nl.update(clust)
    return (new_clust)
def test_small_cell_and_large_cutoff():
    # See: https://gitlab.com/ase/ase/-/issues/441
    cutoff = 50

    atoms = bulk('Cu', 'fcc', a=3.6)
    atoms *= (2, 2, 2)
    atoms.set_pbc(False)
    radii = cutoff * np.ones(len(atoms.get_atomic_numbers()))

    neighborhood_new = NeighborList(radii,
                                    skin=0.0,
                                    self_interaction=False,
                                    bothways=True,
                                    primitive=NewPrimitiveNeighborList)
    neighborhood_old = NeighborList(radii,
                                    skin=0.0,
                                    self_interaction=False,
                                    bothways=True,
                                    primitive=PrimitiveNeighborList)

    neighborhood_new.update(atoms)
    neighborhood_old.update(atoms)

    n0, d0 = neighborhood_new.get_neighbors(0)
    n1, d1 = neighborhood_old.get_neighbors(0)

    assert np.all(n0 == n1)
    assert np.all(d0 == d1)
Exemple #7
0
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.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
Exemple #8
0
    def get_Z_TM(self, atoms, d_Z_TM, TM_type):
        # todo: improve flexibility to allow Z-TM-H or Z-TM-OH insertions while avoid overlapping
        nl = NeighborList(natural_cutoffs(atoms),
                          bothways=True,
                          self_interaction=False)
        nl.update(atoms)
        index_Al = [a.index for a in atoms if a.symbol == 'Al']
        indices, offsets = nl.get_neighbors(index_Al[0])
        indices = [val for val in indices if atoms[val].symbol == 'O']
        assert len(indices) == 4

        dict_Z_TM = {}
        original_atoms = copy.copy(atoms)
        pairs = list(itertools.combinations(indices, 2))
        for i, pair in enumerate(pairs):
            atoms = copy.copy(original_atoms)
            v = self._get_direction_of_insertion(atoms,
                                                 index_Al[0],
                                                 pair[0],
                                                 pair[1],
                                                 tag='TM')
            atoms = atoms + Atoms(
                TM_type, positions=[atoms[index_Al[0]].position] + v * d_Z_TM)
            atoms.wrap()
            key_tag = 'O' + str(pair[0]) + '_O' + str(pair[1])
            dict_Z_TM[key_tag] = atoms

        return dict_Z_TM
def all_connected_to(id_atom, atoms, exclude):
    cov_radii = [covalent_radii[a.number] for a in atoms]

    atoms.set_pbc([False, False, False])
    nl_no_pbc = NeighborList(cov_radii, bothways=True, self_interaction=False)
    nl_no_pbc.update(atoms)
    atoms.set_pbc([True, True, True])

    tofollow = []
    followed = []
    isconnected = []
    tofollow.append(id_atom)
    isconnected.append(id_atom)
    while len(tofollow) > 0:
        indices, offsets = nl_no_pbc.get_neighbors(tofollow[0])
        indices = list(indices)
        followed.append(tofollow[0])
        for i in indices:
            if (i not in isconnected) and (atoms[i].symbol not in exclude):
                tofollow.append(i)
                isconnected.append(i)
        for i in followed:
            if i in tofollow:  ### do not remove this check
                tofollow.remove(i)
            #try:
            #    tofollow.remove(i)
            #except:
            #    pass
            #

    return isconnected
Exemple #10
0
    def get_donor_vec(self, donor_index):
        """finds direction of lone pair electrons on an adsorbate donor atom
        :return: vector direction of donor atoms

        Args:
            donor_index:
        """
        nl = NeighborList(natural_cutoffs(self),
                          self_interaction=False,
                          bothways=True)
        nl.update(self)
        # gets neighbors of donor atom and adds the vectors from neighbor to donor
        # for most donor atoms this is roughly in the proper binding direction
        donor_neighbors = nl.get_neighbors(donor_index)[0]  # neighbor's index
        donor_vec = np.array([0, 0, 0])
        for i in donor_neighbors:
            a = self.get_distance(i, donor_index, vector=True)
            donor_vec = donor_vec + a
        if np.linalg.norm(donor_vec) == 0:
            warnings.warn(
                "donor vector with magnitude 0 found, providing default  vector"
            )
            return np.array([1, 0, 0])

        donor_vec = donor_vec / np.linalg.norm(
            donor_vec)  # normalizes donor vec
        return donor_vec
Exemple #11
0
def main():
    args = sys.argv
    imgs = read(args[1], index="::40")
    #layers = find_layers(atoms.copy())
    traj = Trajectory('traj.traj','w')

    H_indices = random.sample([a.index for a in imgs[0] if a.symbol == 'H'],8)

    n_img = 0
    for atoms in imgs:
       nl=NeighborList([2.5/2]*len(atoms), self_interaction=False, bothways=True)
       nl.update(atoms)
       pair_selected = []
       for H_index in H_indices:
         nl_indices, nl_offsets = nl.get_neighbors(H_index)
         pair_selected.append([H_index, random.sample(nl_indices, 1)[0]])
       for HPd_dist in [1.0, 1.1, 1.2, 1.3, 1.4]:
          img = atoms.copy()
          for pair in pair_selected:
            H_index = pair[0]
            Pd_selected = pair[1]
            v = atoms[H_index].position - atoms[Pd_selected].position
            vn = v/np.linalg.norm(v)
            del img[H_index]
            img.append(Atom('H',atoms[Pd_selected].position + vn * HPd_dist))
          traj.write(img)
          print n_img
          n_img+=1
Exemple #12
0
    def add_pairwise(self, properties):
        positions = self.atoms.get_positions()

        mcut = 0.0
        lcut = 2.5

        if self.pwiter:
            N = positions.shape[0]
            self.nl = NeighborList(np.full(N, mcut / 2.0),
                                   skin=0.25,
                                   self_interaction=False)
            self.Xn = np.zeros((N, 0, 3), dtype=np.float64)
            self.Dn = np.zeros((N, 0, 3), dtype=np.float64)
            self.pwiter = False

        #start_time = time.time()
        self.nl.update(self.atoms)

        Epairwise = 0.0
        if 'forces' in properties:
            Fpairwise = 0. * positions

        # loop over all atoms in the cell
        for ia, posa in enumerate(positions):
            indices, offsets = self.nl.get_neighbors(ia)
            #print('Neh/Dsp:', indices.shape, offsets.shape)

            #nposition = positions[indices]
            R = positions[indices] + np.dot(
                offsets, self.atoms.get_cell()) - posa[np.newaxis, :]
            Rmag = np.linalg.norm(R, axis=1)
            cidx = np.where((Rmag >= lcut) & (Rmag < mcut))
            sidx = np.where(Rmag >= mcut)
            E = self.Efunc(Rmag)

            Ecut = coscut(Rmag[cidx], 1.0 / (mcut - lcut), lcut)
            #Ecut = tanhcut(Rmag[cidx], lcut-0.1*lcut)
            E[cidx] = E[cidx] * Ecut
            E[sidx] = 0.0 * E[sidx]

            Epairwise += E.sum(
            )  # Neighbors list supplies only neighbors once (NO DOUBLE COUNT)

            if 'forces' in properties:
                F = self.Ffunc(Rmag[:, np.newaxis], R)
                F[cidx] = (E[cidx][:, np.newaxis] *
                           dcoscut(Rmag[cidx][:, np.newaxis], R[cidx], 1.0 /
                                   (mcut - lcut), lcut) +
                           Ecut[:, np.newaxis] * F[cidx])
                #F[cidx] = (E[cidx][:,np.newaxis]*dtanhcut(Rmag[cidx][:,np.newaxis], R[cidx], lcut-0.1*lcut)+Ecut[:,np.newaxis]*F[cidx])
                F[sidx] = 0.0 * F[sidx]
                Fpairwise[indices] += -F
                Fpairwise[ia] += np.sum(F, axis=0)

        self.results['energy'] += Epairwise
        self.Epwise = Epairwise
        if 'forces' in properties:
            #print(Fpairwise.shape,np.sum(Fpairwise, axis=1))
            #print(Fpairwise[0])
            self.results['forces'] += Fpairwise
Exemple #13
0
def find_tmpo(atoms):
    """
    Args:
        atoms:
    """
    tmpo_indices = []
    p_index = None
    for a in atoms:
        if a.symbol == 'P':
            p_index = a.index
            break
    tmpo_indices.append(p_index)
    if p_index is None:
        return tmpo_indices
    nl = NeighborList(natural_cutoffs(atoms),
                      bothways=True,
                      self_interaction=False)
    nl.update(atoms)
    p_nl = nl.get_neighbors(p_index)[0]
    tmpo_indices.extend(p_nl)
    for i in p_nl:
        if atoms[i].symbol == 'C':
            tmpo_indices.extend(nl.get_neighbors(i)[0])

    return tmpo_indices
Exemple #14
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!")
def get_rdf(atoms, a, rs, dr, rmax, nl=None):
    """number of atoms in a shell between r and r+dr
       centered around atom a and normalized by the shell volume.
       The number of atoms are devided into types according to
       their atomic number.
    """
    V_r = get_shell_volume(rs, dr)
    if nl is None:
        cutoffs = [
            rmax / 2 + 0.1,
        ] * len(atoms)
        nl = NeighborList(cutoffs=cutoffs,
                          skin=0,
                          self_interaction=False,
                          bothways=True)
        nl.update(atoms)

    cluster = get_cluster(atoms, a=a, nl=nl)  # first atom in the cluser -> a=0
    zs = set(atoms.get_chemical_symbols())
    p = dict([[z, np.zeros(len(rs))] for z in zs])
    for ir, r in enumerate(rs):
        shell = get_shell(atoms=cluster, r=r, dr=dr, a=0)
        zs_shell, count = np.unique(shell.get_chemical_symbols(),
                                    return_counts=True)
        zc = dict([(z, c) for z, c in zip(zs_shell, count)])
        for z in zs:
            if z in zc:
                p[z][ir] = zc[z]
            else:
                p[z][ir] = 0
    for z in zs:
        p[z] /= V_r

    return p
Exemple #16
0
def main():
    imgs = read('train.traj', index='0::10', format='traj')
    natoms = len(imgs[0])
    cutoff = 3.3
    mindist = 2.7

    traj = Trajectory('traj.traj', 'w')

    for atoms in imgs:
        nl = NeighborList([cutoff / 2] * len(atoms),
                          self_interaction=False,
                          bothways=False)
        nl.update(atoms)
        neighbor_info = {}
        n_pairs = 0
        for i in range(natoms):
            i_indices, i_offsets = nl.get_neighbors(i)
            neighbor_info[i] = i_indices
            n_pairs += len(i_indices)
            print len(i_indices)
        #randomvalues=np.random.random((n_pairs,)) + mindist
        randomvalues = np.random.normal(mindist, 0.5, (n_pairs, ))

        pullcloser = {}
        pointer = 0
        for key in neighbor_info.keys():
            pullcloser[key] = randomvalues[pointer:len(neighbor_info[key]) +
                                           pointer:1]
            pointer += len(neighbor_info[key])

        atoms.set_positions(
            pull_closer(atoms.get_positions(), neighbor_info, pullcloser))
        #write('CONTCAR',atoms,format='vasp')
        traj.write(atoms)
  def test0(self):
    """check one-way neighborlist for fcc on different repeats."""
    a = 3.6
    for rep in ((1, 1, 1), (2, 1, 1), (1, 2, 1), (1, 1, 2), (1, 2, 2),
                (2, 1, 1), (2, 2, 1), (2, 2, 2), (1, 2, 3), (4, 1, 1)):
      for cutoff_radius in np.linspace(a / 2.1, 5 * a, 5):
        atoms = bulk('Cu', 'fcc', a=a).repeat(rep)
        # It is important to rattle the atoms off the lattice points.
        # Otherwise, float tolerances makes it hard to count correctly.
        atoms.rattle(0.02)
        nl = NeighborList(
            [cutoff_radius / 2] * len(atoms),
            skin=0.0,
            self_interaction=False,
            bothways=False)
        nl.update(atoms)

        neighbors, displacements = get_neighbors_oneway(
            atoms.positions, atoms.cell, cutoff_radius, skin=0.0)

        for i in range(len(atoms)):
          an, ad = nl.get_neighbors(i)
          # Check the same number of neighbors
          self.assertEqual(len(neighbors[i]), len(an))
          # Check the same indices
          self.assertCountEqual(neighbors[i], an)
Exemple #18
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.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)
        self.coordination = np.zeros((self.images.natoms), dtype=int)
        if nb == 0:
            return

        n1 = 0
        for a in range(self.images.natoms):
            indices, offsets = nl.get_neighbors(a)
            self.coordination[a] += len(indices)
            for a2 in indices:
                self.coordination[a2] += 1
            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:]
Exemple #19
0
 def get_color_scalars(self, frame=None):
     if self.colormode == 'tag':
         return self.atoms.get_tags()
     if self.colormode == 'force':
         f = (self.get_forces()**2).sum(1)**0.5
         return f * self.images.get_dynamic(self.atoms)
     elif self.colormode == 'velocity':
         return (self.atoms.get_velocities()**2).sum(1)**0.5
     elif self.colormode == 'initial charge':
         return self.atoms.get_initial_charges()
     elif self.colormode == 'magmom':
         return get_magmoms(self.atoms)
     elif self.colormode == 'neighbors':
         from ase.neighborlist import NeighborList
         n = len(self.atoms)
         nl = NeighborList(self.get_covalent_radii(self.atoms) * 1.5,
                           skin=0,
                           self_interaction=False,
                           bothways=True)
         nl.update(self.atoms)
         return [len(nl.get_neighbors(i)[0]) for i in range(n)]
     else:
         scalars = np.array(self.atoms.get_array(self.colormode),
                            dtype=float)
         return np.ma.array(scalars, mask=np.isnan(scalars))
Exemple #20
0
def generate_normals(atoms,
                     surface_normal=0.5,
                     normalize_final=True,
                     adsorbate_atoms=[]):
    normals = np.zeros(shape=(len(atoms), 3), dtype=float)

    atoms = atoms.copy()

    del atoms[adsorbate_atoms]

    cutoffs = natural_cutoffs(atoms)

    nl = NeighborList(cutoffs, self_interaction=False, bothways=True)
    nl.update(atoms)

    cell = atoms.get_cell()

    for index, atom in enumerate(atoms):
        normal = np.array([0, 0, 0], dtype=float)
        for neighbor, offset in zip(*nl.get_neighbors(index)):
            direction = atom.position - relative_position(
                atoms, neighbor, offset)
            normal += direction
        if norm(normal) > surface_normal:
            normals[index, :] = normalize(
                normal) if normalize_final else normal

    surface_mask = [
        index for index in range(len(atoms)) if norm(normals[index]) > 1e-5
    ]

    return normals, surface_mask
Exemple #21
0
def get_external_internal(atoms, symbols=None):

    # Atoms to include in external and internal indices
    if symbols is None:
        symbols = list(set(atoms.symbols))
        try:
            symbols.pop(symbols.index('H'))
        except ValueError as e:
            print(e)
    #
    symbols = list(symbols)

    # Define list of neighbors
    cov_radii = [covalent_radii[a.number] for a in atoms]
    nl = NeighborList(cov_radii, bothways=True, self_interaction=False)
    nl.update(atoms)

    external_i = []
    internal_i = []
    for a in atoms:
        if a.symbol not in symbols:
            continue
        nlist = nl.get_neighbors(a.index)[0]
        n_is_H = [True if atoms[n0].symbol == 'H' else False for n0 in nlist]
        if any(n_is_H):
            external_i.append(a.index)
        else:
            internal_i.append(a.index)

    return external_i, internal_i
Exemple #22
0
def ase_connectivity(atoms, cutoffs=None, count_bonds=True):
    """Return a connectivity matrix calculated of an atoms object.

    If no neighborlist or connectivity matrix is attached to the atoms object,
    a new one will be generated. Multiple connections are counted.

    Parameters
    ----------
    atoms : object
        An ase atoms object.
    cutoffs : list
        A list of cutoff radii for the atoms, ordered by atom index.

    Returns
    -------
    conn : array
        An n by n, where n is len(atoms).
    """
    if hasattr(atoms, 'neighborlist'):
        nl = atoms.neighborlist
    else:
        nl = NeighborList(cutoffs=cutoffs, bothways=True)
        nl.update(atoms)
        conn_mat = nl.get_connectivity_matrix(sparse=False)
        np.fill_diagonal(conn_mat, 0)

    return np.asarray(conn_mat, dtype=int)
Exemple #23
0
def find_layers(atoms):
    cutoff = 3.2

    nlayer = 0
    layers = {}
    while True:
       if len(atoms) == 0:
          break
       nl=NeighborList([cutoff/2]*len(atoms), self_interaction=False, bothways=True)
       nl.update(atoms)
       com=atoms.get_center_of_mass()
       core = []
       for i in range(len(atoms)):
          #first_layer (most outer layer)
          i_indices, i_offsets = nl.get_neighbors(i)
          if i==13 or i==15 or i==3:
             print i, len(i_indices)
          if len(i_indices) < 10:
             if nlayer not in layers.keys():
                layers[nlayer] = [i] 
             else:
                layers[nlayer].append(i)
          else:
            core.append(i)
       #layers[nlayer].sort(reverse=True) 
       shell = atoms.copy()
       del shell[core]
       del atoms[layers[nlayer]]
       write('shell_'+str(nlayer)+'.xyz',shell,format='xyz')
       write('core_'+str(nlayer)+'.xyz',atoms,format='xyz')
       layers[nlayer].append(shell.copy())
       print nlayer
       print "     ",layers[nlayer]
       nlayer += 1
    return layers
Exemple #24
0
def ase_neighborlist(atoms, cutoffs=None):
    """Make dict of neighboring atoms using ase function.

    This provides a wrapper for the ASE neighborlist generator. Currently
    default values are used.

    Parameters
    ----------
    atoms : object
        Target ase atoms object on which to get neighbor list.
    cutoffs : list
        A list of radii for each atom in atoms.
    rtol : float
        The tolerance factor to allow for small variation in the cutoff radii.

    Returns
    -------
    neighborlist : dict
        A dictionary containing the atom index and each neighbor index.
    """
    if cutoffs is None:
        cutoffs = [get_radius(a.number) for a in atoms]
    nl = NeighborList(
        cutoffs, skin=0., sorted=False, self_interaction=False,
        bothways=True)

    nl.update(atoms)

    neighborlist = {}
    for i, _ in enumerate(atoms):
        neighborlist[i] = sorted(list(map(int, nl.get_neighbors(i)[0])))

    return neighborlist
Exemple #25
0
def get_bonds(atoms, covalent_radii):
    from ase.neighborlist import NeighborList
    nl = NeighborList(covalent_radii * 1.5, skin=0, self_interaction=False)
    nl.update(atoms)
    nbonds = nl.nneighbors + nl.npbcneighbors

    bonds = np.empty((nbonds, 5), int)
    if nbonds == 0:
        return bonds

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

    i = bonds[:n2, 2:].any(1)
    pbcbonds = bonds[:n2][i]
    bonds[n2:, 0] = pbcbonds[:, 1]
    bonds[n2:, 1] = pbcbonds[:, 0]
    bonds[n2:, 2:] = -pbcbonds[:, 2:]
    return bonds
Exemple #26
0
def get_angles(cluster, mult=1, excluded_index=None, excluded_pair=None):
    """
    #TODO: consider combining get_bonds and get_angles function
    ase.geometry.analysis.Analysis.unique_angles function does not work, return all angles.
    three-body interactions.
    :param excluded_pair: excluding all [particle1, particle2, particle3] lists involving the excluded pair
    """
    if excluded_index is None:
        excluded_index = []
    if excluded_pair is None:
        excluded_pair = []

    nl = NeighborList(natural_cutoffs(cluster, mult=mult),
                      bothways=True,
                      self_interaction=False)
    nl.update(cluster)

    angle_list, shortened_list = [], []
    for count, indices in enumerate(Analysis(cluster, nl=nl).all_angles[0]):
        for index in indices:
            if all(
                    list(val) not in angle_list for val in list(
                        permutations([count, index[0], index[1]]))):
                angle_list.append([count, index[0], index[1]])

    for angle in angle_list:
        if all(single_index not in angle for single_index in excluded_index) and \
                all(list(value) not in excluded_pair for value in list(permutations(angle, 2))):
            shortened_list.append(angle)

    return angle_list, shortened_list
Exemple #27
0
    def __init__(self,
                 quadrature,
                 cutoff,
                 atoms=None,
                 I=5E-2,
                 sigma=2,
                 g=None,
                 w=1,
                 debug=False):

        self.g = g
        self.I = I
        self.sigma = sigma
        self.cutoff = cutoff
        self.debug = debug

        self.quad = quadrature
        self.weights = self.quad.weights
        self.sensors = self.quad.points

        self.w_integral = w

        self.atoms = atoms
        if atoms is not None:
            self.nlist = NeighborList([cutoff * 0.5] * len(atoms),
                                      skin=0,
                                      self_interaction=False,
                                      bothways=True)

            self.nlist.update(atoms)
Exemple #28
0
    def get_all_Z_TM(self, d_Z_TM, TM_type):
        """
        :param d_Z_TM: Z-TM distance with Z being the T sites on the zeolite framework and TM being extraframework atom
        to be inserted
        :return: a dictionary of structures for each T site name
        """
        dict_Z_TM = {}
        for site_name, all_zeo_with_same_T in self.dict_1Al_replaced.items():
            atoms = copy.copy(all_zeo_with_same_T[0])
            nl = NeighborList(natural_cutoffs(atoms),
                              bothways=True,
                              self_interaction=False)
            nl.update(atoms)
            index_Al = [a.index for a in atoms if a.symbol == 'Al']
            indices, offsets = nl.get_neighbors(index_Al[0])
            assert len(indices) == 4

            traj = []
            pairs = list(itertools.combinations(indices, 2))
            for i, pair in enumerate(pairs):
                atoms = copy.copy(all_zeo_with_same_T[0])
                v = self._get_direction_of_insertion(atoms,
                                                     index_Al[0],
                                                     pair[0],
                                                     pair[1],
                                                     tag='TM')
                atoms = atoms + Atoms(
                    TM_type,
                    positions=[atoms[index_Al[0]].position] + v * d_Z_TM)
                traj.append(atoms)
            dict_Z_TM[site_name] = traj

        return dict_Z_TM
Exemple #29
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)
Exemple #30
0
def get_bonds(cluster, mult=1, excluded_index=None, excluded_pair=None):
    """
    Using ase.geometry.analysis.Analysis to get all bonds, then remove the repeated ones.
    Function also allows removing certain bonding pair defined by user (excluded_pair).
    Or removing pairs including certain atomic indices (excluded_index).
    :param cluster:
    :param mult:
    :param excluded_index: list of integers
    :param excluded_pair: list of lists
    :return: full bonding list, shortened list.
    If both excluded_index and excluded_pair are None, bonding list == shortened list
    """
    if excluded_index is None:
        excluded_index = []
    if excluded_pair is None:
        excluded_pair = []

    nl = NeighborList(natural_cutoffs(cluster, mult=mult),
                      bothways=True,
                      self_interaction=False)
    nl.update(cluster)

    bond_list, shortened_list = [], []
    for count, indices in enumerate(Analysis(cluster, nl=nl).all_bonds[0]):
        for index in indices:
            if [count, index] not in bond_list and [index, count
                                                    ] not in bond_list:
                bond_list.append([count, index])

    for bond in bond_list:
        if all(single_index not in bond for single_index in excluded_index) and \
                all(tuple(bond) not in list(permutations(pair)) for pair in excluded_pair):
            shortened_list.append(bond)

    return bond_list, shortened_list