Example #1
0
def test_zb():
    from numpy import all, abs, dot
    from pylada.crystal import space_group, transform, binary

    structure = binary.zinc_blende()
    ops = space_group(structure)
    assert len(ops) == 24
    for op in ops:
        assert op.shape == (4, 3)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type

    for atom in structure:
        atom.type = ['A', 'B']
    ops = space_group(structure)
    assert len(ops) == 48
    for op in ops:
        assert op.shape == (4, 3)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type
def test_zb():
    from numpy import all, abs, dot
    from pylada.crystal import space_group, transform, binary

    structure = binary.zinc_blende()
    ops = space_group(structure)
    assert len(ops) == 24
    for op in ops:
        assert op.shape == (4, 3)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type

    for atom in structure:
        atom.type = ['A', 'B']
    ops = space_group(structure)
    assert len(ops) == 48
    for op in ops:
        assert op.shape == (4, 3)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type
def get_symmetries0(A, mode=0):
    """ call space_group to get all symmetries of structure A.
    mode 0 -> return them all, totally unfiltered
    optionally (mode 1) reduce to unique sets of eigenvalues, b/c others are in some sense equivalent
    optionally (mode 2) combine by unique eval sets (return list of lists)
    """
    import scipy.linalg as spl
    sA = space_group(A)

    print "unfiltered symmetries:"
    for s in sA:
        print s
        print spl.eig(s[0:3, 0:3])
    print "done unfiltered symmetries"
    if (mode == 0):
        return sA

    if (mode == 1):
        sunique = [s[0]]
    else:
        sunique = [[s[0]]]
    for i in range(1, len(sA)):
        s = s[i]
        found = False
        for p in sunique:
            if eq_sym2(s, p):
                found = True
                if (mode == 2):
                    p.append(s)
                break  # out of "for p"
        if mode == 1 and not found:
            sunique.append(s)

    return sunique
Example #4
0
def symmetrically_inequivalent_sites(lattice, type):
# Haowei, not tested, but seldomly used in practice
  """ Yields sites occupied by type which are inequivalent according to symmetry operations. 
  
      When creating a vacancy on, say, "O", or a substitution of "Al" by "Mg",
      there may be more than one site which qualifies. We want to iterate over
      those sites which are inequivalent only, so that only the minimum number
      of operations are performed. 

      :note:
        lattice sites can be defined as occupiable by more than one atomic type\:
        lattice.site.type[i] = ["Al", "Mg"]. These sites will be counted if
        type in lattice.site.type, where type is the input parameter.
 
      :Parameters:
          lattice : `pylada.crystal.Lattice`
            Lattice for which to find equivalent sites.
          type : str 
            Atomic specie for which to find inequivalent sites. 

      :return: indices of inequivalent sites.
  """
  from numpy import dot
  from numpy.linalg import inv, norm
  from pylada.crystal import into_cell, space_group, primitive

  # all sites with occupation "type". 
  sites = [site for site in lattice if type in site.type]
  site_indices = [i for i,site in enumerate(lattice) if type in site.type]

  # inverse cell.
  invcell = inv(lattice.cell)
  # loop over all site with type occupation.
  i = 0
  while i < len(sites):
    # iterates over symmetry operations.
    for op in space_group(primitive(lattice)):
      pos = dot(op[:3], site.pos) + op[3] 
      # finds index of transformed position, using translation quivalents.
      for t, other in enumerate(sites):
        if norm(into_cell(pos, lattice.cell, invcell)) < 1e-12:
          print t
          break
      # removes equivalent site and index from lists if necessary
      if t != i and t < len(sites): 
        sites.pop(t)
        site_indices.pop(t)
    i += 1
  return site_indices
Example #5
0
def symmetrically_inequivalent_sites(lattice, type):
    """ Yields sites occupied by type which are inequivalent according to symmetry operations. 

        When creating a vacancy on, say, "O", or a substitution of "Al" by "Mg",
        there may be more than one site which qualifies. We want to iterate over
        those sites which are inequivalent only, so that only the minimum number
        of operations are performed. 

        :note:
          lattice sites can be defined as occupiable by more than one atomic type:
          lattice.site.type[i] = ["Al", "Mg"]. These sites will be counted if
          type in lattice.site.type, where type is the input parameter.

        :Parameters:
            lattice : `pylada.crystal.Lattice`
              Lattice for which to find equivalent sites.
            type : str 
              Atomic specie for which to find inequivalent sites. 

        :return: indices of inequivalent sites.
    """
    from numpy import dot
    from numpy.linalg import inv, norm
    from pylada.crystal import into_cell, space_group, primitive

    # all sites with occupation "type".
    sites = [site for site in lattice if type in site.type]
    site_indices = [i for i, site in enumerate(lattice) if type in site.type]

    # inverse cell.
    invcell = inv(lattice.cell)
    # loop over all site with type occupation.
    i = 0
    while i < len(sites):
        # iterates over symmetry operations.
        for op in space_group(primitive(lattice)):
            pos = dot(op[:3], site.pos) + op[3]
            # finds index of transformed position, using translation quivalents.
            for t, other in enumerate(sites):
                if norm(into_cell(pos, lattice.cell, invcell)) < 1e-12:
                    print(t)
                    break
            # removes equivalent site and index from lists if necessary
            if t != i and t < len(sites):
                sites.pop(t)
                site_indices.pop(t)
        i += 1
    return site_indices
Example #6
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)
Example #7
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)
Example #8
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])
Example #9
0
  def __init__(self, lattice, spins=None):
    from pylada.crystal import Structure, space_group
    from pylada.error import ValueError

    super(Cluster, self).__init__()
    if not isinstance(lattice, Structure): 
      raise ValueError( "Lattice should be an instance of "                    \
                        "pylada.crystal.Structure.")
    self.lattice = lattice
    """ Lattice back-bone on which this cluster exists. 

        Should be an instance of
        :py:class:`~pylada.crystal.cppwrappers.Structure` or derived.
    """
    self.spins = spins
    """ Holds array of spins. """
    self.spacegroup = getattr(lattice, 'spacegroup', space_group(self.lattice))
    """ Symmetry operations. """
def get_symmetries(A, mode=0):
    import scipy.linalg as spl
    sA = space_group(A)
    allsyms = []
    if (mode == 0):
        for s in sA:
            sym = Symmetry(s)
            allsyms.append(sym)
        return allsyms

    if (mode == 1):
        allsyms.append(Symmetry(sA[0]))
    else:
        allsyms.append([Symmetry(sA[0])])

    for i in range(1, len(sA)):
        s = sA[i]
        sym = Symmetry(s)
        found = False
        for p in allsyms:
            if (mode == 1):
                pcomp = p
            else:
                pcomp = p[0]
            if eq_evals(sym, pcomp):
                found = True
                if (mode == 2):
                    p.append(sym)
                break  # out of "for p"
        if not found:
            if (mode == 1):
                allsyms.append(sym)
            else:
                allsyms.append([sym])

    print "found syms:"
    for eqsymlist in allsyms:
        print eqsymlist[0].evals


#        for s in eqsymlist:
#            print s.evects
#        print
    return allsyms
Example #11
0
def test_fcc():
    """ Test fcc space-group """
    from numpy import all, abs, dot
    from pylada.crystal import space_group, Structure, transform

    structure = Structure([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]],
                          m=True).add_atom(0, 0, 0, "Si", m=True)
    ops = space_group(structure)
    assert len(ops) == 48
    for op in ops:
        assert op.shape == (4, 3)
        assert all(abs(op[3, :]) < 1e-8)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        assert getattr(other, 'm', False)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type
            assert getattr(atom, 'm', False)
Example #12
0
def test_fcc():
    """ Test fcc space-group """
    from numpy import all, abs, dot
    from pylada.crystal import space_group, Structure, transform

    structure = Structure([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]],
                          m=True).add_atom(0, 0, 0, "Si", m=True)
    ops = space_group(structure)
    assert len(ops) == 48
    for op in ops:
        assert op.shape == (4, 3)
        assert all(abs(op[3,:]) < 1e-8)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        assert getattr(other, 'm', False)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type
            assert getattr(atom, 'm', False)
def mess_cell(options, A, tag):
    # generated some test poscars from A (B ignored)
    from copy import deepcopy

    save_struct(options, A, "%s.orig" % tag)

    # 1) shift 1 atom, save
    AA = deepcopy(A)
    AA[1].pos = AA[1].pos + np.array([0.1, 0.1, 0.1])
    save_struct(options, AA, "%s.shift_one" % tag)

    # 2) pick a nontrivial symmetry (of lattice), apply to A, save
    AA = deepcopy(A)
    AA.clear()
    AA.add_atom(0, 0, 0, "Au")
    asym = space_group(primitive(AA))
    sym = asym[1]
    #    print sym
    AA = transform_cell(sym[0:3, :], A)
    save_struct(options, AA, "%s.sym" % tag)

    # 3) shift whole cell
    AA = deepcopy(A)
    offset = [1.2, 2.7, 0]
    for i in range(len(AA)):
        AA[i].pos = into_cell(AA[i].pos + offset, AA.cell)
    save_struct(options, AA, "%s.shift_all" % tag)

    # 4) rotate whole cell
    from util import rot_euler
    T = rot_euler(122, 27, -55)
    AA = transform_cell(T, A)
    save_struct(options, AA, "%s.rot" % tag)

    # 5) rotate AND shift
    offset = [0.5, 0.11, 0.2]
    for i in range(len(AA)):
        AA[i].pos = into_cell(AA[i].pos + offset, AA.cell)
    save_struct(options, AA, "%s.rotshift" % tag)
Example #14
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])
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
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
Example #17
0
def test_b5(u):
    """ Test b5 space-group """
    from random import random, randint
    from numpy import all, abs, dot, pi
    from numpy.linalg import inv, norm
    from numpy.random import random_sample
    from pylada.crystal import space_group, Structure, transform
    from pylada.crystal import which_site

    x, y = u, 0.25 - u
    structure = Structure([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]) \
        .add_atom(5.000000e-01, 5.000000e-01, 5.000000e-01, "A") \
        .add_atom(5.000000e-01, 2.500000e-01, 2.500000e-01, "A") \
        .add_atom(2.500000e-01, 5.000000e-01, 2.500000e-01, "A") \
        .add_atom(2.500000e-01, 2.500000e-01, 5.000000e-01, "A") \
        .add_atom(8.750000e-01, 8.750000e-01, 8.750000e-01, "B") \
        .add_atom(1.250000e-01, 1.250000e-01, 1.250000e-01, "B") \
        .add_atom(     x,     x,     x, "X") \
        .add_atom(     x,     y,     y, "X") \
        .add_atom(     y,     x,     y, "X") \
        .add_atom(     y,     y,     x, "X") \
        .add_atom(    -x,    -x,    -x, "X") \
        .add_atom(    -x,    -y,    -y, "X") \
        .add_atom(    -y,    -x,    -y, "X") \
        .add_atom(-y,    -y,    -x, "X")
    ops = space_group(structure)
    assert len(ops) == 48
    invcell = inv(structure.cell)
    for op in ops:
        assert op.shape == (4, 3)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type
        sites = []
        for i, atom in enumerate(structure):
            pos = dot(op[:3], atom.pos) + op[3]
            j = which_site(pos, structure, invcell)
            assert j != -1
            sites.append(j)
        assert len(set(sites)) == len(structure)

    structure[0], structure[-1] = structure[-1], structure[0]
    ops = space_group(structure)
    assert len(ops) == 48
    for op in ops:
        assert op.shape == (4, 3)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type
        sites = []
        for i, atom in enumerate(structure):
            pos = dot(op[:3], atom.pos) + op[3]
            j = which_site(pos, structure, invcell)
            assert j != -1, (i, atom, op)
            sites.append(j)
        assert len(set(sites)) == len(structure)

    # try random rotation, translations, atom swap
    structure[0], structure[-1] = structure[-1], structure[0]
    for u in range(10):
        axis = random_sample((3,))
        axis /= norm(axis)
        rotation = rotation_matrix(pi * random(), axis)
        translation = random_sample((3,))
        other = transform(structure, rotation, translation)
        for u in range(10):
            l, m = randint(0, len(structure) - 1), randint(0, len(structure) - 1)
            a, b = other[l], other[m]
            other[l], other[m] = b, a
        invcell = inv(other.cell)
        ops = space_group(other)
        for z, op in enumerate(ops):
            assert op.shape == (4, 3)

            other2 = transform(other, op)
            assert all(abs(dot(op[:3], other.cell) - other2.cell) < 1e-8)
            for a, atom in zip(other, other2):
                assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
                assert a.type == atom.type
            sites = []
            for i, atom in enumerate(other):
                pos = dot(op[:3], atom.pos) + op[3]
                j = which_site(pos, other, invcell)
                if j == -1:
                    print((i, z))
                    print(atom)
                    print(op)
                    print(pos)
                    print(other)
                    raise Exception()
                sites.append(j)
            assert len(set(sites)) == len(other)
Example #18
0
def test_b5(u):
    """ Test b5 space-group """
    from random import random, randint
    from numpy import all, abs, dot, pi
    from numpy.linalg import inv, norm
    from numpy.random import random_sample
    from pylada.crystal import space_group, Structure, transform
    from pylada.crystal import which_site

    x, y = u, 0.25 - u
    structure = Structure([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]) \
        .add_atom(5.000000e-01, 5.000000e-01, 5.000000e-01, "A") \
        .add_atom(5.000000e-01, 2.500000e-01, 2.500000e-01, "A") \
        .add_atom(2.500000e-01, 5.000000e-01, 2.500000e-01, "A") \
        .add_atom(2.500000e-01, 2.500000e-01, 5.000000e-01, "A") \
        .add_atom(8.750000e-01, 8.750000e-01, 8.750000e-01, "B") \
        .add_atom(1.250000e-01, 1.250000e-01, 1.250000e-01, "B") \
        .add_atom(     x,     x,     x, "X") \
        .add_atom(     x,     y,     y, "X") \
        .add_atom(     y,     x,     y, "X") \
        .add_atom(     y,     y,     x, "X") \
        .add_atom(    -x,    -x,    -x, "X") \
        .add_atom(    -x,    -y,    -y, "X") \
        .add_atom(    -y,    -x,    -y, "X") \
        .add_atom(-y,    -y,    -x, "X")
    ops = space_group(structure)
    assert len(ops) == 48
    invcell = inv(structure.cell)
    for op in ops:
        assert op.shape == (4, 3)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type
        sites = []
        for i, atom in enumerate(structure):
            pos = dot(op[:3], atom.pos) + op[3]
            j = which_site(pos, structure, invcell)
            assert j != -1
            sites.append(j)
        assert len(set(sites)) == len(structure)

    structure[0], structure[-1] = structure[-1], structure[0]
    ops = space_group(structure)
    assert len(ops) == 48
    for op in ops:
        assert op.shape == (4, 3)

        other = transform(structure, op)
        assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8)
        for a, atom in zip(structure, other):
            assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
            assert a.type == atom.type
        sites = []
        for i, atom in enumerate(structure):
            pos = dot(op[:3], atom.pos) + op[3]
            j = which_site(pos, structure, invcell)
            assert j != -1, (i, atom, op)
            sites.append(j)
        assert len(set(sites)) == len(structure)

    # try random rotation, translations, atom swap
    structure[0], structure[-1] = structure[-1], structure[0]
    for u in range(10):
        axis = random_sample((3, ))
        axis /= norm(axis)
        rotation = rotation_matrix(pi * random(), axis)
        translation = random_sample((3, ))
        other = transform(structure, rotation, translation)
        for u in range(10):
            l, m = randint(0,
                           len(structure) - 1), randint(0,
                                                        len(structure) - 1)
            a, b = other[l], other[m]
            other[l], other[m] = b, a
        invcell = inv(other.cell)
        ops = space_group(other)
        for z, op in enumerate(ops):
            assert op.shape == (4, 3)

            other2 = transform(other, op)
            assert all(abs(dot(op[:3], other.cell) - other2.cell) < 1e-8)
            for a, atom in zip(other, other2):
                assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8)
                assert a.type == atom.type
            sites = []
            for i, atom in enumerate(other):
                pos = dot(op[:3], atom.pos) + op[3]
                j = which_site(pos, other, invcell)
                if j == -1:
                    print((i, z))
                    print(atom)
                    print(op)
                    print(pos)
                    print(other)
                    raise Exception()
                sites.append(j)
            assert len(set(sites)) == len(other)