def test_gruber(): from numpy import dot from numpy.linalg import inv from pylada.math import gruber, is_integer from pylada.error import internal, input cell = [[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]] lim = 5 for a00 in [-1, 1]: for a10 in xrange(-lim, lim+1): for a11 in [-1, 1]: for a20 in xrange(-lim, lim+1): for a21 in xrange(-lim, lim+1): for a22 in [-1, 1]: a = [[a00, 0, 0], [a10, a11, 0], [a20, a21, a22]] g = gruber(dot(cell, a)) assert is_integer(dot(inv(cell), g)) assert is_integer(dot(inv(g), cell)) try: gruber([[0, 0, 0], [1, 2, 0], [4, 5, 6]]) except input: pass else: raise Exception() try: gruber([[1, 0, 0], [1, 1, 0], [4, 5, 1]], itermax=2) except internal: pass else: raise Exception()
def test_gruber(): from numpy import dot from numpy.linalg import inv from pylada.math import gruber, is_integer from pylada.error import internal, input cell = [[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]] lim = 5 for a00 in [-1, 1]: for a10 in xrange(-lim, lim+1): for a11 in [-1, 1]: for a20 in xrange(-lim, lim+1): for a21 in xrange(-lim, lim+1): for a22 in [-1, 1]: a = [[a00, 0, 0], [a10, a11, 0], [a20, a21, a22]] testcell = dot(cell, a) g = gruber(testcell) print testcell print g assert is_integer(dot(inv(cell), g)) assert is_integer(dot(inv(g), cell)) try: gruber([[0, 0, 0], [1, 2, 0], [4, 5, 6]]) except input: pass else: raise Exception() try: gruber([[1, 0, 0], [1, 1, 0], [4, 5, 1]], itermax=2) except internal: pass else: raise Exception()
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
def check(structure): from numpy import multiply, cast, any from numpy.linalg import inv from pylada.crystal.cppwrappers import periodic_dnc from pylada.math import gruber mesh, boxes = periodic_dnc(structure, nperbox=30, overlap=0.125, return_mesh = True) invcell = gruber(structure.cell) invcell[:, 0] /= float(mesh[0]) invcell[:, 1] /= float(mesh[1]) invcell[:, 2] /= float(mesh[2]) invcell = inv(invcell) for box in boxes: assert any(u[2] for u in box) for atom, trans, inbox in box: if inbox: break index = indices(invcell, trans+atom.pos, mesh) for atom, trans, inbox in box: pi = indices(invcell, trans+atom.pos, mesh) if inbox: assert all(abs(pi - index) < 1e-8), (pi, index) else: assert any( abs(u-v) == 1 \ or (w>1 and abs(u-v) == w-1) \ or w == 1 for u, v, w in zip(pi, index, mesh) )
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