def main2():
    fname1 = "geometry/test_poscars/hackit.pos"
    A = pcread.poscar(fname1)
    fname2 = "geometry/test_poscars/hackit.pos"
    B = pcread.poscar(fname2)
    
    Astats = cell_stats(A.cell)
    Bstats = cell_stats(B.cell)

    m = np.array([[1,0,0],[0,1,1],[1,0,2]])
    A = supercell(A,np.dot(A.cell, m))
    Astats = cell_stats(A.cell)

    m = len(A)/len(B)  ## for now aSSUME m integer
    print "vol factor", m
    nmatch = 0

    print "target", Astats
    print A.cell

    allms = pickle.load(file("Ms_upto_2.pickle"))
#    allms = pickle.load(file("someMs.pickle"))

#    B = supercell(B, np.dot(B.cell, np.array([[m,0,0],[0,1,0],[0,0,1]])))
    Bcells = enum.supercells(B, [m])
    print "B.cell" 
    print B.cell
    print "all size m Bcells", Bcells
    for Bc in Bcells[m]:
        Bs = supercell(B, np.dot(B.cell, Bc))
        Bstats = cell_stats(Bs.cell)
        print "source", Bstats
        print Bs.cell

#    M = np.dot(npl.inv(B.cell), A.cell)
#    print "correct M (same as original m):"
#    print M

        print "testing like crazy:"

        for i in range(len(allms)):
            M = allms[i]
            newb = np.dot(Bs.cell, M)
            stats = cell_stats(newb)
            if (equal_stats(stats, Astats)):
                print "match", i, stats
                print "M="
                print M
                print "newb="
                print newb
                print "----"
                Btest = supercell(Bs, newb)
                fout = file("ucellX%d.tcl"% nmatch , "w")
                write_xyz_noopt(Btest, "B.X%d" %nmatch ,1, no_atoms=True)
                write_struct(fout, Btest, "B.X%d.xyz" %nmatch, 0, False)
                fout.close()
                nmatch += 1

                if nmatch > 4:
                    sys.exit()
Пример #2
0
def test_random():
  from numpy import dot, all, abs
  from numpy.random import randint
  from random import choice
  from pylada.ce import Cluster
  from pylada.crystal import binary, supercell

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

  # now try random clusters with cell and their supercells
  for i in xrange(10):
    # random cluster
    a = Cluster(lattice)
    site = choice([0, 1])
    a.add_spin(lattice[site].pos)
    for j in xrange(4): 
      site = choice([0, 1])
      pos = lattice[site].pos + dot(lattice.cell, randint(4, size=(3,))-2)
      try: a.add_spin(pos)
      except ValueError: pass

    # random structure
    structure = supercell(lattice, dot(lattice.cell, get_cell(3)))
    for atom in structure: atom.type = choice(lattice[atom.site].type)

    # random supercell
    for j in xrange(5):
      sp = supercell(structure, dot(structure.cell, get_cell(3)))
      for atom in sp: atom.site = structure[atom.site].site
      assert all(abs(a(sp) - len(sp) / len(structure) * a(structure)) < 1e-8)
Пример #3
0
def test_onsite():
  """ Tests J0 PI calculation.

      This uses the same algorithmic pathway as more complex figures, but can
      be easily computed as the sum of particular specie-dependent terms on
      each site.  
  """ 
  from numpy import dot, abs, all
  from random import choice
  from pylada.crystal import binary, supercell
  from pylada.ce import Cluster

  lattice = binary.zinc_blende()
  for atom in lattice: atom.type = ['Si', 'Ge', 'C']

  structure = binary.zinc_blende()
  for atom in structure: atom.type = 'Si'

  a = Cluster(lattice)

  # Empty cluster first
  assert abs(a(structure) - len(structure)) < 1e-8
  for i in xrange(10):
    superstructure = supercell(lattice, dot(lattice.cell, get_cell()))
    for atom in superstructure: atom.type = choice(atom.type)
    assert abs(a(superstructure) - len(superstructure)) < 1e-8

  # Try on-site cluster.
  # loop over random supercells.
  # PI should be number of proportional to number of each atomic type on each
  # site, or thereabouts
  mapping = a.occupation_mapping()
  for i in xrange(10):
    # create random superstructure
    superstructure = supercell(lattice, dot(lattice.cell, get_cell()))
    for atom in superstructure: atom.type = choice(atom.type)

    # now first and second site clusters
    for i, site in enumerate(lattice):
      # loop over flavors.
      types = [u.type for u in superstructure]
      a.spins = None
      a.add_spin(site.pos)
      s = mapping[i].itervalues().next().copy()
      s[:] = 0e0
      for t in site.type:
        s += float(types.count(t)) * mapping[i][t]
      assert all(abs(a(superstructure) - s) < 1e-8)
Пример #4
0
def test_primitive(cell):
    """ Tests whether primitivization works. """
    from numpy import abs, dot
    from numpy.linalg import inv
    from pylada.crystal import supercell, Structure, are_periodic_images as api, primitive, \
        is_primitive

    lattice = Structure(0.0, 0.5, 0.5,
                        0.5, 0.0, 0.5,
                        0.5, 0.5, 0.0, scale=2.0, m=True) \
        .add_atom(0, 0, 0, "As")                           \
        .add_atom(0.25, 0.25, 0.25, ['In', 'Ga'], m=True)

    structure = supercell(lattice, dot(lattice.cell, cell))
    assert not is_primitive(structure)
    structure = primitive(structure, 1e-8)
    assert is_primitive(structure)
    assert abs(structure.volume - lattice.volume) < 1e-8
    assert len(structure) == len(lattice)
    assert is_integer(dot(structure.cell, inv(lattice.cell)))
    assert is_integer(dot(lattice.cell, inv(structure.cell)))
    invcell = inv(lattice.cell)
    for atom in structure:
        assert api(lattice[atom.site].pos, atom.pos, invcell)
        assert atom.type == lattice[atom.site].type
        assert getattr(lattice[atom.site], 'm', False) == getattr(atom, 'm', False)
        assert (getattr(atom, 'm', False) or atom.site == 0)
Пример #5
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
Пример #6
0
def test_ediff():
    from pickle import loads, dumps
    from pylada.crystal import Structure, supercell
    from pylada.vasp.incar._params import Ediff, Ediffg

    structure = Structure([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]])\
        .add_atom(0, 0, 0, 'Si')\
        .add_atom(0.25, 0.25, 0.25, 'Si')
    assert Ediff(None).incar_string(structure=structure) is None
    a = loads(dumps(Ediff(1e-4))).incar_string(structure=structure).split()
    assert a[0] == 'EDIFF' and a[1] == '=' and abs(float(a[2]) - 1e-4 * 2.) < 1e-8
    a = loads(dumps(Ediff(-1e-4))).incar_string(structure=structure).split()
    assert a[0] == 'EDIFF' and a[1] == '=' and abs(float(a[2]) - 1e-4) < 1e-8 and float(a[2]) > 0e0

    assert Ediffg(None).incar_string(structure=structure) is None
    a = loads(dumps(Ediffg(1e-4))).incar_string(structure=structure).split()
    assert a[0] == 'EDIFFG' and a[1] == '=' and abs(float(a[2]) - 1e-4 * 2.) < 1e-8
    a = loads(dumps(Ediffg(-1e-4))).incar_string(structure=structure).split()
    assert a[0] == 'EDIFFG' and a[1] == '=' and abs(float(a[2]) + 1e-4) < 1e-8

    structure = supercell(structure, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    a = loads(dumps(Ediff(1e-4))).incar_string(structure=structure).split()
    assert a[0] == 'EDIFF' and a[1] == '=' and abs(float(a[2]) - 1e-4 * 8.) < 1e-8
    a = loads(dumps(Ediff(-1e-4))).incar_string(structure=structure).split()
    assert a[0] == 'EDIFF' and a[1] == '=' and abs(float(a[2]) - 1e-4) < 1e-8 and float(a[2]) > 0e0

    a = loads(dumps(Ediffg(1e-4))).incar_string(structure=structure).split()
    assert a[0] == 'EDIFFG' and a[1] == '=' and abs(float(a[2]) - 1e-4 * 8.) < 1e-8
    a = loads(dumps(Ediffg(-1e-4))).incar_string(structure=structure).split()
    assert a[0] == 'EDIFFG' and a[1] == '=' and abs(float(a[2]) + 1e-4) < 1e-8
Пример #7
0
def test_disorder(lim=8):
  from numpy import all, array, dot
  from numpy.random import random, randint
  from numpy.linalg import det
  from pylada.crystal import binary, supercell
  from pylada.vff import build_tree


  lattice = binary.zinc_blende()
  for i in xrange(10):
    cell = randint(-lim, lim, (3,3))
    while det(cell) == 0: cell = randint(-lim, lim, (3,3))
    a = supercell(lattice, dot(lattice.cell, cell))
  
    b = build_tree(a, overlap=0.8)
    ids = [id(node.center) for node in b]
    connections = array([ sorted([ids.index(id(n.center)) for n, v in node])
                          for node in b ])
  
    epsilon = random((3,3)) * 0.1
    epsilon = epsilon + epsilon.T
    a.cell += dot(epsilon, a.cell)
    for atom in a: atom.pos += dot(epsilon, atom.pos)
    
    b = build_tree(a, overlap=0.8)
    c = array([ sorted([ids.index(id(n.center)) for n, v in node])
                          for node in b ])
    assert all(connections == c)
    
    b = build_tree(a, overlap=0.8)
    for atom in a: atom.pos += random(3) * 0.05 - 0.025
    c = array([ sorted([ids.index(id(n.center)) for n, v in node])
                          for node in b ])
    assert all(connections == c)
  return a
Пример #8
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
Пример #9
0
def test_toarray():
    """ Tests label exchange """
    from random import choice
    from numpy import all, zeros
    from pylada.crystal import binary, supercell, HFTransform
    from pylada.decorations import Transforms

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

    for u in range(11):
        structure = supercell(lattice, get_cell())
        for atom in structure:
            atom.type = choice(atom.type)
        hft = HFTransform(lattice, structure)
        a = transforms.toarray(hft, structure)
        b = zeros(len(structure), dtype='int')
        for atom in structure:
            site = lattice[atom.site]
            b[hft.index(atom.pos - site.pos,
                        atom.site)] = site.type.index(atom.type) + 1
        assert all(a == b)
Пример #10
0
def test_translations(cell):
    from numpy import abs, all
    from pylada.crystal import binary, supercell, HFTransform
    from pylada.decorations import Transforms

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

    # create random structure
    structure = supercell(lattice, cell)
    hft = HFTransform(lattice, structure)

    # these are all the translations
    translations = Transforms(lattice).translations(hft)
    assert translations.shape == (len(structure) // len(lattice) - 1,
                                  len(structure))
    # compute each translation and gets decorations
    for atom in structure:
        if atom.site != 0:
            continue
        # create translation
        trans = atom.pos - lattice[0].pos
        if all(abs(trans) < 1e-8):
            continue
        # figure out its index
        index = hft.index(trans) - 1
        for site in structure:
            pos = site.pos - lattice[site.site].pos
            i = hft.index(pos, site.site)
            j = hft.index(pos + trans, site.site)
            assert translations[index, i] == j
Пример #11
0
def test_labelexchange():
    """ Tests label exchange """
    from pylada.crystal import binary, supercell, HFTransform
    from pylada.decorations import Transforms

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

    structure = supercell(lattice, [[8, 0, 0], [0, 0.5, 0.5], [0, -0.5, 0.5]])
    species = ['Ge', 'C', 'Si', 'C', 'Si', 'C', 'Si', 'Si', 'Ge', 'Si', 'Ge',
               'Si', 'Ge', 'Si', 'Ge', 'Ge', 'Ge', 'C', 'Ge', 'Si', 'Si', 'Si',
               'Si', 'Ge', 'Si', 'Ge', 'Si', 'Si', 'Si', 'C', 'Ge', 'Si']
    for atom, s in zip(structure, species):
        atom.type = s
    hft = HFTransform(lattice, structure)
    x = transforms.toarray(hft, structure)
    results = [21112222221111123331111231122131,  # <- this is x
               21112222221111122221111321133121,
               21112222221111123332222132211232,
               21112222221111121112222312233212,
               21112222221111122223333123311323,
               21112222221111121113333213322313,
               12221111112222213331111231122131,
               12221111112222212221111321133121,
               12221111112222213332222132211232,
               12221111112222211112222312233212,
               12221111112222212223333123311323,
               12221111112222211113333213322313]
    permutations = transforms.label_exchange(hft)
    for a, b in zip(permutations(x), results[1:]):
        assert int(str(a)[1:-1].replace(' ', '')) == b
Пример #12
0
def test_translations(cell):
    from numpy import abs, all
    from pylada.crystal import binary, supercell, HFTransform
    from pylada.decorations import Transforms

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

    # create random structure
    structure = supercell(lattice, cell)
    hft = HFTransform(lattice, structure)

    # these are all the translations
    translations = Transforms(lattice).translations(hft)
    assert translations.shape == (len(structure) // len(lattice) - 1, len(structure))
    # compute each translation and gets decorations
    for atom in structure:
        if atom.site != 0:
            continue
        # create translation
        trans = atom.pos - lattice[0].pos
        if all(abs(trans) < 1e-8):
            continue
        # figure out its index
        index = hft.index(trans) - 1
        for site in structure:
            pos = site.pos - lattice[site.site].pos
            i = hft.index(pos, site.site)
            j = hft.index(pos + trans, site.site)
            assert translations[index, i] == j
Пример #13
0
def test_primitive(cell):
    """ Tests whether primitivization works. """
    from numpy import abs, dot
    from numpy.linalg import inv
    from pylada.crystal import supercell, Structure, are_periodic_images as api, primitive, \
        is_primitive

    lattice = Structure(0.0, 0.5, 0.5,
                        0.5, 0.0, 0.5,
                        0.5, 0.5, 0.0, scale=2.0, m=True ) \
        .add_atom(0, 0, 0, "As")                           \
        .add_atom(0.25, 0.25, 0.25, ['In', 'Ga'], m=True)

    structure = supercell(lattice, dot(lattice.cell, cell))
    assert not is_primitive(structure)
    structure = primitive(structure, 1e-8)
    assert is_primitive(structure)
    assert abs(structure.volume - lattice.volume) < 1e-8
    assert len(structure) == len(lattice)
    assert is_integer(dot(structure.cell, inv(lattice.cell)))
    assert is_integer(dot(lattice.cell, inv(structure.cell)))
    invcell = inv(lattice.cell)
    for atom in structure:
        assert api(lattice[atom.site].pos, atom.pos, invcell)
        assert atom.type == lattice[atom.site].type
        assert getattr(lattice[atom.site], 'm',
                       False) == getattr(atom, 'm', False)
        assert (getattr(atom, 'm', False) or atom.site == 0)
Пример #14
0
def test_coordination_shells():
    from random import random
    from numpy import array
    from numpy.random import randint, random
    from pylada.crystal import supercell, Structure

    lattice = Structure([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]) \
        .add_atom(0, 0, 0, "Si")                                      \
        .add_atom(0.25, 0.25, 0.25, "Ge")
    for atom in lattice:
        check(lattice, atom)

    structure = supercell(lattice, [[1, 1, 0], [-5, 2, 0], [0, 0, 1]])
    for index in randint(len(structure), size=4):
        check(structure, structure[index])

    for atom in lattice:
        atom.pos += random(3) * 1e-4 - 5e-5
    for atom in lattice:
        check(lattice, atom, 1e-2)

    for atom in structure:
        atom.pos += random(3) * 1e-4 - 5e-5
    for index in randint(len(structure), size=4):
        check(structure, structure[index], 1e-2)

    check_against_neighbors(structure, 1e-8)

    lattice = Structure([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]) \
        .add_atom(0, 0, 0, "Si")
    check_against_neighbors(structure, 1e-8)
    lattice = Structure([[-0.5, 0.5, 0.5], [0.5, -0.5, 0.5], [0.5, 0.5, -0.5]]) \
        .add_atom(0, 0, 0, "Si")
    check_against_neighbors(structure, 1e-8)
Пример #15
0
def explore_defect(defect, host, **kwargs):
    """ Diagnostic tool to determine defect from defect calculation and host. 

        :Parameters:
          defect : `pylada.vasp.ExtractDFT`
            Extraction object for the vasp calculation of the defect structure.
            The defect structure should be a supercell of the host. Its unit cell
            must be an exact multiple of the host unit cell. Atoms may have moved
            around, however.
          host : `pylada.vasp.ExtractDFT`
            Extraction object for the vasp calculation of the host structure.
          kwargs 
            Passed on to `reindex_sites`.

        :return: 
          Dictionary containing three items:

          - 'vacancy': a list of atoms from the host *missing* in the defect
            structure. The position of these atoms correspond to the missing atom
            in the supercell (not the translational equivalent of the unit-cell).
          - 'substitution': list of indices referring to atoms in the defect
            structure with substituted types (w.r.t. the host).
          - 'intersititial': list of indices referring to atoms in the defect
            structure with no counterpart in the host structure.

        :note: The results may be incorrect if the defects incur too much relaxation. 
    """
    from copy import deepcopy
    from pylada.crystal.defects import reindex_sites
    from pylada.crystal import supercell

    dstr = deepcopy(defect.structure)
    hstr = host.structure
    reindex_sites(dstr, hstr, **kwargs)

    result = {'interstitial': [], 'substitution': [], 'vacancy': []}
    # looks for intersitials and substitutionals.
    for i, atom in enumerate(dstr):
        if atom.site == -1:
            result['interstitial'].append(i)
        elif atom.type != hstr[atom.site].type:
            result['substitution'].append(i)

    # looks for vacancies.
    # haowei: supercell,  scale
    filled = supercell(lattice=hstr,
                       supercell=dstr.cell * dstr.scale / hstr.scale)
    reindex_sites(filled, dstr, **kwargs)
    for atom in filled:
        if atom.site != -1:
            continue
        result['vacancy'].append(deepcopy(atom))
    return result
Пример #16
0
def test_supercell():
    """ Simple supercell test. """
    from numpy import identity, abs, all, dot
    from numpy.linalg import inv
    from pylada.crystal import supercell, Structure, are_periodic_images as api
    from quantities import angstrom
    lattice = Structure(0.0, 0.5, 0.5,
                        0.5, 0.0, 0.5,
                        0.5, 0.5, 0.0, scale=2.0, m=True ) \
        .add_atom(0, 0, 0, "As")                           \
        .add_atom(0.25, 0.25, 0.25, ['In', 'Ga'], m=True)
    result = supercell(lattice, dot(lattice.cell, [[-1, 1, 1],
                                                   [1, -1, 1],
                                                   [1, 1, -1]]))
    assert all(abs(result.cell - identity(3)) < 1e-8)
    assert abs(result.scale - 2 * angstrom) < 1e-8
    assert getattr(result, 'm', False)
    assert all(abs(result[0].pos - [0.00, 0.00, 0.00]) < 1e-8)
    assert result[0].type == "As"
    assert getattr(result[0], 'site', -1) == 0
    assert api(result[0].pos, lattice[0].pos, inv(lattice.cell))
    assert all(abs(result[1].pos - [0.25, 0.25, 0.25]) < 1e-8)
    assert result[1].type == ["In", "Ga"]
    assert getattr(result[1], 'm', False)
    assert getattr(result[1], 'site', -1) == 1
    assert api(result[1].pos, lattice[1].pos, inv(lattice.cell))
    assert all(abs(result[2].pos - [0.50, 0.00, 0.50]) < 1e-8)
    assert result[2].type == "As"
    assert getattr(result[2], 'site', -1) == 0
    assert api(result[2].pos, lattice[0].pos, inv(lattice.cell))
    assert all(abs(result[3].pos - [0.75, 0.25, 0.75]) < 1e-8)
    assert result[3].type == ["In", "Ga"]
    assert getattr(result[3], 'm', False)
    assert getattr(result[3], 'site', -1) == 1
    assert api(result[3].pos, lattice[1].pos, inv(lattice.cell))
    assert all(abs(result[4].pos - [0.50, 0.50, 0.00]) < 1e-8)
    assert result[4].type == "As"
    assert getattr(result[4], 'site', -1) == 0
    assert api(result[4].pos, lattice[0].pos, inv(lattice.cell))
    assert all(abs(result[5].pos - [0.75, 0.75, 0.25]) < 1e-8)
    assert result[5].type == ["In", "Ga"]
    assert getattr(result[5], 'm', False)
    assert getattr(result[5], 'site', -1) == 1
    assert api(result[5].pos, lattice[1].pos, inv(lattice.cell))
    assert all(abs(result[6].pos - [0.00, 0.50, 0.50]) < 1e-8)
    assert result[6].type == "As"
    assert getattr(result[6], 'site', -1) == 0
    assert api(result[6].pos, lattice[0].pos, inv(lattice.cell))
    assert all(abs(result[7].pos - [0.25, 0.75, 0.75]) < 1e-8)
    assert result[7].type == ["In", "Ga"]
    assert getattr(result[7], 'm', False)
    assert getattr(result[7], 'site', -1) == 1
    assert api(result[7].pos, lattice[1].pos, inv(lattice.cell))
Пример #17
0
def explore_defect(defect, host, **kwargs):
    """ Diagnostic tool to determine defect from defect calculation and host. 

        :Parameters:
          defect : `pylada.vasp.ExtractDFT`
            Extraction object for the vasp calculation of the defect structure.
            The defect structure should be a supercell of the host. Its unit cell
            must be an exact multiple of the host unit cell. Atoms may have moved
            around, however.
          host : `pylada.vasp.ExtractDFT`
            Extraction object for the vasp calculation of the host structure.
          kwargs 
            Passed on to `reindex_sites`.

        :return: 
          Dictionary containing three items:

          - 'vacancy': a list of atoms from the host *missing* in the defect
            structure. The position of these atoms correspond to the missing atom
            in the supercell (not the translational equivalent of the unit-cell).
          - 'substitution': list of indices referring to atoms in the defect
            structure with substituted types (w.r.t. the host).
          - 'intersititial': list of indices referring to atoms in the defect
            structure with no counterpart in the host structure.

        :note: The results may be incorrect if the defects incur too much relaxation. 
    """
    from copy import deepcopy
    from pylada.crystal.defects import reindex_sites
    from pylada.crystal import supercell

    dstr = deepcopy(defect.structure)
    hstr = host.structure
    reindex_sites(dstr, hstr, **kwargs)

    result = {'interstitial': [], 'substitution': [], 'vacancy': []}
    # looks for intersitials and substitutionals.
    for i, atom in enumerate(dstr):
        if atom.site == -1:
            result['interstitial'].append(i)
        elif atom.type != hstr[atom.site].type:
            result['substitution'].append(i)

    # looks for vacancies.
    # haowei: supercell,  scale
    filled = supercell(lattice=hstr, supercell=dstr.cell *
                       dstr.scale / hstr.scale)
    reindex_sites(filled, dstr, **kwargs)
    for atom in filled:
        if atom.site != -1:
            continue
        result['vacancy'].append(deepcopy(atom))
    return result
Пример #18
0
def test_supercell():
    """ Simple supercell test. """
    from numpy import identity, abs, all, dot
    from numpy.linalg import inv
    from pylada.crystal import supercell, Structure, are_periodic_images as api
    from quantities import angstrom
    lattice = Structure(0.0, 0.5, 0.5,
                        0.5, 0.0, 0.5,
                        0.5, 0.5, 0.0, scale=2.0, m=True ) \
        .add_atom(0, 0, 0, "As")                           \
        .add_atom(0.25, 0.25, 0.25, ['In', 'Ga'], m=True)
    result = supercell(lattice,
                       dot(lattice.cell, [[-1, 1, 1], [1, -1, 1], [1, 1, -1]]))
    assert all(abs(result.cell - identity(3)) < 1e-8)
    assert abs(result.scale - 2 * angstrom) < 1e-8
    assert getattr(result, 'm', False)
    assert all(abs(result[0].pos - [0.00, 0.00, 0.00]) < 1e-8)
    assert result[0].type == "As"
    assert getattr(result[0], 'site', -1) == 0
    assert api(result[0].pos, lattice[0].pos, inv(lattice.cell))
    assert all(abs(result[1].pos - [0.25, 0.25, 0.25]) < 1e-8)
    assert result[1].type == ["In", "Ga"]
    assert getattr(result[1], 'm', False)
    assert getattr(result[1], 'site', -1) == 1
    assert api(result[1].pos, lattice[1].pos, inv(lattice.cell))
    assert all(abs(result[2].pos - [0.50, 0.00, 0.50]) < 1e-8)
    assert result[2].type == "As"
    assert getattr(result[2], 'site', -1) == 0
    assert api(result[2].pos, lattice[0].pos, inv(lattice.cell))
    assert all(abs(result[3].pos - [0.75, 0.25, 0.75]) < 1e-8)
    assert result[3].type == ["In", "Ga"]
    assert getattr(result[3], 'm', False)
    assert getattr(result[3], 'site', -1) == 1
    assert api(result[3].pos, lattice[1].pos, inv(lattice.cell))
    assert all(abs(result[4].pos - [0.50, 0.50, 0.00]) < 1e-8)
    assert result[4].type == "As"
    assert getattr(result[4], 'site', -1) == 0
    assert api(result[4].pos, lattice[0].pos, inv(lattice.cell))
    assert all(abs(result[5].pos - [0.75, 0.75, 0.25]) < 1e-8)
    assert result[5].type == ["In", "Ga"]
    assert getattr(result[5], 'm', False)
    assert getattr(result[5], 'site', -1) == 1
    assert api(result[5].pos, lattice[1].pos, inv(lattice.cell))
    assert all(abs(result[6].pos - [0.00, 0.50, 0.50]) < 1e-8)
    assert result[6].type == "As"
    assert getattr(result[6], 'site', -1) == 0
    assert api(result[6].pos, lattice[0].pos, inv(lattice.cell))
    assert all(abs(result[7].pos - [0.25, 0.75, 0.75]) < 1e-8)
    assert result[7].type == ["In", "Ga"]
    assert getattr(result[7], 'm', False)
    assert getattr(result[7], 'site', -1) == 1
    assert api(result[7].pos, lattice[1].pos, inv(lattice.cell))
def main3():
    from pylada.math import gruber
    fname1 = "geometry/test_poscars/hackit.pos"
    A0 = pcread.poscar(fname1)

    m = np.array([[1,0,0],[0,1,1],[0,0,2]])
    A = supercell(A0,np.dot(A0.cell, m))
    Ag = gruber(A.cell)

    m = np.array([[2,0,0],[0,1,0],[0,0,1]])
    B = supercell(A0,np.dot(A0.cell, m))
    Bg = gruber(B.cell)

    sa = cell_stats(Ag)
    print sa
    A2 = ang2vec(sa[3][0],sa[3][1],sa[3][2],sa[4][0],sa[4][1],sa[4][2])
    print Ag
    print A2
    sb = cell_stats(Bg)
    B2 = ang2vec(sb[3][0],sb[3][1],sb[3][2],sb[4][0],sb[4][1],sb[4][2])
    print Bg
    print B2
Пример #20
0
def test_single_counting():
  from pylada.crystal import binary, supercell
  from pylada.vff import build_tree
  a = binary.zinc_blende()
  a = supercell(binary.zinc_blende(), [[4, 0, 0], [0, 2, 0], [0, 0, 1]])
  b = build_tree(a, overlap=0.5)
  
  n = 0
  for center in b:
    for endpoint, vector in center.sc_bond_iter():
      n += 1
      for other, v in endpoint.sc_bond_iter(): assert other is not center
      assert id(center) in [id(c) for c, v in endpoint]
  assert n == 2 * len(a)
Пример #21
0
def get_a_supercell(u):
    from random import randint
    from numpy import array
    from numpy.linalg import det
    from pylada.crystal import supercell
    lattice = get_some_lattice(u)
    while True:
        cell = [[randint(-2, 3) for j in range(3)] for k in range(3)]
        if det(cell) != 0:
            break
    structure = supercell(lattice, cell)
    copy = structure.copy()
    for atom in copy:
        del atom.site
        return structure, copy, lattice
Пример #22
0
def test_angle():
  from pylada.crystal import binary, supercell
  from pylada.vff import build_tree

  a = binary.zinc_blende()
  a = supercell(binary.zinc_blende(), [[4, 0, 0], [0, 2, 0], [0, 0, 1]])
  b = build_tree(a, overlap=0.5)

  for center in b:
    ids = [id(u.center) for u, d in center]
    angles = set([(id(u.center), id(v.center)) for (u, d), (v, d) in center.angle_iter()])
    for i, ida in enumerate(ids[:-1]):
      for idb in ids[i+1:]:
        if (ida, idb) in angles: assert (idb, ida) not in angles
        else: assert (idb, ida) in angles
    assert len(angles) == 6
Пример #23
0
def test_tree():
  from numpy import all, array, dot, sum, any
  from pylada.crystal import binary, supercell
  from pylada.vff import build_tree
  a = binary.zinc_blende()
  a = supercell(binary.zinc_blende(), [[2, 0, 0], [0, 2, 0], [0, 0, 1]])
  b = build_tree(a, overlap=0.5)
  
  for center in b:
    positions = []
    for i, (bond, vector) in enumerate(center):
      position = bond.pos + dot(a.cell, vector)
      assert abs(sum((position - center.pos)**2) - 0.25*0.25*3) < 1e-8
      assert all( [any(abs(array(p) - position[None, :]) > 1e-8) for p in positions] )
      positions.append(position)
    assert i == 3
Пример #24
0
def test_firstisid(cell):
    """ Assumption is made in Transforms.transformations """
    from numpy import abs, all, identity
    from pylada.crystal import binary, supercell, space_group

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

    # create random structure
    structure = supercell(lattice, cell)
    while len(structure) > 1:
        structure.pop(-1)
    assert len(structure) == 1
    sg = space_group(structure)[0]
    assert all(abs(sg[:3] - identity(3, dtype='float64')) < 1e-8)
    assert all(abs(sg[3]) < 1e-8)
Пример #25
0
def test_firstisid(cell):
    """ Assumption is made in Transforms.transformations """
    from numpy import abs, all, identity
    from pylada.crystal import binary, supercell, space_group

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

    # create random structure
    structure = supercell(lattice, cell)
    while len(structure) > 1:
        structure.pop(-1)
    assert len(structure) == 1
    sg = space_group(structure)[0]
    assert all(abs(sg[:3] - identity(3, dtype='float64')) < 1e-8)
    assert all(abs(sg[3]) < 1e-8)
Пример #26
0
def test_rotations():
  from numpy import all, dot, zeros
  from numpy.linalg import inv
  from pylada.crystal import binary, supercell, HFTransform, space_group,        \
                           which_site
  from pylada.enum import Transforms

  lattice = binary.zinc_blende()
  lattice[0].type = ['Si', 'Ge']
  lattice[1].type = ['Si', 'Ge', 'C']
  sg = space_group(lattice)
  invcell = inv(lattice.cell)

  def get_cells(n):
    for i in xrange(1, n):
      yield [[i, 0, 0], [0, 0.5, 0.5], [0, -0.5, 0.5]]
    for i in xrange(1, n):
      yield [[i, 0, 0], [0, i, 0], [0, 0, 1]]
    for i in xrange(1, n):
      yield [[i, 0, 0], [0, i, 0], [0, 0, i]]
    yield dot(lattice.cell, [[1, 0, 0], [0, 1, 0], [0, 0, 2]])
  for cell in get_cells(8):
    # create random structure
    structure = supercell(lattice, cell)
    hft = HFTransform(lattice, structure)
 
    # these are all the translations
    transforms = Transforms(lattice)
    permutations = transforms.transformations(hft)
    assert permutations.shape == (len(sg) - 1, len(structure))
    operations = transforms.invariant_ops(structure)
    assert any(operations) 

    # compute each translation and gets decorations
    for index, (op, isgood) in enumerate(zip(sg[1:], operations)):
      if not isgood: continue
      # Create rotation and figure out its index
      permutation = zeros(len(structure), dtype='int') - 1
      for atom in structure:
        pos = dot(op[:3], atom.pos) + op[3]
        newsite = which_site(pos, lattice, invcell)
        i = hft.index(atom.pos - lattice[atom.site].pos, atom.site)
        j = hft.index(pos - lattice[newsite].pos, newsite)
        permutation[i] = j
      assert all(permutation == permutations[index])
Пример #27
0
def test_deformed_b5(u):
    from pytest import raises
    from random import randint
    from numpy import all, abs, dot, array, concatenate
    from pylada.crystal import HFTransform, supercell

    lattice = b5(u)
    supercell = supercell(lattice,
                          dot(lattice.cell, [[2, 2, 0], [0, 2, 2], [4, 0, 4]]))

    a = HFTransform(lattice.cell, supercell)

    assert all(abs(a.transform - [[-1, 1, 1], [1, -1, 1], [5, -3, -1]]) < 1e-8)
    assert all(abs(a.quotient - [2, 2, 8]) < 1e-8)
    all_indices = set()
    others = set()
    for atom in supercell:
        indices = a.indices(atom.pos - lattice[atom.site].pos)
        index = a.index(atom.pos - lattice[atom.site].pos, atom.site)
        assert index not in all_indices, (index, all_indices)
        assert all(indices >= 0)
        assert all(indices <= a.quotient)
        all_indices.add(index)
        assert str(concatenate((indices, [atom.site]))) not in others
        others.add(str(concatenate((indices, [atom.site]))))
        for i in range(20):
            vec = dot(
                supercell.cell,
                array([randint(-20, 20),
                       randint(-20, 20),
                       randint(-20, 20)],
                      dtype="float64"))
            vec += atom.pos - lattice[atom.site].pos
            assert all(abs(a.indices(vec) - indices) < 1e-8)
            with raises(ValueError):
                a.indices(vec + [0.1, 0.1, 0])
        assert index == a.index(vec, atom.site)
        with raises(ValueError):
            a.index(vec + [0.1, 0.1, 0])

    assert len(all_indices) == len(supercell)
Пример #28
0
def test_supercell_indices():
    from pytest import raises
    from random import randint
    from numpy import all, abs, dot, array
    from pylada.crystal import HFTransform, Structure, supercell

    unitcell = array([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]])
    lattice = Structure(unitcell).add_atom(0, 0, 0, "Si")
    supercell = supercell(
        lattice, dot(lattice.cell, [[3, 0, 5], [0, 0, -1], [-2, 1, 2]]))

    a = HFTransform(unitcell, supercell)

    assert all(abs(a.transform - [[0, 2, 0], [1, 5, -1], [-2, -4, 0]]) < 1e-8)
    assert all(abs(a.quotient - [1, 1, 3]) < 1e-8)
    all_indices = set()
    for atom in supercell:
        indices = a.indices(atom.pos)
        index = a.index(atom.pos)
        assert index not in all_indices, (index, all_indices)
        assert all(indices >= 0)
        assert all(indices <= a.quotient)
        assert index == a.flatten_indices(*indices)
        all_indices.add(index)
        for i in range(20):
            vec = dot(
                supercell.cell,
                array([randint(-20, 20),
                       randint(-20, 20),
                       randint(-20, 20)],
                      dtype="float64"))
            vec += atom.pos
            assert all(abs(a.indices(vec) - indices) < 1e-8)
            with raises(ValueError):
                a.indices(vec + [0.1, 0.1, 0])

            assert index == a.index(vec)
            with raises(ValueError):
                a.index(vec + [0.1, 0.1, 0])

    assert len(all_indices) == len(supercell)
Пример #29
0
def test_manysupercell():
    from numpy import dot
    from numpy.linalg import inv, det
    from pylada.crystal import supercell, binary, are_periodic_images as api
    lattice = binary.zinc_blende()
    invlat = inv(lattice.cell)
    for i in range(10):
        cell = get_cell()
        struc = supercell(lattice, dot(lattice.cell, cell))
        assert len(struc) == len(lattice) * int(abs(det(cell)) + 0.01)
        invcell = inv(struc.cell)
        for i, atom in enumerate(struc):
            # compare to lattice
            tolat = [api(atom.pos, site.pos, invlat) for site in lattice]
            assert tolat.count(True) == 1
            assert tolat.index(True) == atom.site
            assert lattice[tolat.index(True)].type == atom.type
            # compare to self
            tolat = [api(atom.pos, site.pos, invcell) for site in struc]
            assert tolat.count(True) == 1
            assert i == tolat.index(True)
Пример #30
0
def test_manysupercell():
    from numpy import dot
    from numpy.linalg import inv, det
    from pylada.crystal import supercell, binary, are_periodic_images as api
    lattice = binary.zinc_blende()
    invlat = inv(lattice.cell)
    for i in range(10):
        cell = get_cell()
        struc = supercell(lattice, dot(lattice.cell, cell))
        assert len(struc) == len(lattice) * int(abs(det(cell)) + 0.01)
        invcell = inv(struc.cell)
        for i, atom in enumerate(struc):
            # compare to lattice
            tolat = [api(atom.pos, site.pos, invlat) for site in lattice]
            assert tolat.count(True) == 1
            assert tolat.index(True) == atom.site
            assert lattice[tolat.index(True)].type == atom.type
            # compare to self
            tolat = [api(atom.pos, site.pos, invcell) for site in struc]
            assert tolat.count(True) == 1
            assert i == tolat.index(True)
Пример #31
0
def create_supercell(struct, N1, N2, N3):
    """ Create a supercell with lattice vector N1 x N2 x N3 of input cell

    Parameters
    struct = input structure (whoes supercell to be made) as pylada structure obj
    N1, N2, N3 = multiple for X, Y, Z cell vectors respectively

    Returns
    supercell = (N1 x N2 x N3) of input structure
    """

    N1 = float(N1)
    N2 = float(N2)
    N3 = float(N3)
    input_str = deepcopy(struct)
    transp_cell = np.transpose(input_str.cell)
    new_cell = np.transpose(
        np.array(
            [N1 * transp_cell[0], N2 * transp_cell[1], N3 * transp_cell[2]]))
    sc = supercell(input_str, new_cell)

    return sc
Пример #32
0
def test_labelexchange():
    """ Tests label exchange """
    from pylada.crystal import binary, supercell, HFTransform
    from pylada.decorations import Transforms

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

    structure = supercell(lattice, [[8, 0, 0], [0, 0.5, 0.5], [0, -0.5, 0.5]])
    species = [
        'Ge', 'C', 'Si', 'C', 'Si', 'C', 'Si', 'Si', 'Ge', 'Si', 'Ge', 'Si',
        'Ge', 'Si', 'Ge', 'Ge', 'Ge', 'C', 'Ge', 'Si', 'Si', 'Si', 'Si', 'Ge',
        'Si', 'Ge', 'Si', 'Si', 'Si', 'C', 'Ge', 'Si'
    ]
    for atom, s in zip(structure, species):
        atom.type = s
    hft = HFTransform(lattice, structure)
    x = transforms.toarray(hft, structure)
    results = [
        21112222221111123331111231122131,  # <- this is x
        21112222221111122221111321133121,
        21112222221111123332222132211232,
        21112222221111121112222312233212,
        21112222221111122223333123311323,
        21112222221111121113333213322313,
        12221111112222213331111231122131,
        12221111112222212221111321133121,
        12221111112222213332222132211232,
        12221111112222211112222312233212,
        12221111112222212223333123311323,
        12221111112222211113333213322313
    ]
    permutations = transforms.label_exchange(hft)
    for a, b in zip(permutations(x), results[1:]):
        assert int(str(a)[1:-1].replace(' ', '')) == b
def mess_supercells(options, A):
    # generate arbitrary supercells and mess_up() both.
    # tools should find they are the all the same.
    from pylada import enum
    from pylada.crystal import primitive
    A = primitive(A)
    #    Acells = enum.supercells(A,[2])
    #    Acells = Acells[2]
    #    print Acells
    #    if len(Acells) == 1:
    #        return

    # custom to do a better job making hard cells!
    Acells = [
        np.array([[2, 0, 0], [3, 2, 0], [4, 1, 1]]),
        np.array([[1, 0, 0], [3, 4, 0], [2, 0, 1]])
    ]

    print Acells

    for idx in range(len(Acells) - 2, len(Acells)):
        AA = supercell(A, np.dot(A.cell, Acells[idx]))
        mess_cell(options, AA, "%d" % idx)
Пример #34
0
def test_rotations(cell):
    from numpy import all, dot, zeros
    from numpy.linalg import inv
    from pylada.crystal import binary, supercell, HFTransform, space_group,        \
        which_site
    from pylada.decorations import Transforms

    lattice = binary.zinc_blende()
    lattice[0].type = ['Si', 'Ge']
    lattice[1].type = ['Si', 'Ge', 'C']
    sg = space_group(lattice)
    invcell = inv(lattice.cell)

    # create random structure
    structure = supercell(lattice, cell)
    hft = HFTransform(lattice, structure)

    # these are all the translations
    transforms = Transforms(lattice)
    permutations = transforms.transformations(hft)
    assert permutations.shape == (len(sg) - 1, len(structure))
    operations = transforms.invariant_ops(structure)
    assert any(operations)

    # compute each translation and gets decorations
    for index, (op, isgood) in enumerate(zip(sg[1:], operations)):
        if not isgood:
            continue
        # Create rotation and figure out its index
        permutation = zeros(len(structure), dtype='int') - 1
        for atom in structure:
            pos = dot(op[:3], atom.pos) + op[3]
            newsite = which_site(pos, lattice, invcell)
            i = hft.index(atom.pos - lattice[atom.site].pos, atom.site)
            j = hft.index(pos - lattice[newsite].pos, newsite)
            permutation[i] = j
        assert all(permutation == permutations[index])
Пример #35
0
def test_supercell_indices():
    from pytest import raises
    from random import randint
    from numpy import all, abs, dot, array
    from pylada.crystal import HFTransform, Structure, supercell

    unitcell = array([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]])
    lattice = Structure(unitcell).add_atom(0, 0, 0, "Si")
    supercell = supercell(lattice, dot(lattice.cell, [[3, 0, 5], [0, 0, -1], [-2, 1, 2]]))

    a = HFTransform(unitcell, supercell)

    assert all(abs(a.transform - [[0, 2, 0], [1, 5, -1], [-2, -4, 0]]) < 1e-8)
    assert all(abs(a.quotient - [1, 1, 3]) < 1e-8)
    all_indices = set()
    for atom in supercell:
        indices = a.indices(atom.pos)
        index = a.index(atom.pos)
        assert index not in all_indices, (index, all_indices)
        assert all(indices >= 0)
        assert all(indices <= a.quotient)
        assert index == a.flatten_indices(*indices)
        all_indices.add(index)
        for i in range(20):
            vec = dot(supercell.cell, array(
                [randint(-20, 20), randint(-20, 20), randint(-20, 20)], dtype="float64"))
            vec += atom.pos
            assert all(abs(a.indices(vec) - indices) < 1e-8)
            with raises(ValueError):
                a.indices(vec + [0.1, 0.1, 0])

            assert index == a.index(vec)
            with raises(ValueError):
                a.index(vec + [0.1, 0.1, 0])

    assert len(all_indices) == len(supercell)
Пример #36
0
def test_toarray():
    """ Tests label exchange """
    from random import choice
    from numpy import all, zeros
    from pylada.crystal import binary, supercell, HFTransform
    from pylada.decorations import Transforms

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

    for u in range(11):
        structure = supercell(lattice, get_cell())
        for atom in structure:
            atom.type = choice(atom.type)
        hft = HFTransform(lattice, structure)
        a = transforms.toarray(hft, structure)
        b = zeros(len(structure), dtype='int')
        for atom in structure:
            site = lattice[atom.site]
            b[hft.index(atom.pos - site.pos, atom.site)] = site.type.index(atom.type) + 1
        assert all(a == b)
Пример #37
0
def test_deformed_b5(u):
    from pytest import raises
    from random import randint
    from numpy import all, abs, dot, array, concatenate
    from pylada.crystal import HFTransform, supercell

    lattice = b5(u)
    supercell = supercell(lattice, dot(lattice.cell, [[2, 2, 0], [0, 2, 2], [4, 0, 4]]))

    a = HFTransform(lattice.cell, supercell)

    assert all(abs(a.transform - [[-1, 1, 1], [1, -1, 1], [5, -3, -1]]) < 1e-8)
    assert all(abs(a.quotient - [2, 2, 8]) < 1e-8)
    all_indices = set()
    others = set()
    for atom in supercell:
        indices = a.indices(atom.pos - lattice[atom.site].pos)
        index = a.index(atom.pos - lattice[atom.site].pos, atom.site)
        assert index not in all_indices, (index, all_indices)
        assert all(indices >= 0)
        assert all(indices <= a.quotient)
        all_indices.add(index)
        assert str(concatenate((indices, [atom.site]))) not in others
        others.add(str(concatenate((indices, [atom.site]))))
        for i in range(20):
            vec = dot(supercell.cell, array(
                [randint(-20, 20), randint(-20, 20), randint(-20, 20)], dtype="float64"))
            vec += atom.pos - lattice[atom.site].pos
            assert all(abs(a.indices(vec) - indices) < 1e-8)
            with raises(ValueError):
                a.indices(vec + [0.1, 0.1, 0])
        assert index == a.index(vec, atom.site)
        with raises(ValueError):
            a.index(vec + [0.1, 0.1, 0])

    assert len(all_indices) == len(supercell)
Пример #38
0
def raw_anim(A, B, options):
    # just animate between A and B, straight up!
    ### this option is under development
    savedir = os.getcwd()
    os.chdir(options.trajdir)

    structure = pcread.poscar(options.A)
    structure = pcread.poscar(options.B)

    print "saving starting anim"
    Bpath = deepcopy(B)
    tag = "Bpath0"
    write_xyz(options, Bpath, tag, options.output_tiles)
    fout = file("%s.tcl" % tag, "w")
    write_struct(fout,
                 Bpath,
                 "%s.xyz" % tag,
                 0,
                 center=False,
                 bonds=True,
                 bond_len=options.bond_len)
    fout.close()

    # now write frames
    dt = 1.0 / (options.frames - 1)
    t = 0
    iter = 0
    eps = 1e-6
    curpos = []
    while t <= 1 + eps:
        Bpath = deepcopy(B)
        Bpath.cell = t * A.cell + (1.0 - t) * B.cell
        for i in range(len(apos)):
            pos = t * A[i].pos[i] + (1.0 - t) * B[i].pos[i]
            if (iter == 0):
                Bpath[i].pos = into_cell(
                    pos, Bpath.cell)  # then make sure it's _in_ the unit cell
                curpos.append(Bpath[i].pos)
            else:
                Bpath[i].pos = closest_to(pos, Bpath.cell, curpos[i])
                curpos[i] = Bpath[i].pos

        if (iter == 0):  ## testing/bug fixing
            from pylada.crystal import space_group, primitive
            from pylada.math import gruber
            Btest = primitive(Bpath)
            g = gruber(Btest.cell)
            print "src has cell:"
            print Btest.cell
            #            print g
            Btest = supercell(Btest, g)
            spacegroup = space_group(Btest)
            sg = spglib.get_spacegroup(Btest,
                                       symprec=1e-4,
                                       angle_tolerance=2.0)
            print "src has %d syms and sg %s" % (len(spacegroup), str(sg))
            Bstart = deepcopy(Bpath)

        sg = spglib.get_spacegroup(Bpath, symprec=1e-4, angle_tolerance=2.0)
        #        sg = spglib.get_spacegroup(Bpath, symprec=1e-1, angle_tolerance=10.0) ### debugging
        print t, sg, tag

        if (iter == options.frames - 1):  ## testing/bug fixing
            from pylada.crystal import space_group, primitive
            from pylada.math import gruber
            Btest = primitive(Bpath)
            g = gruber(Btest.cell)
            print "target has cell:"
            print Btest.cell
            #            print g
            Btest = supercell(Btest, g)
            spacegroup = space_group(Btest)
            sg = spglib.get_spacegroup(Btest,
                                       symprec=1e-4,
                                       angle_tolerance=2.0)
            print "target has %d syms and sg %s" % (len(spacegroup), str(sg))
            Bend = deepcopy(Bpath)

        tag = "traj.%d" % iter
        write_xyz(options, Bpath, tag, options.output_tiles)
        fout = file("%s.tcl" % tag, "w")
        write_struct(fout,
                     Bpath,
                     "%s.xyz" % tag,
                     0,
                     center=False,
                     bonds=True,
                     bond_len=options.bond_len)
        fout.close()

        # write poscar we can analyze later
        #        bigB = supercell(Bpath, np.dot(eye2,Bpath.cell))  # for writing a big poscar
        with open("%s.POSCAR" % tag, "w") as f:
            pcwrite.poscar(Bpath, f, vasp5=True)

        t += dt
        iter += 1

    os.chdir(savedir)
    if (options.verbose > 2):
        write_tcl(options, Bend, Bstart, pairs[1], "pairs")

    # some special work to verify we really arrived at B:


#    Borig = pcread.poscar(options.A)
#    M = np.dot(Borig.cell, npl.inv(Bpath.cell))
#    Bfinal = transform_cell(M,Bpath)
#    bigB = supercell(Bfinal, np.dot(eye2,Bfinal.cell))  ## this is a special "doubling" test
#    with open("final.POSCAR", "w") as f: pcwrite.poscar(bigB, f, vasp5=True)
#    with open("final.POSCAR", "w") as f: pcwrite.poscar(Bfinal, f, vasp5=True)
#    sg = spglib.get_spacegroup(Bfinal, symprec=1e-4, angle_tolerance=2.0)  ## this is "B in A coords"
#    print "spacegroup of final structure: ", sg
    sg = spglib.get_spacegroup(B, symprec=1e-4, angle_tolerance=2.0)
    print "spacegroup of initial structure (B, [Bflip in code]) ", sg
    sg = spglib.get_spacegroup(A, symprec=1e-4, angle_tolerance=2.0)
    print "spacegroup of target structure (A) ", sg
Пример #39
0
def make_anim(A, B, Tm, shift, pairs, options):
    # combined view of the unit call and atom transforms
    # A is target, B is src, after src has been rotated and its unit cell axes permuted so that they
    # "most align" with those of A.  Then transform is just two parts: first is unit cell Tform "Tm"
    # next is mapping in pairs
    ### no longer true: which is expressed in 3N-dim space as bigA.

    from copy import deepcopy
    from util import write_struct, write_xyz, transform_cell, write_tcl

    if options.verbose > 1:
        print "Exploring minimal path we have discovered..."
        # the results come out a little convoluated b/c of all the steps, so here we gather the
        # actual start and finish positions.

        details = False

        print B.cell
        print "maps to"
        print A.cell
        print "with internal atom shift"
        print shift
        print "and atom idx pairing"

    ppidx = pairs[0]
    ppos = pairs[1]
    ainv = npl.inv(A.cell)
    apos = []
    bpos = []
    for i in range(len(ppidx)):
        p = ppidx[i]
        q = ppos[i]
        print p, q  ##, into_cell(np.dot(B.cell, np.dot(ainv, q[4])), B.cell)
        apos.append(q[3])  # target atom position
        bpos.append(q[4])  # src atom position

    if (options.verbose > 2):
        print "and A is just"
        print A.cell
        for a in A:
            print a.pos, into_cell(a.pos, A.cell)
        print "and B is just"
        print B.cell
        for b in B:
            print b.pos, into_cell(b.pos, B.cell)

    if (not os.path.exists(options.trajdir)):
        os.mkdir(options.trajdir)

    savedir = os.getcwd()
    os.chdir(options.trajdir)

    if (options.verbose > 1):
        print "saving starting anim"
    Bpath = deepcopy(B)
    tag = "Bpath0"
    write_xyz(options, Bpath, tag, options.output_tiles)
    fout = file("%s.tcl" % tag, "w")
    write_struct(fout,
                 Bpath,
                 "%s.xyz" % tag,
                 0,
                 center=False,
                 bonds=True,
                 bond_len=options.bond_len)
    fout.close()

    # now write frames
    eye2 = 2.0 * np.identity(3)  # for writing a big cell if we want
    dt = 1.0 / (options.frames - 1)
    t = 0
    iter = 0
    eps = 1e-6
    curpos = []
    while t <= 1 + eps:

        Bpath = deepcopy(B)
        Bpath.cell = t * A.cell + (1.0 - t) * B.cell
        for i in range(len(apos)):
            p = t * apos[i] + (1.0 - t) * bpos[
                i]  # this is an abs position, but in A's frame of reference (both apos and bpos are created with
            # B.cell transformed to A.cell.  Here we are mapping to cells in between original B.cell and A.cell)
            # Note apos and bpos are not taken directly from A, B input cells but are part of the "pairing" data
            c = np.dot(ainv, p)  # so get the coords
            pos = np.dot(Bpath.cell,
                         c)  # and express it w.r.t. evolving Bpath frame
            if (iter == 0):
                Bpath[i].pos = into_cell(
                    pos, Bpath.cell)  # then make sure it's _in_ the unit cell
                curpos.append(Bpath[i].pos)
            else:
                Bpath[i].pos = closest_to(pos, Bpath.cell, curpos[i])
                curpos[i] = Bpath[i].pos

        if (iter == 0):  ## testing/bug fixing
            Bstart = deepcopy(Bpath)
            if (options.verbose > 2):
                from pylada.crystal import space_group, primitive
                from pylada.math import gruber
                Btest = primitive(Bpath)
                g = gruber(Btest.cell)
                print "src has primitive cell:"
                print Btest.cell
                #            print g
                Btest = supercell(Btest, g)
                spacegroup = space_group(Btest)
                sg = spglib.get_spacegroup(Btest,
                                           symprec=1e-4,
                                           angle_tolerance=2.0)
                print "src has %d syms and sg %s" % (len(spacegroup), str(sg))

        sg = spglib.get_spacegroup(Bpath, symprec=1e-4, angle_tolerance=2.0)
        #        sg = spglib.get_spacegroup(Bpath, symprec=1e-1, angle_tolerance=10.0) ### debugging
        if (options.verbose > 1):
            print t, sg, tag

        if (iter == options.frames - 1):  ## testing/bug fixing
            Bend = deepcopy(Bpath)
            if (options.verbose > 2):
                from pylada.crystal import space_group, primitive
                from pylada.math import gruber
                Btest = primitive(Bpath)
                g = gruber(Btest.cell)
                print "target has primitive cell:"
                print Btest.cell
                #            print g
                Btest = supercell(Btest, g)
                spacegroup = space_group(Btest)
                sg = spglib.get_spacegroup(Btest,
                                           symprec=1e-4,
                                           angle_tolerance=2.0)
                print "target has %d syms and sg %s" % (len(spacegroup),
                                                        str(sg))

        tag = "traj.%d" % iter
        write_xyz(options, Bpath, tag, options.output_tiles)
        fout = file("%s.tcl" % tag, "w")
        write_struct(fout,
                     Bpath,
                     "%s.xyz" % tag,
                     0,
                     center=False,
                     bonds=True,
                     bond_len=options.bond_len)
        fout.close()

        # write poscar we can analyze later
        #        bigB = supercell(Bpath, np.dot(eye2,Bpath.cell))  # for writing a big poscar
        with open("%s.POSCAR" % tag, "w") as f:
            pcwrite.poscar(Bpath, f, vasp5=True)

        t += dt
        iter += 1

    os.chdir(savedir)
    if (options.verbose > 2):
        write_tcl(options, Bend, Bstart, pairs[1], "pairs")

    # some special work to verify we really arrived at B:


#    Borig = pcread.poscar(options.A)
#    M = np.dot(Borig.cell, npl.inv(Bpath.cell))
#    Bfinal = transform_cell(M,Bpath)
#    bigB = supercell(Bfinal, np.dot(eye2,Bfinal.cell))  ## this is a special "doubling" test
#    with open("final.POSCAR", "w") as f: pcwrite.poscar(bigB, f, vasp5=True)
#    with open("final.POSCAR", "w") as f: pcwrite.poscar(Bfinal, f, vasp5=True)
#    sg = spglib.get_spacegroup(Bfinal, symprec=1e-4, angle_tolerance=2.0)  ## this is "B in A coords"
#    print "spacegroup of final structure: ", sg
    sg = spglib.get_spacegroup(B, symprec=1e-4, angle_tolerance=2.0)
    if (options.verbose > 0):
        print "spacegroup of initial structure (B, [Bflip in code]) ", sg
    sg = spglib.get_spacegroup(A, symprec=1e-4, angle_tolerance=2.0)
    if (options.verbose > 1):
        print "spacegroup of target structure (A) ", sg
Пример #40
0
from copy import deepcopy
import os
from pylada.crystal import supercell, Structure
import pylada.periodic_table as pt
import pickle
import numpy as np

nproc = 96

# Primittive structure
perfectStruc = Structure([[0.5, 0.5, 0], [0.5, 0, 0.5], [0, 0.5, 0.5]])
perfectStruc.add_atom(0, 0, 0, 'Si')
perfectStruc.add_atom(0.25, 0.25, 0.25, 'Si')

# Building the (perfect) supercell
perfectStrucsc = supercell(perfectStruc, 4 * perfectStruc.cell)

# Primitive Cell Calculations ########################################################

# Relaxation
pwrelax = pwcalc()
pwrelax.name = "pcPara"
pwrelax.calc_type = "vc-relax"
pwrelax.restart_mode = "from_scratch"
pwrelax.pseudo_dir = os.path.expanduser("~/scratch/pseudo_pz-bhs/")
pwrelax.celldm = 10.7
pwrelax.ecutwfc = 45.0
pwrelax.ecutrho = 400.0
pwrelax.nbnd = len(perfectStruc) * 4
pwrelax.occupations = "fixed"
pwrelax.masses = {'Si': pt.Si.atomic_weight}
Пример #41
0
        # print("Done with the supercell")
        try:
            slab = minimize_broken_bonds(bulk=bulk,slab=slab,vacuum=vacuum,charge=charge,minimize_total=True)

        except AssertionError:
            print("Charges do not sum up to zero for %s, the charges are:"%(files[f]), charge)
            print("Going to the next structure.")
            break
        # print("Done with the supercell construction, now shaping it")
        
        cell=transpose(slab.cell)
        cell[2][0]=0.
        cell[2][1]=0.
        slab.cell=transpose(cell)
        r=diag([1,1,1])
        slab=supercell(slab,dot(slab.cell,r))
        
        write.poscar(structure=slab,file=outdir_cur + '/POSCAR_%s%s%s_%slay_%svac' %(miller[0],miller[1],miller[2],nlayers,vacuum),vasp5=True)
        
        file.write('% 2i  % 2i  % 2i    broken_bonds %2.4f %2.4f polar=%s\n' %(miller[0],miller[1],miller[2],count_broken_bonds(bulk=bulk,slab=slab),count_broken_bonds_per_area(bulk=bulk,slab=slab),is_polar(slab=slab,charge=charge)))
        file.flush()

    else:
        file.write('DONE %d\n'%(miller_bounds))
        file.flush()
        file.close()
        print("%s on core %d: DONE"%(files[f], rank))
        continue

    file.write('FAILED\n')
    file.flush()
Пример #42
0
relax = Relax(copy=vasp)

relax.nsw=75
relax.minrelsteps= 4
relax.maxiter = 10
relax.keep_steps = True
relax.first_trial = { "kpoints": "\n0\nAuto\n10", "encut": 0.9 }

############### setting up the structures

# input bulk primitive cell
In2O3prim = read.poscar('POSCAR_In2O3')

# create bulk supercell
In2O3_sc = supercell(In2O3prim,np.diag([In2O3prim.cell[0][0]*2., In2O3prim.cell[1][1]*2., In2O3prim.cell[2][2]*2.]))

# create list of job folders
calcs = ['epsilon', 'SC', 'Ini', 'VIn', 'OIn']

structures = {}

for calc in calcs:
    if calc=='epsilon':
        structure=deepcopy(In2O3prim)
        structures[calc]=structure

    else:
        structure=deepcopy(In2O3_sc)

        # supercell
Пример #43
0
from pylada.crystal import supercell, Structure
from prepare import reciprocal
from mpl_toolkits.mplot3d import Axes3D
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

tol = 1e-12

# Primittive structure
A = Structure([[0.5, 0.5, 0], [0.5, 0, 0.5], [0, 0.5, 0.5]])
A.add_atom(0, 0, 0, 'Si')
A.add_atom(0.25, 0.25, 0.25, 'Si')

# Building the (perfect) supercell
Asc = supercell(A, [[3, 0, 0], [0, 3, 0], [0, 0, 3]])

rpc = reciprocal(A.cell)  #reciprocal lattice of PC
irpc = np.linalg.inv(rpc)  #inverse of reciprocal lattice of PC

rsc = reciprocal(Asc.cell)  #reciprocal lattice of SC
irsc = np.linalg.inv(rsc)  #inverse of reciprocal lattice of SC

# big square
# Finds the furthest corner
corner = np.array([[0, 0, 0]])
for i in range(2):
    for j in range(2):
        for k in range(2):
            corner = np.reshape(
                np.max(np.concatenate(
Пример #44
0
def make_surface(structure=None, miller=None, nlayers=5, vacuum=15, acc=5):
    """Returns a slab from the 3D structure 

       Takes a structure and makes a slab defined by the miller indices 
       with nlayers number of layers and vacuum defining the size 
       of the vacuum thickness. Variable acc determines the number of 
       loops used to get the direct lattice vectors perpendicular 
       and parallel to miller. For high index surfaces use larger acc value 
       .. warning: (1) cell is always set such that miller is alogn z-axes
                   (2) nlayers and vacuum are always along z-axes.

       :param structure: LaDa structure
       :param miller: 3x1 float64 array
           Miller indices defining the slab    
       :param nlayers: integer
           Number of layers in the slab
       :param vacuum: real
           Vacuum thicness in angstroms
       :param acc: integer
           number of loops for finding the cell vectors of the slab structure
    """
    direct_cell = transpose(structure.cell)
    reciprocal_cell = 2 * pi * transpose(inv(direct_cell))

    orthogonal = []  # lattice vectors orthogonal to miller

    for n1 in arange(-acc, acc + 1):
        for n2 in arange(-acc, acc + 1):
            for n3 in arange(-acc, acc + 1):

                pom = array([n1, n2, n3])
                if dot(pom, miller) == 0 and dot(pom, pom) != 0:
                    orthogonal.append(array([n1, n2, n3]))

    # chose the shortest parallel and set it to be a3 lattice vector
    norm_orthogonal = [sqrt(dot(dot(x, direct_cell), dot(x, direct_cell))) for x in orthogonal]
    a1 = orthogonal[norm_orthogonal.index(min(norm_orthogonal))]

    # chose the shortest orthogonal to miller and not colinear with a1 and set it as a2
    in_plane = []

    for x in orthogonal:
        if dot(x, x) > 1e-3:
            v = cross(dot(x, direct_cell), dot(a1, direct_cell))
            v = sqrt(dot(v, v))
            if v > 1e-3:
                in_plane.append(x)

    norm_in_plane = [sqrt(dot(dot(x, direct_cell), dot(x, direct_cell))) for x in in_plane]
    a2 = in_plane[norm_in_plane.index(min(norm_in_plane))]

    a1 = dot(a1, direct_cell)
    a2 = dot(a2, direct_cell)

    # new cartesian axes z-along miller, x-along a1, and y-to define the right-hand orientation
    e1 = a1 / sqrt(dot(a1, a1))
    e2 = a2 - dot(e1, a2) * e1
    e2 = e2 / sqrt(dot(e2, e2))
    e3 = cross(e1, e2)

    # find vectors parallel to miller and set the shortest to be a3
    parallel = []

    for n1 in arange(-acc, acc + 1):
        for n2 in arange(-acc, acc + 1):
            for n3 in arange(-acc, acc + 1):
                pom = dot(array([n1, n2, n3]), direct_cell)
                if sqrt(dot(pom, pom)) - dot(e3, pom) < 1e-8 and sqrt(dot(pom, pom)) > 1e-3:
                    parallel.append(pom)

    # if there are no lattice vectors parallel to miller
    if len(parallel) == 0:
        for n1 in arange(-acc, acc + 1):
            for n2 in arange(-acc, acc + 1):
                for n3 in arange(-acc, acc + 1):
                    pom = dot(array([n1, n2, n3]), direct_cell)
                    if dot(e3, pom) > 1e-3:
                        parallel.append(pom)

    parallel = [x for x in parallel if sqrt(
        dot(x - dot(e1, x) * e1 - dot(e2, x) * e2, x - dot(e1, x) * e1 - dot(e2, x) * e2)) > 1e-3]
    norm_parallel = [sqrt(dot(x, x)) for x in parallel]

    assert len(norm_parallel) != 0, "Increase acc, found no lattice vectors parallel to (hkl)"

    a3 = parallel[norm_parallel.index(min(norm_parallel))]

    # making a structure in the new unit cell - defined by the a1,a2,a3
    new_direct_cell = array([a1, a2, a3])

    assert abs(det(new_direct_cell)) > 1e-5, "Something is wrong your volume is equal to zero"

    # make sure determinant is positive
    if det(new_direct_cell) < 0.:
        new_direct_cell = array([-a1, a2, a3])

    #structure = fill_structure(transpose(new_direct_cell),structure.to_lattice())
    structure = supercell(lattice=structure, supercell=transpose(new_direct_cell))

    # transformation matrix to new coordinates x' = dot(m,x)
    m = array([e1, e2, e3])

    # seting output structure
    out_structure = Structure()
    out_structure.scale = structure.scale
    out_structure.cell = transpose(dot(new_direct_cell, transpose(m)))

    for atom in structure:
        p = dot(m, atom.pos)
        out_structure.add_atom(p[0], p[1], p[2], atom.type)

    # repaeting to get nlayers and vacuum
    repeat_cell = dot(out_structure.cell, array([[1., 0., 0.], [0., 1., 0.], [0., 0., nlayers]]))
    out_structure = supercell(lattice=out_structure, supercell=repeat_cell)

    # checking whether there are atoms close to the cell faces and putting them back to zero
    for i in range(len(out_structure)):
        scaled_pos = dot(out_structure[i].pos, inv(transpose(out_structure.cell)))
        for j in range(3):
            if abs(scaled_pos[j] - 1.) < 1e-5:
                scaled_pos[j] = 0.
        out_structure[i].pos = dot(scaled_pos, transpose(out_structure.cell))

    # adding vaccum to the cell
    out_structure.cell = out_structure.cell + \
        array([[0., 0., 0.], [0., 0., 0.], [0., 0., float(vacuum) / float(out_structure.scale)]])

    # translating atoms so that center of the slab and the center of the cell along z-axes coincide
    max_z = max([x.pos[2] for x in out_structure])
    min_z = min([x.pos[2] for x in out_structure])
    center_atoms = 0.5 * (max_z + min_z)
    center_cell = 0.5 * out_structure.cell[2][2]

    for i in range(len(out_structure)):
        out_structure[i].pos = out_structure[i].pos + array([0., 0., center_cell - center_atoms])

    # exporting the final structure
    return out_structure
Пример #45
0
def expand_cell_by(A, m):
    cellA = np.array(m) * A.cell
    bigA = supercell(A, cellA)
    return bigA