Ejemplo n.º 1
0
def reindex_sites(structure, lattice, tolerance=0.5):
    """ Reindexes atoms of structure according to lattice sites.

        Expects that the structure is an exact supercell of the lattice, as far
        cell vectors are concerned. The atoms, however, may have moved around a
        bit. To get an index, an atom must be clearly closer to one ideal lattice
        site than to any other, within a given tolerance (in units of `structure.scale`?).
    """
    from pylada.crystal import neighbors, supercell
    from copy import deepcopy
    # haowei: should not change lattice
    lat = deepcopy(lattice)
    # first give a natural index for the sites in lattice
    for i, a in enumerate(lat):
        a.site = i
    # in the supercell, each atom carry the site from the lat above, and will
    # goes into the neighs
    lat = supercell(lattice=lat, supercell=structure.cell *
                    structure.scale / lat.scale)
    for atom in structure:
        neighs_in_str = [n for n in neighbors(structure, 1, atom.pos)]
        d = neighs_in_str[0][2]
        # if two atoms from structure and lattice have exactly the same coordination
        # and hence dist = 0, it will be neglected by neighbors
        # add 1E-6 to atom.pos to avoid this, but aparrently this is not a perfect
        # solution, Haowei
        neighs = [n for n in neighbors(lat, 2, atom.pos + 1E-6)]
        assert abs(neighs[1][2]) > 1e-12,\
            RuntimeError('Found two sites occupying the same position.')
        if neighs[0][2] * lat.scale > tolerance * d:
            atom.site = -1
        else:
            atom.site = neighs[0][0].site
Ejemplo n.º 2
0
def reindex_sites(structure, lattice, tolerance=0.5):
    """ Reindexes atoms of structure according to lattice sites.

        Expects that the structure is an exact supercell of the lattice, as far
        cell vectors are concerned. The atoms, however, may have moved around a
        bit. To get an index, an atom must be clearly closer to one ideal lattice
        site than to any other, within a given tolerance (in units of `structure.scale`?).
    """
    from pylada.crystal import neighbors, supercell
    from copy import deepcopy
    # haowei: should not change lattice
    lat = deepcopy(lattice)
    # first give a natural index for the sites in lattice
    for i, a in enumerate(lat):
        a.site = i
    # in the supercell, each atom carry the site from the lat above, and will
    # goes into the neighs
    lat = supercell(lattice=lat,
                    supercell=structure.cell * structure.scale / lat.scale)
    for atom in structure:
        neighs_in_str = [n for n in neighbors(structure, 1, atom.pos)]
        d = neighs_in_str[0][2]
        # if two atoms from structure and lattice have exactly the same coordination
        # and hence dist = 0, it will be neglected by neighbors
        # add 1E-6 to atom.pos to avoid this, but aparrently this is not a perfect
        # solution, Haowei
        neighs = [n for n in neighbors(lat, 2, atom.pos + 1E-6)]
        assert abs(neighs[1][2]) > 1e-12,\
            RuntimeError('Found two sites occupying the same position.')
        if neighs[0][2] * lat.scale > tolerance * d:
            atom.site = -1
        else:
            atom.site = neighs[0][0].site
Ejemplo n.º 3
0
def relax_structure_v1(structure, min_dist_AA=1., min_dist_AB=1., Niter=500):
    from itertools import combinations
    from pylada.crystal import neighbors
    indexes = range(len(structure))
    for iter in range(Niter):
        succes = 1
        np.random.shuffle(indexes)
        for index_A in indexes:
            neighs = [
                n for n in neighbors(structure, 1, structure[index_A].pos)
            ]
            index_B = get_index(structure, neighs[0][0])

            if not same_kind(structure, index_A, index_B):
                min_dist = min_dist_AB / float(structure.scale)
            else:
                min_dist = min_dist_AA / float(structure.scale)

            if neighs[0][-1] < min_dist:

                move_by = min_dist - neighs[0][-1]
                if move_by * structure.scale > 0.02:
                    succes = 0
                    relax_pair_cm(structure, index_A, index_B, 1.2 * move_by,
                                  min_dist)
                    move_to_cell(structure, index_A)
                    move_to_cell(structure, index_B)
        if succes:
            return 1
    return 0
def get_cn(structure,  cut_off = 2.8, index = -1, **kwargs):

    atom_types, N = get_types(structure)
    types_pdf = kwargs.get("types_pdf", get_pdf_types(atom_types))
    scale = float(structure.scale)

    cn = {}
    max_coord = 15
    for type in types_pdf:
      cn[type] = np.zeros(max_coord)
    for index_A in range(len(structure)):
      A = structure[index_A].type  
      pos_A = structure[index_A].pos
      neighs = [n for n in neighbors(structure, max_coord-1, pos_A)]
      d2_AB_prev = 10.
      count = {}
      for i, nB in enumerate(neighs):
        B = nB[0].type  
        d2_AB = (scale *nB[2])
        delta_dist = d2_AB - d2_AB_prev
        d2_AB_prev = d2_AB
        if d2_AB > cut_off:
          break
        #if delta_dist>0.5:
        #  break
        else:
          if A+B not in count.keys():
            count[A+B] = 0
          count[A+B] += 1
      for key in count.keys():  
        cn[key][count[key]] += 1./N[A]
    return cn
Ejemplo n.º 5
0
def count_tot_broken_bonds(bulk=None, slab=None):
    """Counts total number of broken bonds"""

    from pylada.crystal import neighbors

    under_coord = sort_under_coord(bulk=bulk, slab=slab)

    rc = z_center(slab=slab)

    # Check the coordination in the bulk first shell
    bulk_first_shell = []
    for atom in bulk:
        bulk_first_shell.append(
            [atom.type, len(neighbors(structure=bulk, nmax=1, center=atom.pos, tolerance=1e-1 / bulk.scale))])

    broken_bonds = []

    for i in range(len(under_coord)):
        atom = slab[under_coord[i][0]]
        coordination = under_coord[i][1]

        for j in range(len(bulk)):
            eq_site = float(atom.site - j) / float(len(bulk))
            if abs(int(eq_site) - eq_site) < 1e-5:
                break

        broken_bonds.append(abs(coordination - bulk_first_shell[j][1]))

    return sum(array(broken_bonds))
Ejemplo n.º 6
0
def count_broken_bonds_per_area(bulk=None, slab=None):
    """Counts broken bonds per atom"""

    from pylada.crystal import neighbors

    under_coord = sort_under_coord(bulk=bulk, slab=slab)
    rc = z_center(slab=slab)

    # Check the coordination in the bulk first shell
    bulk_first_shell = []
    for atom in bulk:
        bulk_first_shell.append(
            [atom.type, len(neighbors(structure=bulk, nmax=1, center=atom.pos, tolerance=1e-1 / bulk.scale))])

    broken_bonds = []

    for i in range(len(under_coord)):
        atom = slab[under_coord[i][0]]
        coordination = under_coord[i][1]

        for j in range(len(bulk)):
            eq_site = float(atom.site - j) / float(len(bulk))
            if abs(int(eq_site) - eq_site) < 1e-5:
                break

        broken_bonds.append(abs(coordination - bulk_first_shell[j][1]))

    c = cross(slab.cell[0], slab.cell[1])
    area = sqrt(dot(c, c)) * float(slab.scale)**2

    return sum(array(broken_bonds)) / area / 2  # there are two surfaces
def relax_structure_v1(structure,  min_dist_AA=1., min_dist_AB=1., Niter = 500):
    from itertools import  combinations
    from pylada.crystal import neighbors
    indexes = range(len(structure))
    for iter in range(Niter):
      succes = 1
      np.random.shuffle(indexes)
      for index_A in indexes:
            neighs = [n for n in neighbors(structure, 1, structure[index_A].pos)]
            index_B = get_index(structure, neighs[0][0])
            
            if not same_kind(structure, index_A, index_B):
              min_dist =  min_dist_AB /float(structure.scale)
            else:
              min_dist =  min_dist_AA /float(structure.scale)
                
            if neighs[0][-1] < min_dist:
            
                move_by = min_dist - neighs[0][-1]
                if move_by*structure.scale > 0.02:
                  succes = 0
                  relax_pair_cm(structure, index_A, index_B, 1.2*move_by, min_dist) 
                  move_to_cell(structure, index_A)
                  move_to_cell(structure, index_B)
      if succes:
        return 1
    return 0 
Ejemplo n.º 8
0
def get_duplicates(massextr, te_diff=0.01):
    """ function to identify unique intersitials
    
    Parameters
        massextr = Pylada mass extraction object (directory with all intersitials directories)
        te_diff = difference in total energy among interstitials, default = 0.01 eV
    Returns
        dict = {key='foldername', total_energy, index}
    
    Note"
    index = all the foldername (intersitials) with same index are effectively considered equivalent
    Criteria for duplicates
    1. Total_energy_difference <= 0.01 eV
    2. Space_group
    3. comparing first neighbor list for all the sites in the structure
    """

    dict_E = massextr.total_energies
    dict_Str = massextr.structure

    dict2 = {}
    g = 0

    for k in dict_E.keys():
        g = g + 1
        dict2[k] = [dict_E[k]]
        dict2[k].append(g)

    folder_list = [l for l in massextr]
    folder_combs = combinations(folder_list, 2)

    for i in folder_combs:
        diff_E = abs(dict2[i[0]][0] - dict2[i[1]][0])
        str1 = dict_Str[i[0]]
        str2 = dict_Str[i[1]]
        spg1 = spglib.get_spacegroup(str1)
        spg2 = spglib.get_spacegroup(str2)
        ngh_list_1 = sorted(
            [len(neighbors(str1, 1, atom.pos, 0.2)) for atom in str1])
        ngh_list_2 = sorted(
            [len(neighbors(str2, 1, atom.pos, 0.2)) for atom in str2])
        if diff_E <= te_diff:
            if spg1 == spg2:
                if ngh_list_1 == ngh_list_2:
                    dict2[i[1]][1] = dict2[i[0]][1]

    return (dict2)
def  Dz(point, structure, k=1, d0=1.5):
  from pylada.crystal import neighbors
  neighs = [n for n in neighbors(structure, k, point)]
  d0 /= float(structure.scale)
  value = 0
  for i in range(k):
    value += (abs(neighs[k-1][-1]-d0))**2
  return   value
def Dz(point, structure, k=1, d0=1.5):
    from pylada.crystal import neighbors
    neighs = [n for n in neighbors(structure, k, point)]
    d0 /= float(structure.scale)
    value = 0
    for i in range(k):
        value += (abs(neighs[k - 1][-1] - d0))**2
    return value
Ejemplo n.º 11
0
def test_symmetrized():
  """ Tests that symmetrized clusters are determined correctly. """
  from numpy import all, any
  from pylada.ce import Cluster
  from pylada.crystal import binary, neighbors

  lattice = binary.zinc_blende()
  lattice[0].type = ['Si', 'Ge']
  lattice[1].type = ['Si', 'Ge']

  a = Cluster(lattice)
  a.add_spin(lattice[0].pos)
  a.add_spin(lattice[0].pos + [0.0, -0.5, -0.5])
  a._create_symmetrized()

  assert len(a._symmetrized) == 2 * 12
  for i, (atom, vec, d) in enumerate(neighbors(lattice, 16, lattice[0].pos)):
    if i < 4: continue
    b = Cluster(lattice)
    b.add_spin(lattice[0].pos)
    b.add_spin(vec)
    assert any(all(b.spins == u) for u in a._symmetrized)
  for i, (atom, vec, d) in enumerate(neighbors(lattice, 16, lattice[1].pos)):
    if i < 4: continue
    b = Cluster(lattice)
    b.add_spin(lattice[1].pos)
    b.add_spin(vec)
    assert any(all(b.spins == u) for u in a._symmetrized)

  lattice = binary.zinc_blende()
  lattice[0].type = ['Si', 'Ge']
  lattice[1].type = ['Si', 'Ge', 'C']

  a = Cluster(lattice)
  a.add_spin(lattice[1].pos)
  a.add_spin(lattice[1].pos + [1.0, 0, 0])
  a._create_symmetrized()

  assert len(a._symmetrized) ==  6
  for i, (atom, vec, d) in enumerate(neighbors(lattice, 24, lattice[0].pos)):
    if i < 16: continue
    b = Cluster(lattice)
    b.add_spin(lattice[1].pos)
    b.add_spin(vec)
    assert any(all(b.spins == u) for u in a._symmetrized)
Ejemplo n.º 12
0
def check_against_neighbors(structure, tolerance=1e-8):
    from bisect import bisect_right
    from pylada.crystal import coordination_shells, neighbors

    distances = [u[-1] for u in neighbors(structure, 150, [0, 0, 0], tolerance)]
    shells = coordination_shells(structure, 10, [0, 0, 0], tolerance)
    for j in range(8):
        i = bisect_right(distances, max([u[-1] for u in shells[j]]))
        assert i == sum([len(shell) for shell in shells[:j + 1]])
Ejemplo n.º 13
0
def sort_under_coord(bulk=None, slab=None):
    """Returns indices and th coordinations of the undercoordinated atoms in a slab created from the bulk 

       :param bulk: pylada structure
       :param slab: pylada structure
    """
    from pylada.crystal import neighbors

    # Check the coordination in the bulk first shell
    bulk_first_shell = []
    for atom in bulk:
        bulk_first_shell.append(
            [atom.type, len(neighbors(structure=bulk, nmax=1, center=atom.pos, tolerance=1e-1 / bulk.scale))])

    del atom

    maxz = max([x.pos[2] for x in slab])
    minz = min([x.pos[2] for x in slab])

    # Find the undercoordinated atoms in the slab
    under_coord = []
    indices = [br for br in range(len(slab)) if slab[br].pos[
        2] <= minz + 4. / float(slab.scale) or maxz - 4. / float(slab.scale) <= slab[br].pos[2]]

    for i in indices:
        atom = slab[i]
        coordination = len(neighbors(structure=slab, nmax=1,
                                     center=atom.pos, tolerance=1e-1 / slab.scale))

        # Find the equivalent bulk atom to compare the coordination with
        for j in range(len(bulk)):
            eq_site = float(atom.site - j) / float(len(bulk))
            if abs(int(eq_site) - eq_site) < 1e-2:
                break

        # Comparing coordination with the "equivalent" bulk atom
        if coordination != bulk_first_shell[j][1]:
            under_coord.append([i, coordination])

        del coordination

    # returns the list of undercoordinated atoms,
    # atom index in the slab, coordination
    return under_coord
def calc_correlation(structure,  rad, **kwargs):

    scale = float(structure.scale)
    Natoms = len(structure)

    cell = structure.cell.T
    abc = [ v for v in structure.cell]
    ds  = [np.dot(v, v)**0.5 for v in abc]
    Vol =  np.linalg.det(cell)

    atom_types, N = get_types(structure)
    print atom_types, N 
    types_pdf = kwargs.get("types_pdf", get_pdf_types(atom_types))
    Npdfs = len(types_pdf)


    pdf_cut = kwargs.get("pdf_cut", Vol**(1/3.) * scale)/scale
    pdf_nbins  =  len(rad)

    cut2 = 6.25 / (scale**2)
    N_in_rcut = kwargs.get("N_in_rcut", int(1.2 *Natoms*4*np.pi*pdf_cut**3/(3*Vol)))

    pdfs = {}
    count = {}
    for type in types_pdf:
      [A, B] = re.findall('[A-Z][^A-Z]*', type)
      pdfs[A+B]  = np.zeros(pdf_nbins)
      count[A+B] = 0
    if 1:
      A_range = range(Natoms)
      for index_A in A_range:
        A = structure[index_A].type  
        pos_A = structure[index_A].pos
        neighs = [n for n in neighbors(structure, N_in_rcut, pos_A)]
        for i, nB in enumerate(neighs):
          index_B = get_index(structure, nB[0])
          if index_B > index_A:
            B = structure[index_B].type  
            dist = nB[2]*scale
            for Nbin, d in enumerate(rad[1:]):
              if dist < d:
                pdf_width = rad[Nbin-1] - d
                break
            if Nbin < pdf_nbins:
              pdf_width
              weigth0 = 4 * np.pi * pdf_width**3 / Vol
              val = np.zeros(pdf_nbins)
              val[Nbin] = weigth0
              pdfs[A+B] += val
              pdfs[B+A] += val
    for type in types_pdf:
      [A, B] = re.findall('[A-Z][^A-Z]*', type)
      pdfs[A+B] /=  N[B] * N[A]
      for i in range(pdf_nbins):
        pdfs[A+B][i] /=  (i + 1e-5)**2
    return pdfs
Ejemplo n.º 15
0
def first_shell(structure, pos, tolerance=0.25):
  """ Iterates though first neighbor shell. """
  from pylada.crystal import neighbors
  from copy import deepcopy

  struct = deepcopy(structure)
  for i, a in enumerate(struct):    a.index = i
  neighs = [n for n in neighbors(struct, 12, pos)]
  d = neighs[0][2]
  return [n for n in neighs if abs(n[2] - d) < tolerance * d]
def analyze_voids(zipped_voids, structure):
    ''' Analysis voids'''
    centers = []
    for value, point in zipped_voids:
        print '######', value * structure.scale
        centers.append(-value * structure.scale)
        neighs = [n for n in neighbors(structure, 7, point)]
        for n in neighs:
            print n[0].type, n[2] * structure.scale
    return centers
Ejemplo n.º 17
0
def get_all_interstitials(prim_structure, positions):
    """ function to return list of all interstitial sites using Voronoi.py

    Parameters
        prim = pylada primitive structure
        positions = positions (numpy array) to compute interstitials for

    Returns
        Inst_list = list of list, with inner list containing ['atom type', [x,y,z]]
    """

    ints_list = []

    for site_num in range(len(positions)):
        site = np.array([
            positions[site_num][0], positions[site_num][1],
            positions[site_num][2]
        ])

        site_ngh = neighbors(prim_structure, 13, site, 0.1)

        points = [site]

        ### creating list with site and its neighbors
        for i in range(len(site_ngh)):
            a = site + site_ngh[i][1]
            points.append(a)

        ### converting list to numpy array
        points = np.asarray(points)

        ### using tess object cntr to compute voronoi
        cntr = compute_voronoi(points)

        ### Voronoi vertices
        ### the first position in points is the site, therefore '0'
        v = get_vertices(0, cntr)

        for i in range(len(v)):
            ints_list.append(['B', v[i].tolist()])

        ### Voronoi face centers
        f = get_facecentroid(0, cntr)

        for j in range(len(f)):
            ints_list.append(['C', f[j].tolist()])

        ### Voronoi edge centers
        e = get_edgecenter(0, cntr)

        for k in range(len(e)):
            ints_list.append(['N', e[k].tolist()])

    ### return list of list ['Atom type', [x,y,z]]
    return ints_list
Ejemplo n.º 18
0
def check(structure, center, tolerance=1e-8):
    from numpy import abs, sqrt, all
    from pylada.crystal import neighbors

    # check we get the neighbors of zinc-blende.
    neighs = neighbors(structure, 46, center, tolerance)
    assert len(neighs) == 46
    for atom, diff, dist in neighs[:4]:
        assert abs(dist - sqrt(3.0) * 0.25) < tolerance
        assert all(abs(abs(diff) - 0.25) < tolerance)

    for atom, diff, dist in neighs[4: 16]:
        assert abs(dist - sqrt(2.0) * 0.5) < tolerance
        assert len([0 for u in diff if abs(u) < tolerance]) == 1
        assert len([0 for u in diff if abs(abs(u) - 0.5) < tolerance]) == 2

    for atom, diff, dist in neighs[16: 28]:
        assert abs(dist - sqrt(0.75 * 0.75 + 2. * 0.25 * 0.25)) < tolerance
        assert len([0 for u in diff if abs(abs(u) - 0.25) < tolerance]) == 2
        assert len([0 for u in diff if abs(abs(u) - 0.75) < tolerance]) == 1

    for atom, diff, dist in neighs[28:34]:
        assert abs(dist - 1.) < tolerance
        assert len([0 for u in diff if abs(u) < tolerance]) == 2
        assert len([0 for u in diff if abs(abs(u) - 1.) < tolerance]) == 1

    for atom, diff, dist in neighs[34:]:
        assert abs(dist - sqrt(2 * 0.75 * 0.75 + 0.25 * 0.25)) < tolerance
        assert len([0 for u in diff if abs(abs(u) - 0.75) < tolerance]) == 2
        assert len([0 for u in diff if abs(abs(u) - 0.25) < tolerance]) == 1

    # check input using position rather than atom.
    neighs2 = neighbors(structure, 36, center.pos, tolerance)
    for (a, b, c), (d, e, f) in zip(neighs, neighs2):
        assert a is d
        assert all(abs(b - e)) < tolerance
        assert abs(c - f) < tolerance

    # check neighbor completeness.
    assert len(neighbors(structure, 2, center, tolerance)) == 4
    assert len(neighbors(structure, 4, center, tolerance)) == 4
    assert len(neighbors(structure, 6, center, tolerance)) == 16
Ejemplo n.º 19
0
def first_shell(structure, pos, tolerance=0.25):
    """ Iterates though first neighbor shell. """
    from pylada.crystal import neighbors
    from copy import deepcopy

    struct = deepcopy(structure)
    for i, a in enumerate(struct):
        a.index = i
    neighs = [n for n in neighbors(struct, 12, pos)]
    d = neighs[0][2]
    return [n for n in neighs if abs(n[2] - d) < tolerance * d]
Ejemplo n.º 20
0
def get_nnb(s, i, mytol):

    nghs = neighbors(s, 20, s[i].pos, 0.001)
    shortest_dist = nghs[0][-1]
    shortest_type = nghs[0][0].type

    hlp = []
    for ng in nghs:
        if ng[0].type != shortest_type: break
        if ng[-1] > shortest_dist * (1 + mytol): continue
        hlp.append(ng)

    return len(hlp)
Ejemplo n.º 21
0
def find_ngh_indices(atomind,structure):
    """ function to return ngh indices from given atomind
   
    """
    
    nghs=neighbors(structure,1,structure[atomind],0.2)
    ngh_indices=[]

    for ii in range(len(structure)):
        if any([ all(structure[ii].pos==ngh[0].pos) for ngh in nghs]) and any([ structure[ii].type==ngh[0].type for ngh in nghs]):
           ngh_indices.append(ii)

    return ngh_indices
Ejemplo n.º 22
0
def ffirst_shell(structure, pos, tolerance):
    """ Function to iterate through the first neighbor shell
    
    Parameters
        structure = pylada structure object
        pos = position (numpy array) of site, around which neighbor shell need to be computed
        tolerance = for choosing neighbors whose distance from 'pos' is within first neighbor distance, d(1+tolerance)

    Returns
        list of neighbors, same format as pylada.crystal.neigbors
    """

    struct = deepcopy(structure)

    for i, a in enumerate(struct):
        a.index = i
        neighs = [n for n in neighbors(struct, 12, pos)]
        d = neighs[0][2]

    return [n for n in neighs if abs(n[2] - d) < tolerance * d]
Ejemplo n.º 23
0
def void_hop_type(structure,seed):
    point, value  = void.get_rnd_void_center(structure, seed=seed)
    neighs = [n for n in neighbors(structure, 12, point)]
    n0 = neighs[0]
    type0 = n0[0].type
    n_in = 0
    n_o = 0 
    for n in neighs[1:]:
      type_tmp =  n[0].type
      if (n[2] - n0[2])*structure.scale <0.4:
        if type_tmp != 'O':
          n_in +=1 
        if type_tmp == 'O':
          n_o +=1

    for n in neighs:
      type = n[0].type
      if n_in < n_o:
        if type != 'O':
            dp = point - n[0].pos
            ddp = structure.scale*np.dot(dp,dp)**0.5
            dp = impose_pbc(structure.cell, dp)
            ddp1 = structure.scale*np.dot(dp,dp)**0.5
            print type, ddp, ddp1, structure.scale*n[2]
            n[0].pos = point
            break
      else:
          if type == 'O':
            dp = point - n[0].pos
            ddp = structure.scale*np.dot(dp,dp)**0.5
            dp = impose_pbc(structure.cell, dp)
            ddp1 = structure.scale*np.dot(dp,dp)**0.5
            print type, ddp, ddp1, structure.scale*n[2]
            n[0].pos = point
            break

    #print '######moved', n_in, n_o, type, index, n[2]*structure.scale
    return structure
Ejemplo n.º 24
0
def get_2shells(s, i, mytol):

    nghs = neighbors(s, 50, s[i].pos, 0.001)
    shortest_dist = nghs[0][-1]
    shortest_type = nghs[0][0].type

    hlp = []
    for ii in range(len(nghs)):
        ng = nghs[ii]
        if ng[0].type != shortest_type: break
        if ng[-1] > shortest_dist * (1 + mytol): continue
        hlp.append(ng)

    shortest_dist = nghs[ii][-1]
    shortest_type = nghs[ii][0].type

    hlphlp = []
    for jj in range(ii, len(nghs)):
        ng = nghs[jj]
        if ng[0].type != shortest_type: break
        if ng[-1] > shortest_dist * (1 + mytol): continue
        hlphlp.append(ng)

    return [hlp, hlphlp]
Ejemplo n.º 25
0
def check_bcc():
    """ Check on BCC structure. """
    from pylada.crystal import Structure, neighbors
    structure = Structure([[-0.5, 0.5, 0.5], [0.5, -0.5, 0.5], [0.5, 0.5, -0.5]])\
        .add_atom(0, 0, 0, "Mo")
    print(neighbors(structure, 12, [0, 0, 0]))
def calc_Dx(point, structure):
    '''Calculates the distnace to the nearest atom'''
    neighs = [n for n in neighbors(structure, 3, point)]
    return -neighs[0][2]
def calc_pdfs(structure,  template = False, index = -1, **kwargs):

    scale = float(structure.scale)
    Natoms = len(structure)

    cell = structure.cell.T
    abc = [ v for v in structure.cell]
    ds  = [np.dot(v, v)**0.5 for v in abc]
    Vol =  np.linalg.det(cell)

    atom_types, N = get_types(structure)
    print atom_types, N 
    types_pdf = kwargs.get("types_pdf", get_pdf_types(atom_types))
    Npdfs = len(types_pdf)

    pdf_width = kwargs.get("pdf_width", 0.05)
    smear_flag = kwargs.get("smear_flag", True)
    pdf_sigma = kwargs.get("pdf_sigma", pdf_width)

    pdf_nsigma  = pdf_sigma/pdf_width
    pdf_nsmear = int(3*pdf_nsigma+0.5)

    pdf_cut = kwargs.get("pdf_cut", Vol**(1/3.) * scale)/scale
    pdf_nbins  =  2 *  int(pdf_cut * scale / (2* pdf_width) ) + 1
    pdf_width = pdf_cut / pdf_nbins
    cut2 = 6.25 / (scale**2)
    N_in_rcut = kwargs.get("N_in_rcut", int(1.2 *Natoms*4*np.pi*pdf_cut**3/(3*Vol)))
    weight0 = 4 * np.pi * pdf_width**3 / Vol


    pdfs = {}
    count = {}
    for type in types_pdf:
      [A, B] = re.findall('[A-Z][^A-Z]*', type)
      pdfs[A+B]  = np.zeros(pdf_nbins)
      count[A+B] = 0
    if 1:
      if index >=0:
        A_range = [index]
        weight0 = Natoms * weight0 
      else:
        A_range = range(Natoms)
        weight0 = weight0 
      for index_A in A_range:
        A = structure[index_A].type  
        pos_A = structure[index_A].pos
        neighs = [n for n in neighbors(structure, N_in_rcut, pos_A)]
        for i, nB in enumerate(neighs):
          index_B = get_index(structure, nB[0])
          if index_B > index_A:
            B = structure[index_B].type  
            Nbin =  np.around(nB[2]/pdf_width)
            if Nbin < pdf_nbins:
              #val = gauss1D( 1., Nbin, pdf_nbins, 0, pdf_nsigma)
              if smear_flag:
                val = gauss1D( 1., Nbin, pdf_nbins, pdf_nsmear, pdf_nsigma)
              else:
                val = np.zeros(pdf_nbins)
                val[Nbin] = 1
              pdfs[A+B] += val
              pdfs[B+A] += val
    for type in types_pdf:
      [A, B] = re.findall('[A-Z][^A-Z]*', type)
      pdfs[A+B] /= weight0 * N[B] * N[A]
      for i in range(pdf_nbins):
        pdfs[A+B][i] /=  (i + 1e-5)**2
    r =  pdf_width * np.arange(pdf_nbins) * scale
    return pdfs, r 
Ejemplo n.º 28
0
def void_hop(structure,seed):
    point, value  = void.get_rnd_void_center(structure, seed=seed)
    neighs = [n for n in neighbors(structure, 1, point)]
    n[0].pos = point
import numpy as np

d = json.load(open("data.json", 'r'))
cord = {}
coulomb = {"ZiZj/d": {}, 
           "1/d": {}}
for item in d:
    icsdstr = "{0:06d}".format(int(item["icsdnum"]))
    atoms = read.icsd_cif_a("/scratch/jyan/allcifs/icsd_%s.cif"%(icsdstr)) 
    ngh = defaultdict(float)
    uniqueatom = defaultdict(int)
    coul1 = defaultdict(float)
    coul2 = defaultdict(float)

    for i, atom in enumerate(atoms):
        ngh_n = neighbors(structure=atoms,nmax=1,center=atom.pos,tolerance=0.05)
        uniqueatom[atom.type] += 1
        ngh[atom.type] += len(ngh_n)
        
        Zi = getattr(pt, atom.type).atomic_number 
        # loop over neighbors
        for j in range(len(ngh_n)):
            Zj = getattr(pt, ngh_n[j][0].type).atomic_number 
            coul1[atom.type] += Zi * Zj / ngh_n[j][2]
            coul2[atom.type] += 1. / ngh_n[j][2]

    for atom in ngh.keys():
        ngh[atom] /= float(uniqueatom[atom])
        coul1[atom] /= float(uniqueatom[atom])
        coul2[atom] /= float(uniqueatom[atom])