def write_interstitials(structure, ttol=0.5): """ function to write POSCAR with interstitials Parameters: host = pylada structure object, bulk supercell recommended ttol = tolerance for finding interstitials Return: POSCAR file with interstitials, atom type "B" """ struct = deepcopy(structure) ints = get_interstitials(struct, ttol) test_str = deepcopy(struct) for nn in range(len(ints)): test_str.add_atom( np.array(ints[nn])[0], np.array(ints[nn])[1], np.array(ints[nn])[2], 'B') print('Writing file POSCAR_ints with "B" type atoms as interstitials') with open("POSCAR_ints", "w") as file: write.poscar(test_str, file, vasp5=True)
def write_tcl_one(options, A, tag): """ write tcl file for viz in VMD """ with open("POSCAR_A.%s" % tag, "w") as f: pcwrite.poscar(A, f, vasp5=True) write_xyz(options, A, "A.%s" % tag, options.output_tiles) fout = file("struct.%s.tcl" % tag, "w") center = False write_struct(fout, A, "A.%s.xyz" % tag, 0, center) fout.close()
def pylada_to_pmg(pylada_structure): ''' Converts a pylada structure to a pymatgen structure via a temporary file :param pylada_structure: Pylada structure to convert :return: Structure ''' with tempfile.NamedTemporaryFile() as tmp: name = tmp.name write.poscar(pylada_structure, name, vasp5=True) pymatgen_structure = Poscar.from_file( name).structure # pymatgen.core.Structure return pymatgen_structure
def strainstructure(orgposcar, strain, direct): import os import numpy as np from pylada.crystal import write, read outdir = gettmpdir() tmp_file_name = "POSCAR" tmp_path = os.path.join(outdir, tmp_file_name) structure = read.poscar(orgposcar) a = np.array([1.0, 1.0, 1.0]) if direct == "a": a[0] = strain elif direct == "b": a[1] = strain elif direct == "c": a[2] = strain A = np.diag(a) structure.cell = structure.cell * A for atom in structure: atom.pos = atom.pos * a write.poscar(structure, tmp_path, vasp5=True) return tmp_path
def write_tcl(options, A, B, pairs, tag="", center=False): """ write tcl file for viz in VMD """ AA = deepcopy(A) BB = deepcopy(B) if pairs != None and len(pairs) > 0: for p in pairs: ia = p[0] ib = p[1] AA[ia].pos = p[3] BB[ib].pos = p[4] with open("POSCAR_A.%s" % tag, "w") as f: pcwrite.poscar(AA, f, vasp5=True) with open("POSCAR_B.%s" % tag, "w") as f: pcwrite.poscar(BB, f, vasp5=True) write_xyz(options, AA, "A.%s" % tag, options.output_tiles) write_xyz(options, BB, "B.%s" % tag, options.output_tiles) fout = file("plotpairs.%s.tcl" % tag, "w") write_struct(fout, AA, "A.%s.xyz" % tag, 0, center) write_struct(fout, BB, "B.%s.xyz" % tag, 1, center) linestr = "draw color green; graphics top line {%f %f %f} {%f %f %f} width 3 style dashed\n" # sum = 0 for p in pairs: print p ia = p[0] ib = p[1] p1 = AA.scale * AA[ia].pos p2 = BB.scale * BB[ib].pos ## double check! print "TCL types: %s %s" % (A[ia].type, B[ib].type) # val = npl.norm(np.array(p1)-np.array(p2)) # sum += val # print "write_tcl pairing: ", p1, p2, val fout.write(linestr % (p1[0], p1[1], p1[2], p2[0], p2[1], p2[2])) # print "write_tcl total pairing dist: ", sum fout.close()
def test_istruc(): from collections import namedtuple from pickle import loads, dumps from os import remove from os.path import join, exists from shutil import rmtree from tempfile import mkdtemp from pylada.vasp.files import POSCAR, CONTCAR from pylada.vasp import Vasp from pylada.crystal import Structure, read, specieset, write from pylada.error import ValueError structure = Structure([[0, 0.5, 0.5],[0.5, 0, 0.5], [0.5, 0.5, 0]], scale=5.43, name='has a name')\ .add_atom(0,0,0, "Si")\ .add_atom(0.25,0.25,0.25, "Si") Extract = namedtuple("Extract", ['directory', 'success', 'structure']) a = Vasp() o = a._input['istruc'] d = {'IStruc': o.__class__} directory = mkdtemp() try: assert a.istruc == 'auto' assert o.output_map(vasp=a, outdir=directory, structure=structure) is None assert eval(repr(o), d).value == 'auto' assert loads(dumps(o)).value == 'auto' assert exists(join(directory, POSCAR)) remove(join(directory, POSCAR)) # check reading from outcar but only on success. a.restart = Extract(directory, False, structure.copy()) a.restart.structure[1].pos[0] += 0.02 assert a.istruc == 'auto' assert o.output_map(vasp=a, outdir=directory, structure=structure) is None assert exists(join(directory, POSCAR)) other = read.poscar(join(directory, POSCAR), types=specieset(structure)) assert abs(other[1].pos[0] - 0.25) < 1e-8 assert abs(other[1].pos[0] - 0.27) > 1e-8 # check reading from outcar but only on success. a.restart = Extract(directory, True, structure.copy()) a.restart.structure[1].pos[0] += 0.02 assert a.istruc == 'auto' assert o.output_map(vasp=a, outdir=directory, structure=structure) is None assert exists(join(directory, POSCAR)) other = read.poscar(join(directory, POSCAR), types=specieset(structure)) assert abs(other[1].pos[0] - 0.25) > 1e-8 assert abs(other[1].pos[0] - 0.27) < 1e-8 # Now check CONTCAR write.poscar(structure, join(directory, CONTCAR)) assert a.istruc == 'auto' assert o.output_map(vasp=a, outdir=directory, structure=structure) is None assert exists(join(directory, POSCAR)) other = read.poscar(join(directory, POSCAR), types=specieset(structure)) assert abs(other[1].pos[0] - 0.25) < 1e-8 assert abs(other[1].pos[0] - 0.27) > 1e-8 # Check some failure modes. write.poscar(structure, join(directory, CONTCAR)) structure[0].type = 'Ge' a.restart = None try: o.output_map(vasp=a, outdir=directory, structure=structure) except ValueError: pass else: raise Exception() structure[0].type = 'Si' structure.add_atom(0.25,0,0, 'Si') try: o.output_map(vasp=a, outdir=directory, structure=structure) except ValueError: pass else: raise Exception() finally: rmtree(directory)
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
a1 = [-d/2., d * (2+sqrt(3))/2., 0] a2 = [d * (1+sqrt(3))/2., d * (3+sqrt(3))/2., 0] a3 = [0,0,1] l1 = d*sqrt(3)/2. l2 = d*(sqrt(3)-1)/2. h1 = 1.5*d h2 = d*(3+sqrt(3))/2. structure = pyc.Structure(np.transpose([a1,a2,a3]), scale=1.0) structure.add_atom(0,0,0, "Si") structure.add_atom(0,d,0, "Si") structure.add_atom(l1, h1, 0, "Si") structure.add_atom(l2, h2, 0, "Si") write.poscar(structure, file='fakeSiO2.POSCAR') write_xyz(None, structure, 'fakeSiO2', 6) ############### hn1 = -sqrt(3)/2. * d h0 = 0 h1 = d h2 = 1.5*d h3 = (2+sqrt(3))/2. * d h4 = (3+sqrt(3))/2. * d h5 = (5+sqrt(3))/2. * d h6 = (5+2*sqrt(3))/2. * d h7 = (6+sqrt(3))/2. * d h8 = (6+2*sqrt(3))/2. * d l0 = 0
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() file.close() print("%s on core %d: FAILED"%(files[f], rank))
def make_surfaces_to_pylada(root, bulk_structure, incar_settings=None, label='', depth=8, frozen_depth=2, override=[], kpt_modifier=1): ''' :param root: root directory of run :param bulk_structure: pylada bulk strucutre :param incar_settings: location of INCAR.defaults :return: ''' from pylada.crystal import write from Generate_Surface import Generate_Surface from Helpers import pyl_to_pmg, pmg_to_pyl from Generate_Surface import get_bottom, get_SD_along_vector # small_surfaces = Generate_Surface(pyl_to_pmg(bulk_structure), 1, 1, 1, 3, vacuum=8, orth=True) for i, surface in enumerate(Generate_Surface(pyl_to_pmg(bulk_structure), 1, 1, 1, depth, vacuum=8, orth=False)): # Frozen Surface # surface_small = small_surfaces[i] surf_folder = root / label / str(i).zfill(2) surf_folder.functional = WSBulkToFrozenSurfacePBE(Vasp(), bulk_structure=bulk_structure, incar_settings=incar_settings, override=override, kpt_modifier=kpt_modifier) surf_folder.params['structure'] = pmg_to_pyl(surface).copy() os.makedirs(surf_folder.name[1:], exist_ok=True) surface.to('poscar', os.path.join(surf_folder.name[1:], 'surface.vasp')) with open(os.path.join(surf_folder.name[1:], 'DATABASE'), 'w') as f: f.write(''' surface surface_cut {} surface_termination {} convergence_study convergence_type surface misc_labels {} '''.format(i, 'None', label)) # Frozen Surfaces for frozen_region in ['top', 'bottom']: froz_folder = surf_folder / frozen_region froz_folder.functional = WSBulkToSurfacePBE(Vasp(), bulk_structure=bulk_structure, incar_settings=incar_settings, override=override, kpt_modifier=kpt_modifier) surface_frozen = surface.copy() # print(surface_frozen) sd = get_SD_along_vector(surface_frozen, 2, get_bottom(surface_frozen, length=frozen_depth, region=frozen_region)) # Poscar(surface_frozen, selective_dynamics=sd).write_file(os.path.join(froz_folder.name[1:], 'surface.vasp')) surface_frozen_pyl = pmg_to_pyl(surface_frozen) # sd_small = get_SD_along_vector(surface_frozen, frozen_depth, get_bottom(surface_frozen, region=frozen_region)) for (atom, sd) in zip(surface_frozen_pyl, sd): if sd[0]: atom.freeze = 'xyz' os.makedirs(froz_folder.name[1:], exist_ok=True) write.poscar(surface_frozen_pyl, os.path.join(froz_folder.name[1:], 'surface.vasp'), vasp5=True) froz_folder.params['structure'] = surface_frozen_pyl.copy() os.makedirs(froz_folder.name[1:], exist_ok=True) with open(os.path.join(froz_folder.name[1:], 'DATABASE'), 'w') as f: f.write(''' surface surface_cut {} surface_termination {} misc_labels {} '''.format(i, frozen_region, label))
def test_istruc(): from collections import namedtuple from pickle import loads, dumps from os import remove from os.path import join, exists from shutil import rmtree from tempfile import mkdtemp from pylada.vasp.files import POSCAR, CONTCAR from pylada.vasp import Vasp from pylada.crystal import Structure, read, specieset, write from pylada.error import ValueError structure = Structure([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]], scale=5.43, name='has a name')\ .add_atom(0, 0, 0, "Si")\ .add_atom(0.25, 0.25, 0.25, "Si") Extract = namedtuple("Extract", ['directory', 'success', 'structure']) a = Vasp() o = a._input['istruc'] d = {'IStruc': o.__class__} directory = mkdtemp() try: assert a.istruc == 'auto' assert o.output_map(vasp=a, outdir=directory, structure=structure) is None assert eval(repr(o), d).value == 'auto' assert loads(dumps(o)).value == 'auto' assert exists(join(directory, POSCAR)) remove(join(directory, POSCAR)) # check reading from outcar but only on success. a.restart = Extract(directory, False, structure.copy()) a.restart.structure[1].pos[0] += 0.02 assert a.istruc == 'auto' assert o.output_map(vasp=a, outdir=directory, structure=structure) is None assert exists(join(directory, POSCAR)) other = read.poscar(join(directory, POSCAR), types=specieset(structure)) assert abs(other[1].pos[0] - 0.25) < 1e-8 assert abs(other[1].pos[0] - 0.27) > 1e-8 # check reading from outcar but only on success. a.restart = Extract(directory, True, structure.copy()) a.restart.structure[1].pos[0] += 0.02 assert a.istruc == 'auto' assert o.output_map(vasp=a, outdir=directory, structure=structure) is None assert exists(join(directory, POSCAR)) other = read.poscar(join(directory, POSCAR), types=specieset(structure)) assert abs(other[1].pos[0] - 0.25) > 1e-8 assert abs(other[1].pos[0] - 0.27) < 1e-8 # Now check CONTCAR write.poscar(structure, join(directory, CONTCAR)) assert a.istruc == 'auto' assert o.output_map(vasp=a, outdir=directory, structure=structure) is None assert exists(join(directory, POSCAR)) other = read.poscar(join(directory, POSCAR), types=specieset(structure)) assert abs(other[1].pos[0] - 0.25) < 1e-8 assert abs(other[1].pos[0] - 0.27) > 1e-8 # Check some failure modes. write.poscar(structure, join(directory, CONTCAR)) structure[0].type = 'Ge' a.restart = None try: o.output_map(vasp=a, outdir=directory, structure=structure) except ValueError: pass else: raise Exception() structure[0].type = 'Si' structure.add_atom(0.25, 0, 0, 'Si') try: o.output_map(vasp=a, outdir=directory, structure=structure) except ValueError: pass else: raise Exception() finally: rmtree(directory)
def save_struct(options, A, tag): print "tag ", tag pcwrite.poscar(A, "%s.%s" % (options.A, tag), vasp5=True) write_tcl_one(options, A, tag)