def set_sd_flags(poscar_input=None, n_layers=2, top=True, bottom=True, poscar_output='POSCAR2'): """ set the relaxation flags for top and bottom layers of interface. The upper and lower bounds of the z coordinate are determined based on the slab. Args: poscar_input: input poscar file name n_layers: number of layers to be relaxed top: whether n_layers from top are be relaxed bottom: whether n_layers from bottom are be relaxed poscar_output: output poscar file name Returns: None writes the modified poscar file """ poscar1 = Poscar.from_file(poscar_input) sd_flags = np.zeros_like(poscar1.structure.frac_coords) z_coords = poscar1.structure.frac_coords[:, 2] z_lower_bound, z_upper_bound = None, None if bottom: z_lower_bound = np.unique(z_coords)[n_layers - 1] sd_flags[np.where(z_coords <= z_lower_bound)] = np.ones((1, 3)) if top: z_upper_bound = np.unique(z_coords)[-n_layers] sd_flags[np.where(z_coords >= z_upper_bound)] = np.ones((1, 3)) poscar2 = Poscar(poscar1.structure, selective_dynamics=sd_flags.tolist()) poscar2.write_file(filename=poscar_output)
def create_surface2(st, miller_index, min_slab_size=10, min_vacuum_size=10, surface_i=0, oxidation=None, suf='', primitive=None, symmetrize=False): """ INPUT: st (Structure) - Initial input structure. Note that to ensure that the miller indices correspond to usual crystallographic definitions, you should supply a conventional unit cell structure. miller_index ([h, k, l]): Miller index of plane parallel to surface. Note that this is referenced to the input structure. If you need this to be based on the conventional cell, you should supply the conventional structure. oxidation (dic) - dictionary of effective oxidation states, e. g. {'Y':'Y3+', 'Ba':'Ba2+', 'Co':'Co2.25+', 'O':'O2-'} allows to calculate dipole moment surface_i (int) - choose particular surface min_slab_size (float) - minimum slab size min_vacuum_size (float) - vacuum thicknes in A """ from pymatgen.core.surface import SlabGenerator from pymatgen.io.vasp.inputs import Poscar from geo import replic pm = st.convert2pymatgen(oxidation=oxidation) # pm = st.convert2pymatgen() slabgen = SlabGenerator(pm, miller_index, min_slab_size, min_vacuum_size, primitive=primitive) # print(slabgen.oriented_unit_cell) slabs = slabgen.get_slabs(symmetrize=symmetrize) printlog( len(slabs), 'surfaces were generated, choose required surface using *surface_i* argument\nWriting POSCARs to xyz', imp='y') for i, slab in enumerate(slabs): pos = Poscar(slab) pos.write_file('xyz/POSCAR_suf' + str(i) + str(suf)) return slabs
def remove_half(st, el, sg=None): """ # works only for sg - required space group TODO 1. Take care about matching the initial cell and supercell from primitive Now the manual shift is done 2. Make full conversion from pymat structure to mine """ from pymatgen.symmetry.analyzer import SpacegroupAnalyzer from pymatgen.io.vasp.inputs import Poscar from calc_manage import smart_structure_read st_ohne_el = st.remove_atoms([el]) st_only_el = st.leave_only(el) st_mp = st_only_el.convert2pymatgen() sf = SpacegroupAnalyzer(st_mp) st_mp_prim = sf.find_primitive() # find primitive based only on element el #convert back to my format! please improve!!! p = Poscar(st_mp_prim) p.write_file('xyz/POSCAR') st_prim = smart_structure_read('xyz/POSCAR') sts = remove_half_based_on_symmetry(st_prim, sg) st_only_el_half = sts[ 0] # now only first configuration is taken, they could be different mul_matrix_float = np.dot(st.rprimd, np.linalg.inv(st_prim.rprimd)) mul_matrix = np.array(mul_matrix_float) mul_matrix = mul_matrix.round(0) mul_matrix = mul_matrix.astype(int) sc_only_el_half = create_supercell(st_only_el_half, mul_matrix=mul_matrix) sc_only_el_half = sc_only_el_half.shift_atoms([0.125, 0.125, 0.125]) sc_only_el_half = sc_only_el_half.return_atoms_to_cell() # st_only_el.write_poscar('xyz/POSCAR1') # sc_only_el_half.write_poscar('xyz/POSCAR2') st_half = st_ohne_el.add_atoms(sc_only_el_half.xcart, el) st_half.name += '_half' + str(sg) return st_half
def write_deformed_poscars(deformed_structures, directory=None): if not directory: directory = "." directory = Path(directory) n_deformations = len(deformed_structures) n_digits = int(np.floor(np.log10(n_deformations)) + 2) for i, deformed_structure in enumerate(deformed_structures): # pad with leading zeros so the files are sorted correctly filename = "POSCAR-{0:0{1}}".format(i + 1, n_digits) deform_poscar = Poscar(deformed_structure) deform_poscar.write_file(directory / filename, significant_figures=16)
def edit_dft_input_positions(output_name: str, structure: Structure): """ Writes a VASP POSCAR file from structure with the name poscar . WARNING: Destructively replaces the file with the name specified by poscar :param poscar: Name of file :param structure: structure to write to file """ if os.path.isfile(output_name): shutil.copyfile(output_name, output_name + ".bak") poscar = Poscar(structure.to_pmg_structure()) poscar.write_file(output_name) return output_name
def get_poscar(self, material_id, fpos): """ Args: material_id (str) - MP ID fpos (str) - where to write POSCAR Returns: Poscar object (also writes POSCAR) """ structure = self.rester.get_structure_by_material_id(material_id) poscar = Poscar(structure) poscar.write_file(fpos) return poscar
def place_files(self, structure, source_uuid=None, metadata=None): """place files Parameters ---------- structure: pymatgen.structure material structure source_uuid : string uuid file metadata: dic metadata to add Returns ------- boolean: True if created False if not created """ super_place_files = super().place_files() if super_place_files: targetdir = self.get_currentdir() if source_uuid is not None: dic = {"source_uuid": source_uuid} else: dic = {} if metadata is not None: dic.update(metadata) kind = self.structurefile_kind dic.update({"kind": kind}) if kind == "cif": # as cif file ciffilename = self.cif_filename dic.update({"positionfile": ciffilename}) cifpath = os.path.join(targetdir, ciffilename) cifwriter = CifWriter(structure) cifwriter.write_file(cifpath) else: # as POSCAR poscarfilename = "POSCAR" dic.update({"positionfile": poscarfilename}) poscarpath = os.path.join(targetdir, poscarfilename) poscar = Poscar(structure) poscar.write_file(poscarpath) species = element_list(structure.species) dic.update({"species": species, "nspecies": len(species)}) self.save_currentdir_metadata(dic) return True else: return False
def plot_images(self, outfile): """ Generates a POSCAR with the calculated diffusion path with respect to the first endpoint. :param outfile: Output file for the POSCAR """ sum_struct = self.__images[0].sites for image in self.__images: for site_i in self.__relax_sites: sum_struct.append(PeriodicSite(image.sites[site_i].specie, image.sites[site_i].frac_coords, self.__images[0].lattice, to_unit_cell=True, coords_are_cartesian=False)) sum_struct = Structure.from_sites(sum_struct, validate_proximity=False) p = Poscar(sum_struct) p.write_file(outfile)
def gen_unitcell_2d(path_poscar,vacuum,zaxis='c',from_bulk=False,slabmin=None,slabmax=None): """ Generate 2D unitcell. Parameters ---------- path_poscar (str): path to unitcell POSCAR vacuum (int): vacuum spacing in Angstroms [optional] zaxis (str): axis perpendicular to layer: a/b/c(default) [optional] from_bulk (bool): extract layer from bulk? Default=False. [optional] slabmin (float): fractional coord of the bottom of the layer to isolate [optional] slabmax (float): fractional coord of the top of the layer to isolate """ ## get current working directory ## subdirectories for different vacuum spacings will be created here dir_main = os.getcwd() poscar = Poscar.from_file(path_poscar, check_for_POTCAR=False) struct = align_axis(poscar.structure,axis=zaxis) if from_bulk: if slabmin == None or slabmax == None: raise ValueError('missing slabmin and/or slabmax argument') else: if slabmin > slabmax: raise ValueError('incorrect slabmin and/or slabmax argument') else: struct = layer_from_bulk(struct,slabmin,slabmax) slab_d = get_slab_thickness(struct) struct = add_vacuum(struct, vacuum - (struct.lattice.c - slab_d)) struct = center_slab(struct) dir_sub = os.path.join(dir_main,"vac_%d"%vacuum) if not os.path.exists(dir_sub): os.makedirs(dir_sub) Poscar.write_file(Poscar(struct),os.path.join(dir_sub,"POSCAR"))
def save_structure(self, file_name="CONTCAR", vacant="V", occupied="O"): """ Save current occupation to an output file in VASP's POSCAR format. Relies on `pymatgen' for the file I/O. Arguments: file_name name of the output file vacant atomic species to be placed at vacant sites occupied atomic species to be placed at occupied sites Note: `vacant` and `occupied` are only used if the species are not explicitly defined when the Lattice instance is created. Note: Sites are grouped (sorted) by species, so the order of sites in the saved POSCAR file is likely different from the original input file. """ try: from pymatgen.core import Structure from pymatgen.io.vasp.inputs import Poscar except ImportError: sys.stderr.write("Writing POSCAR files requires `pymatgen`.\n") if len(self.species) == 0: species = [vacant for i in range(self._nsites)] for i in self._occupied: species[i] = occupied else: species = self.species[:] species = np.array(species) idx = np.argsort(species) struc = Structure(self._avec, species[idx], self._coo[idx]) poscar = Poscar(struc) poscar.write_file(file_name)
sizemults=sizemults, a1=a1, a2=a2, hkl=hkl, a1vect_uvw=a1vect_uvw, a2vect_uvw=a2vect_uvw) stru_fault = solid_solution_random( structure=stru_fault, elem_frac_site=hec_elems[0], elem_list=hec_elems) stru_fault.sort() selective_dynamics = poscar_fix_top_bottom(stru_fault) fault_sys_poscar = Poscar( structure=stru_fault, selective_dynamics=selective_dynamics) compo_name = cation + '-' + anion if math.isclose(a1, 0.0): dir = compo_name + '_' \ + '_'.join([''.join(map(str, hkl)), 'plane']) else: dir = compo_name + '_' \ + '_'.join([''.join(map(str, hkl)), 'plane', ''.join(map(str, a1vect_uvw))]) \ + '_' + format(a1, '.2f') if not os.path.isdir(dir): os.mkdir(dir) fault_sys_poscar.write_file(dir + '/POSCAR', )
from pymatgen.core import Structure from pymatgen.io.vasp.inputs import Poscar from mpinterfaces.interface import Interface if __name__ == '__main__': # input structure file: bulk fin = 'POSCAR.bulk' # output file name fout = 'POSCAR' hkl = [0, 0, 1] # hkl wrt the input structure min_thick = 15 # angstroms min_vac = 30 # angstroms # use ase to create an orthogonal slab bulk = Structure.from_file(fin) iface = Interface(bulk, hkl=hkl, min_thick=min_thick, min_vac=min_vac, primitive=False, from_ase=True) iface.create_interface() iface.sort() # set selective dynamics flags # 1 --> T and 0 --> F sd_flags = [[1, 1, 1] for i in iface.sites] iface_poscar = Poscar(iface, selective_dynamics=sd_flags) # write to file iface_poscar.write_file(fout)
f.writelines("lattice : %4.3f, %4.3f %4.3f\n" % (struc_ini.lattice.abc)) for idx, formula in enumerate(M2O3_list): createFolder('%02d_%s' % (idx + 1.0, formula)) struc_ini.replace(0, TM_list[idx]) struc_ini.replace(1, TM_list[idx]) struc_ini.replace(2, TM_list[idx]) struc_ini.replace(3, TM_list[idx]) # getting conventional unit cell sga = SpacegroupAnalyzer(struc_ini) conv_struc = sga.get_conventional_standard_structure() poscar = Poscar(conv_struc) poscar.write_file('%02d_%s/POSCAR' % (idx + 1.0, formula)) poscar_ase = read_vasp('%02d_%s/POSCAR' % (idx + 1.0, formula)) write_xsd('models/poscar_%02d_%s.xsd' % (idx + 1.0, formula), poscar_ase) for k in range(len(df)): if formula == df['pretty_formula'][k]: struc = df['structure'][k] sga = SpacegroupAnalyzer(struc) # print(idx+1.0," ",formula," ",len(sga.get_conventional_standard_structure())) if len(sga.get_conventional_standard_structure()) != 30: print('Error for conv. struc. of %s' % formula) f.writelines('Error for conv. struc. of %s\n' % formula)
translations= None, rotations=None, samples=20, lowest=5, ecut=energy) for i, iface in enumerate(interfaces): print ("Coloumb Energy") print (i, iface[0]) iface[1].to('poscar', 'POSCAR_interface'+str(iface[0])+'.vasp') iface_slab = iface[1].slab iface_slab.sort() #set selective dynamics flags as required true_site= [1, 1, 1] false_site= [0, 0, 0] sd_flag_iface= [] sd_flag_slab= [] #selective dynamics flags for the interface for i in iface.sites: sd_flag_iface.append(false_site) #selective dynamics flags for the bare slab for i in iface_slab.sites: sd_flag_slab.append(false_site) interface_poscar = Poscar(iface[1], selective_dynamics= sd_flag_iface) slab_poscar = Poscar(iface_slab, selective_dynamics= sd_flag_slab) #slab poscars without selective dynamics flag iface_slab.to('poscar', 'POSCAR_slab'+str(iface[0])+'.vasp') #poscars with selective dynamics flag interface_poscar.write_file("POSCAR_interface_with_sd"+str(iface[0])+'.vasp') slab_poscar.write_file("POSCAR_slab_with_sd"+str(iface[0])+'.vasp')
# creating Incar object incar = Incar(incar_dict) # writing INCAR in designated path incar.write_file(file_dir + 'INCAR') # POSCAR a = a_min + interval * i new_lattice = Lattice([[a, 0, 0], [0, a, 0], [0, 0, a]]) # creating new structure struct.lattice = new_lattice # new_struct_dict = struct.as_dict() # print(new_struct_dict['lattice']['a']) poscar = Poscar(struct) poscar.write_file(file_dir + 'POSCAR') # KPOINTS k = 6 kpoints = Kpoints.gamma_automatic(kpts=(k, k, k), shift=(0.0, 0.0, 0.0)) kpoints.write_file(file_dir + 'KPOINTS') # POTCAR copyfile('./POTCAR', file_dir + 'POTCAR') # job_vasp.sh # setting up job_vasp.sh script new_job_vasp_file = open(file_dir + 'job_vasp.sh', 'w')
import sys from pymatgen.core import Structure from pymatgen.io.vasp.inputs import Poscar from mpinterfaces.interface import Interface if __name__=='__main__': # input structure file: bulk fin = 'POSCAR.bulk' # output file name fout = 'POSCAR' hkl = [0,0,1] # hkl wrt the input structure min_thick = 15 # angstroms min_vac = 30 # angstroms #use ase to create an orthogonal slab bulk = Structure.from_file(fin) iface = Interface(bulk, hkl=hkl, min_thick=min_thick, min_vac=min_vac, primitive= False, from_ase = True) iface.create_interface() iface.sort() #set selective dynamics flags # 1 --> T and 0 --> F sd_flags = [[1,1,1] for i in iface.sites] iface_poscar = Poscar(iface, selective_dynamics= sd_flags) #write to file iface_poscar.write_file(fout)
def volume_workflow_is_converged(pwd, max_num_sub, min_num_vols, volume_tolerance): workflow_converged_list = [] E, V = [], [] minE = 100 for root, dirs, files in os.walk(pwd): for file in files: if file == 'POTCAR' and check_vasp_input(root) == True: if os.path.exists(os.path.join(root, 'vasprun.xml')): try: Vr = Vasprun(os.path.join(root, 'vasprun.xml')) fizzled = False except: fizzled = True workflow_converged_list.append(False) if fizzled == False: job = is_converged(root) if job == 'converged': workflow_converged_list.append(True) vol = Poscar.from_file(os.path.join( root, 'POSCAR')).structure.volume if Vr.final_energy < minE: minE = Vr.final_energy minV = vol minE_path = root minE_formula = str( Poscar.from_file( os.path.join(path, 'POSCAR')). structure.composition.reduced_formula) E.append(Vr.final_energy) V.append(vol) elif fizzled == True and get_incar_value( path, 'STAGE_NUMBER' ) == 0: #job is failing on initial relaxation num_sub = get_number_of_subs(root) if num_sub == max_num_sub: os.remove(os.path.join(root, 'POTCAR')) #job failed too many times.... just ignore this job for the remainder of the workflow else: workflow_converged_list.append(False) num_jobs = check_num_jobs_in_workflow(pwd) if num_jobs < min_num_vols and len(E) > 0: scale_around_min = [0.98, 1.02] for s in scale_around_min: write_path = os.path.join(pwd, minE_formula + str(s * minV)) os.mkdir(write_path) structure = Poscar.from_file(os.path.join(minE_path, 'POSCAR')).structure structure.scale_lattice(s * minV) Poscar.write_file(structure, os.path.join(write_path, 'POSCAR')) files_copy = [ 'backup/Init/INCAR', 'CONVERGENCE', 'KPOINTS', 'POTCAR' ] for fc in files_copy: copy_from_path = os.path.join(minE_path, fc) if os.path.exists(copy_from_path): copy(copy_from_path, write_path) remove_sys_incar(write_path) #create new jobs if False not in workflow_converged_list: if len(E) > min_num_vols - 1: volumes = V energies = E eos = EOS(eos_name='murnaghan') eos_fit = eos.fit(volumes, energies) eos_minV = eos_fit.v0 if abs(eos_minV - minV) < volume_tolerance: # ang^3 cutoff return True #eos_fit.plot() else: scale_around_min = [0.99, 1, 1.01] for s in scale_around_min: write_path = os.path.join(pwd, minE_formula + str(s * eos_minV)) os.mkdir(write_path) structure = Poscar.from_file( os.path.join(minE_path, 'POSCAR')).structure structure.scale_lattice(s * eos_minV) Poscar.write_file(structure, os.path.join(write_path, 'POSCAR')) files_copy = [ 'backup/Init/INCAR', 'CONVERGENCE', 'KPOINTS', 'POTCAR' ] for fc in files_copy: copy_from_path = os.path.join(minE_path, fc) if os.path.exists(copy_from_path): copy(copy_from_path, write_path) remove_sys_incar(write_path) return False else: return False
def write_all_structures(self): """ Write all of the structures relevant for the interface calculation to VASP POSCAR files. """ _poscar = Poscar(self.original_substrate_structure) _poscar.write_file('bulk_substrate_POSCAR') _poscar = Poscar(self.original_film_structure) _poscar.write_file('bulk_film_POSCAR') _poscar = Poscar(self.strained_substrate) _poscar.write_file('strained_substrate_POSCAR') _poscar = Poscar(self.strained_film) _poscar.write_file('strained_film_POSCAR') for i, interface in enumerate(self.modified_substrate_structures): _poscar = Poscar(interface) _poscar.write_file('slab_substrate_%d_POSCAR' % i) for i, interface in enumerate(self.modified_film_structures): _poscar = Poscar(interface) _poscar.write_file('slab_film_%d_POSCAR' % i) for i, interface in enumerate(self.film_structures): _poscar = Poscar(interface) _poscar.write_file('slab_unit_film_%d_POSCAR' % i) for label, interface in zip(self.interface_labels, self.interfaces): _poscar = Poscar(interface) _poscar.write_file('interface_%s_POSCAR' % label.replace("/", "-")) return
def write_poscar(work_dir, struct): file_path = os.path.join(work_dir) poscar = Poscar(struct) poscar.write_file(file_path)
translations=None, rotations=None, samples=20, lowest=5, ecut=energy) for i, iface in enumerate(interfaces): print("Coloumb Energy") print(i, iface[0]) iface[1].to('poscar', 'POSCAR_interface' + str(iface[0]) + '.vasp') iface_slab = iface[1].slab iface_slab.sort() # set selective dynamics flags as required true_site = [1, 1, 1] false_site = [0, 0, 0] sd_flag_iface = [] sd_flag_slab = [] # selective dynamics flags for the interface for i in iface.sites: sd_flag_iface.append(false_site) # selective dynamics flags for the bare slab for i in iface_slab.sites: sd_flag_slab.append(false_site) interface_poscar = Poscar(iface[1], selective_dynamics=sd_flag_iface) slab_poscar = Poscar(iface_slab, selective_dynamics=sd_flag_slab) # slab poscars without selective dynamics flag iface_slab.to('poscar', 'POSCAR_slab' + str(iface[0]) + '.vasp') # poscars with selective dynamics flag interface_poscar.write_file("POSCAR_interface_with_sd" + str(iface[0]) + '.vasp') slab_poscar.write_file("POSCAR_slab_with_sd" + str(iface[0]) + '.vasp')
hkl=[1, 1, 1], min_thick=10, min_vac=25, primitive=False, from_ase=True) # substrate_slab = slab_from_file([0,0,1], 'POSCAR_substrate') mat2d_slab = slab_from_file([0, 0, 1], 'POSCAR_2D') # get the in-plane lattice aligned slabs # substrate_slab.to(fmt='poscar', filename='POSCAR_substrate_slab.vasp') mat2d_slab.to(fmt='poscar', filename='POSCAR_mat2d_slab.vasp') # selective dynamics flag sd_flags = CalibrateSlab.set_sd_flags( interface=substrate_slab, n_layers=nlayers_substrate, top=True, bottom=False) poscar = Poscar(substrate_slab, selective_dynamics=sd_flags) poscar.write_file(filename='POSCAR_substrate_slab.vasp') # get aligned lattices substrate_slab_aligned, mat2d_slab_aligned = get_aligned_lattices( substrate_slab, mat2d_slab, max_area=400, max_mismatch=0.05, max_angle_diff=1, r1r2_tol=0.01) substrate_slab_aligned.to(fmt='poscar', filename='POSCAR_substrate_aligned.vasp') mat2d_slab_aligned.to(fmt='poscar', filename='POSCAR_mat2d_aligned.vasp') # merge substrate and mat2d in all possible ways hetero_interfaces = generate_all_configs(mat2d_slab_aligned, substrate_slab_aligned,
iface = Interface(strt, hkl=hkl, min_thick=min_thick, min_vac=min_vac, supercell=supercell, surface_coverage=0.01, ligand=hydrazine, displacement=displacement, adatom_on_lig='N', adsorb_on_species='Pb', primitive=False) iface.create_interface() iface.sort() # extract bare slab iface_slab = iface.slab iface_slab.sort() # set selective dynamics flags as required true_site = [1, 1, 1] false_site = [0, 0, 0] sd_flag_iface = [] sd_flag_slab = [] # selective dynamics flags for the interface for i in iface.sites: sd_flag_iface.append(false_site) # selective dynamics flags for the bare slab for i in iface_slab.sites: sd_flag_slab.append(false_site) interface_poscar = Poscar(iface, selective_dynamics=sd_flag_iface) slab_poscar = Poscar(iface_slab, selective_dynamics=sd_flag_slab) # poscars without selective dynamics flag iface.to('poscar', 'POSCAR_interface.vasp') iface_slab.to('poscar', 'POSCAR_slab.vasp') # poscars with selective dynamics flag interface_poscar.write_file("POSCAR_interface_with_sd.vasp") slab_poscar.write_file("POSCAR_slab_with_sd.vasp")
INCAR = Incar.from_file('INCAR') KPOINTS = Kpoints.from_file('KPOINTS') for idx, formula in enumerate(LTMO_list): file_path = '%02d_%s/' % (idx + 1.0, formula) createFolder(file_path) struc_ori = entries[0]['structure'] # PtO2 struc_ori.replace(0,TM_list[idx]) conv_struc = struc_ori poscar = Poscar(conv_struc) poscar.write_file(file_path + 'POSCAR') poscar_ase = read_vasp(file_path + 'POSCAR') write_xsd('models/poscar_%02d_%s.xsd' % (idx + 1.0, formula), poscar_ase) # view(poscar_ase) for k in range(len(entries)): if formula == entries[k]['pretty_formula']: struc = entries[k]['structure'] # getting conventional unit cell sga = SpacegroupAnalyzer(struc, symprec = 0.1) # print(idx," ",k," ",sga.get_conventional_standard_structure().formula)
surface_coverage=0.01, ligand=hydrazine, displacement=displacement, adatom_on_lig='N', adsorb_on_species='Pb', primitive=False) iface.create_interface() iface.sort() # extract bare slab iface_slab = iface.slab iface_slab.sort() # set selective dynamics flags as required true_site = [1, 1, 1] false_site = [0, 0, 0] sd_flag_iface = [] sd_flag_slab = [] # selective dynamics flags for the interface for i in iface.sites: sd_flag_iface.append(false_site) # selective dynamics flags for the bare slab for i in iface_slab.sites: sd_flag_slab.append(false_site) interface_poscar = Poscar(iface, selective_dynamics=sd_flag_iface) slab_poscar = Poscar(iface_slab, selective_dynamics=sd_flag_slab) # poscars without selective dynamics flag iface.to('poscar', 'POSCAR_interface.vasp') iface_slab.to('poscar', 'POSCAR_slab.vasp') # poscars with selective dynamics flag interface_poscar.write_file("POSCAR_interface_with_sd.vasp") slab_poscar.write_file("POSCAR_slab_with_sd.vasp")
if __name__ == '__main__': Gulp = GulpIO() num = int(sys.argv[1]) if num == 1: #write input file of gulp Cry_Str = Structure.from_file("POSCAR") with open('gulpinput', 'w') as f: f.write(Gulp.keyword_line('opti conj conp nosymmetry qok')) f.write(Gulp.keyword_line('switch_min bfgs gnorm 0.5\n')) gulpinput = Gulp.structure_lines(structure=Cry_Str, symm_flg=False) f.write(gulpinput) f.write(Gulp.keyword_line('maxcyc 500')) f.write(Gulp.keyword_line('library self_build.lib')) f.write(Gulp.keyword_line('dump every gulpopt')) if num == 2: #output the energy energy = gulp_average_energy() print energy if num == 3: #output the relaxed structure with zopen('log', "rt") as f: contents = f.read() Opt_Str = Gulp.get_relaxed_structure(contents) Vasp_Str = Poscar(Opt_Str) Vasp_Str.write_file('out.vasp')
def create_SNL(dirbase, molecules, atoms, spc_present, num_each_spc, struct, s): layers = len(molecules) with MPRester("sm5RbuEp83T9Wo7P") as m: first_mol = struct[0] mono_or_homo = 0 #if system is a monolayer or homogeneous use its proper .cif file, else use generic WTe2 for heterostructures if (layers == 1) or all(x == first_mol for x in struct): mono_or_homo = 1 if (first_mol == molec[0]): structure = m.get_structure_by_material_id("mp-2815") #MoS2 ref = m.get_materials_id_references("mp-2815") r1 = np.array([0, 2, 4]) elif (first_mol == molec[1]): structure = m.get_structure_by_material_id("mp-1634") #MoSe2 ref = m.get_materials_id_references("mp-1634") r1 = np.array([0, 2, 4]) elif (first_mol == molec[2]): structure = m.get_structure_by_material_id("mp-602") #MoTe2 ref = m.get_materials_id_references("mp-602") r1 = np.array([1, 2, 5]) elif (first_mol == molec[3]): structure = m.get_structure_by_material_id("mp-224") #WS2 ref = m.get_materials_id_references("mp-224") r1 = np.array([0, 3, 5]) elif (first_mol == molec[4]): structure = m.get_structure_by_material_id("mp-1821") #WSe2 ref = m.get_materials_id_references("mp-1821") r1 = np.array([0, 2, 4]) elif (first_mol == molec[5]): structure = m.get_structure_by_material_id("mp-1019322") #WTe2 ref = m.get_materials_id_references("mp-1019322") r1 = np.array([0, 3, 5]) else: structure = m.get_structure_by_material_id("mp-1019322") #WTe2 ref = m.get_materials_id_references("mp-1019322") r1 = np.array([0, 3, 5]) # initialize history history = [] #half the height of original unit cell...to be used for vacuum length calculation later halfz = (structure.lattice.c) / 2 #make supercell if necessary levels = layers if (levels % 2 == 1): levels = levels + 1 tsuper = SupercellTransformation([[1, 0, 0], [0, 1, 0], [0, 0, (levels) / 2]]) history.append(history_node(tsuper)) supercell = tsuper.apply_transformation(structure) #make species replacements for heterostructures with more than one layer levels = layers if (levels % 2 == 1): levels = levels + 1 #if heterostructure has more than one layer: if (mono_or_homo == 0): for i in range(0, len(molecules)): if (molecules[i] == 5): continue else: TMspc = elems[atoms[2 * i]] TMloc = (levels * 2) + (i % 2) * (levels / 2) + int( np.floor((i) / 2)) DCspc = elems[atoms[2 * i + 1]] DCloc1 = (levels - (levels / 2)) - i % 2 * (levels / 2) + int( np.floor((i) / 2)) DCloc2 = levels + i % 2 * (levels / 2) + int( np.floor((i) / 2)) t1 = ReplaceSiteSpeciesTransformation({TMloc: TMspc}) t2 = ReplaceSiteSpeciesTransformation({DCloc1: DCspc}) t3 = ReplaceSiteSpeciesTransformation({DCloc2: DCspc}) history.append(history_node(t1)) history.append(history_node(t2)) history.append(history_node(t3)) supercell = t1.apply_transformation(supercell) supercell = t2.apply_transformation(supercell) supercell = t3.apply_transformation(supercell) #remove top layer of atom if necessary mult_factor = (layers + 1) / 2 - 1 r = r1 + (r1 + 1) * mult_factor tremove = RemoveSitesTransformation(r) if (layers % 2 == 1): supercell = tremove.apply_transformation(supercell) history.append(history_node(tremove)) #sort structure supercell = supercell.get_sorted_structure() #extend z-axis cell vector to add vaccuum to supercell vacuum = 10.0 old_lattice = supercell.lattice if (layers % 2 == 1): new_c = old_lattice.c - halfz + vacuum else: new_c = old_lattice.c + vacuum new_lattice = Lattice.from_parameters(old_lattice.a, old_lattice.b, new_c, old_lattice.alpha, old_lattice.beta, old_lattice.gamma) final_structure = Structure( new_lattice, supercell.species, supercell.frac_coords * np.array([1., 1., (old_lattice.c / new_lattice.c)]), coords_are_cartesian=False) hnode = { 'name': 'add vaccuum', 'url': '', 'description': 'increase z-direction cell vector by 10 angstroms' } history.append(hnode) #creat final SNL authors = [{"name": "Lindsay Bassman", "email": "*****@*****.**"}] projects = ["TMDC-Heterostructures"] remarks = [ "MAGICS calculation of band structures of 2D TMDC stacked heterostructures" ] final_snl = StructureNL(final_structure, authors, projects=projects, remarks=remarks, references=ref, history=history) #optionally write POSCAR file poscar = Poscar(final_structure, s) poscar.write_file(dirbase + "POSCAR", direct=False)
defect_site=defect_site) if initdef[d]["type"][0] == "i" or initdef[d]["type"][0] == "a": ## interstitial/adatom type defect defect.add_defect_info(defect_type=initdef[d]["type"] + "_" + initdef[d]["species_new"], defect_site=defect_site) ## create vacancy defect(s) defect.remove_atom() ## create substitutional defect(s) defect.replace_atom() ## create interstitial defect(s) defect.add_atom() ## write POSCAR Poscar.write_file(Poscar(defect.structure.get_sorted_structure()), os.path.join(dir_sub, "POSCAR")) ## write bulkref POSCAR if args.write_bulkref: if args.q == 0: if not os.path.exists(os.path.join(dir_sub, "bulkref")): os.makedirs(os.path.join(dir_sub, "bulkref")) Poscar.write_file(Poscar(structure_bulk), os.path.join(dir_sub, "bulkref", "POSCAR")) ## write json file with open(os.path.join(dir_sub, "defectproperty.json"), 'w') as file: file.write(json.dumps(defect.as_dict(), indent=4)) # use `json.loads` to do the reverse ## BULK
min_thick=10, min_vac=25, primitive=False, from_ase=True) #substrate_slab = slab_from_file([0,0,1], 'POSCAR_substrate') mat2d_slab = slab_from_file([0, 0, 1], 'POSCAR_2D') # get the in-plane lattice aligned slabs #substrate_slab.to(fmt='poscar', filename='POSCAR_substrate_slab.vasp') mat2d_slab.to(fmt='poscar', filename='POSCAR_mat2d_slab.vasp') # selective dynamics flag sd_flags = CalibrateSlab.set_sd_flags(interface=substrate_slab, n_layers=nlayers_substrate, top=True, bottom=False) poscar = Poscar(substrate_slab, selective_dynamics=sd_flags) poscar.write_file(filename='POSCAR_substrate_slab.vasp') # get aligned lattices substrate_slab_aligned, mat2d_slab_aligned = get_aligned_lattices( substrate_slab, mat2d_slab, max_area=400, max_mismatch=0.05, max_angle_diff=1, r1r2_tol=0.01) substrate_slab_aligned.to(fmt='poscar', filename='POSCAR_substrate_aligned.vasp') mat2d_slab_aligned.to(fmt='poscar', filename='POSCAR_mat2d_aligned.vasp') # merge substrate and mat2d in all possible ways hetero_interfaces = generate_all_configs(mat2d_slab_aligned, substrate_slab_aligned, nlayers_2d, nlayers_substrate, seperation)
def generate(dir_def_main, initdef_file, q, supercell, vacuum, bulkref=False): """ Generate defect supercell. Parameters ---------- dir_def_main (str): path to main defect directory containing unitcell POSCARs initdef_file (str): json file with details to initialize defect q (int): charge supercell (tuple of ints): supercell size as [n1,n2,n3] vacuum (int): vacuum spacing [optional] bulkref (bool): generate only bulk reference supercell? Default=False. """ ## the directory from which this function was called ## should already be the appropriate charge/cell/vacuum subdirectory subdir_def = os.getcwd() ## read in corresponding unit cell POSCAR pos_file = os.path.join(dir_def_main, "POSCAR_vac_%d" % vacuum) if not os.path.exists(pos_file): raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), pos_file) poscar = Poscar.from_file(pos_file, check_for_POTCAR=False, read_velocities=False) ## make undefected supercell structure = poscar.structure.copy() structure.make_supercell(supercell) structure_bulk = structure.copy() if bulkref: ## write bulkref POSCAR Poscar.write_file(Poscar(structure_bulk), os.path.join(subdir_def, "POSCAR")) else: ## read in defect details from initdefect json file id_file = os.path.join(dir_def_main, initdef_file) if not os.path.exists(id_file): raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), id_file) with open(id_file, 'r') as file: initdef = json.loads(file.read()) ## initialize defect object defect = Defect(structure_bulk, structure.copy(), supercell, vacuum, q) ## generate defect supercell defect.generate_supercell(initdef) ## write defect POSCAR Poscar.write_file(Poscar(defect.structure.get_sorted_structure()), os.path.join(subdir_def, "POSCAR")) ## write defectproperty.json file (summary of defect created in this supercell) with open(os.path.join(subdir_def, "defectproperty.json"), 'w') as file: file.write(json.dumps(defect.as_dict(), indent=4))
def main_alloy(): """ Run alloy FFs job """ for file in glob.glob("*.alloy"): try: folder1 = str(os.getcwd()) + str("/") + str(file) + str("_nist") if not os.path.exists(folder1): os.makedirs(str(folder1)) cwd1 = str(os.getcwd()) print("folder1=", folder1) ff = str(file) element_ff = [] f = open(ff, "r") os.chdir(str(folder1)) list_el = [] lines = f.readlines() content = (lines[3]).split(" ") # content=(lines[3]).split("' '|\n|\r\n") for val in content: if val != "" and val != "\n" and val != "\r\n": list_el.append(val) for i in range(0, len(list_el)): if i != 0: element_ff.append(list_el[i]) # print ff,' ',element_ff with MPRester(MAPI_KEY) as m: data = m.get_entries_in_chemsys( element_ff, inc_structure="final", property_data=[ "unit_cell_formula", "material_id", "icsd_id", "spacegroup", "energy_per_atom", "formation_energy_per_atom", "pretty_formula", "band_gap", "total_magnetization", "e_above_hull", ], ) if len(element_ff) > 1: try: entries = m.get_entries_in_chemsys(element_ff) pd = PhaseDiagram(entries) plotter = PDPlotter(pd, show_unstable=True) image = str(ff) + str("_DFT") + str(".jpg") plotter.write_image(image) except: pass structures = [] structures_cvn = [] icsd_arr = [] mp_arr = [] sg_arr = [] enp_arr = [] fenp_arr = [] pf_arr = [] ucf_arr = [] bg_arr = [] tm_arr = [] ehull_arr = [] for d in data: x = d.data["material_id"] sg = d.data["spacegroup"] enp = d.data["energy_per_atom"] fenp = d.data["formation_energy_per_atom"] pf = d.data["pretty_formula"] ucf = d.data["unit_cell_formula"] bg = d.data["band_gap"] tm = d.data["total_magnetization"] ehull = d.data["e_above_hull"] icsd = d.data["icsd_id"] structure = m.get_structure_by_material_id(x) structures.append(structure) icsd_arr.append(icsd) mp_arr.append(x) sg_arr.append(sg) enp_arr.append(enp) fenp_arr.append(fenp) pf_arr.append(pf) bg_arr.append(bg) tm_arr.append(tm) ucf_arr.append(ucf) ehull_arr.append(ehull) comment = str("bulk@") + str(x) folder2 = str(os.getcwd()) + str("/") + str(comment) + str("_fold") if not os.path.exists(folder2): os.makedirs(str(folder2)) print("folder2=", folder2) cwd2 = str(os.getcwd()) os.chdir(str(folder2)) p = Poscar(structure) p.comment = comment p.write_file("POSCAR") poscar_file = str(os.getcwd()) + str("/POSCAR") pair_coeff = str(cwd1) + str("/") + str(file) # pair_coeff=str('/data/knc6/JARVIS-FF-NEW/ALLOY')+str("/")+str(file) parameters = { "pair_style": "eam/alloy", "exec": lammps_exec, "pair_coeff": pair_coeff, "atom_style": "charge", "control_file": input_box, } main_file = open("setup.py", "w") line = str("from jlammps import main_func") + "\n" main_file.write(line) line = str("from pymatgen.io.vasp.inputs import Poscar") + "\n" main_file.write(line) # line=str("try:")+'\n' # main_file.write(line) line = ( str("p=Poscar.from_file(") + str('"') + str(poscar_file) + str('"') + str(")") + "\n" ) main_file.write(line) line = ( str("main_func(mat=p") + str(",") + str("parameters=") + str(parameters) + str(")") + "\n" ) main_file.write(line) # line=str("except:")+'\n' # main_file.write(line) # line=str(" pass")+'\n' # main_file.write(line) main_file.close() # try: # p=Poscar.from_file(poscar_file) # main_func(mat=p,parameters=parameters) # except: # pass os.chdir(cwd2) # =str(os.getcwd()) os.chdir(cwd1) # =str(os.getcwd()) except: pass
def abinit_to_phonopy(anaddbnc, supercell_matrix, symmetrize_tensors=False, output_dir_path=None, prefix_outfiles="", symprec=1e-5, set_masses=False): """ Converts the interatomic force constants(IFC), born effective charges(BEC) and dielectric tensor obtained from anaddb to the phonopy format. Optionally writes the standard phonopy files to a selected directory: FORCE_CONSTANTS, BORN (if BECs are available) POSCAR of the unit cell, POSCAR of the supercell. The conversion is performed taking the IFC in the Wigner–Seitz supercell with weights as produced by anaddb and reorganizes them in a standard supercell multiple of the unit cell. Operations are vectorized using numpy. This may lead to the allocation of large arrays in case of very large supercells. Performs a check to verify if the two codes identify the same symmetries and it gives a warning in case of failure. Mismatching symmetries may lead to incorrect conversions. Args: anaddbnc: an instance of AnaddbNcFile. Should contain the output of the IFC analysis, the BEC and the dielectric tensor. supercell_matrix: the supercell matrix used for phonopy. Any choice is acceptable, however the best agreement between the abinit and phonopy results is obtained if this is set to a diagonal matrix with on the diagonal the ngqpt used to generate the anaddb.nc. symmetrize_tensors: if True the tensors will be symmetrized in the Phonopy object and in the output files. This will apply to IFC, BEC and dielectric tensor. output_dir_path: a path to a directory where the phonopy files will be created prefix_outfiles: a string that will be added as a prefix to the name of the written files symprec: distance tolerance in Cartesian coordinates to find crystal symmetry in phonopy. It might be that the value should be tuned so that it leads to the the same symmetries as in the abinit calculation. set_masses: if True the atomic masses used by abinit will be added to the PhonopyAtoms and will be present in the returned Phonopy object. This should improve compatibility among abinit and phonopy results if frequencies needs to be calculated. Returns: An instance of a Phonopy object that contains the IFC, BEC and dieletric tensor data. """ ifc = anaddbnc.ifc nac_params = None becs = None epsinf = None if anaddbnc.becs is not None and anaddbnc.epsinf is not None: becs = anaddbnc.becs.values epsinf = anaddbnc.epsinf # according to the phonopy website 14.399652 is not the coefficient for abinit # probably it relies on the other conventions in the output. nac_params = {"born": becs, "dielectric": epsinf, "factor": 14.399652} s = anaddbnc.structure phon_at = get_phonopy_structure(s) if set_masses: phon_at.masses = [anaddbnc.amu[n] for n in phon_at.numbers] # use phonopy to get the proper supercell given by the primitive and the matrix # and convert it to pymatgen phonon = Phonopy(phon_at, supercell_matrix, primitive_matrix=np.eye(3), nac_params=nac_params, symprec=symprec) phon_supercell = phonon.get_supercell() supercell = get_pmg_structure(phon_supercell) abi_hall_num = s.abi_spacegroup.get_spglib_hall_number() spglib_hall_num = phonon.symmetry.dataset["hall_number"] if abi_hall_num != spglib_hall_num: warnings.warn( "The hall number obtained based on the DDB symmetries differs " f"from the one calculated with spglib: {abi_hall_num} versus " f"{spglib_hall_num}. The conversion may be incorrect. Try changing symprec." ) # convert to phonopy units at_cart = ifc.atoms_cart_coord * abu.Bohr_Ang ifccc = ifc.ifc_cart_coord * abu.Ha_eV / abu.Bohr_Ang**2 weights = ifc.ifc_weights latt = supercell.lattice ifcph = np.zeros((len(s), len(supercell), 3, 3)) # loop over the atoms in the primitive cell # other operations are vectorized using numpy arrays. Some array may require large allocations for i, (site, c_list, w_list) in enumerate(zip(s, at_cart, weights)): ind_w = np.where(w_list > 0) ifccc_loc = ifccc[i, ind_w[0]] w_list = w_list[ind_w] c_list = c_list[ind_w] # align the coordinates of the first atom in the list (the site under consideration) # with the site in the primitive cell. c_list = c_list - c_list[0] + site.coords # convert to fractional coordinates as needed by the Lattice to get the distances f_list = latt.get_fractional_coords(c_list) sc_fcoords = supercell.frac_coords # construct the list of sites of the supercell that are closer to sites in # the primitive cell dist_and_img = [ latt.get_distance_and_image(f_list[0], fc) for fc in sc_fcoords ] # the function gives the translation of the image, but it should be applied to the coordinates. # Only the positions are needed nearest_sc_fcoords = [ fc + trasl for (_, trasl), fc in zip(dist_and_img, sc_fcoords) ] # divide by the corresponding weights. Elements with weights 0 were discarded above ifccc_loc = np.transpose(ifccc_loc, (0, 2, 1)) / w_list[:, None, None] # create an array with all the possible pairs # instantiating this array seems slow but seems still faster than the required loops coord_pairs = np.array( list(itertools.product(nearest_sc_fcoords, f_list))) # find the pairs that match between the coordinates of the modified supercell and the f_list ind_match = np.where( np.abs(coord_pairs[:, 0] - coord_pairs[:, 1]).sum(axis=1) < 1e-6)[0] # set the ifc for phonopy in the final array corresponding to the matching indices. n_points_f_list = len(f_list) ifcph[i, ind_match // n_points_f_list] = ifccc_loc[ind_match % n_points_f_list] phonon.set_force_constants(ifcph) if symmetrize_tensors: phonon.symmetrize_force_constants() if output_dir_path: makedirs_p(output_dir_path) fc_filepath = os.path.join(output_dir_path, prefix_outfiles + "FORCE_CONSTANTS") write_FORCE_CONSTANTS(phonon.get_force_constants(), fc_filepath) if becs is not None and epsinf is not None: born_filepath = os.path.join(output_dir_path, prefix_outfiles + "BORN") write_BORN(phon_at, borns=becs, epsilon=epsinf, filename=born_filepath, symmetrize_tensors=symmetrize_tensors) poscar_filepath = os.path.join(output_dir_path, prefix_outfiles + "POSCAR") poscar = Poscar(s) poscar.write_file(poscar_filepath, significant_figures=15) supercell_filepath = os.path.join(output_dir_path, prefix_outfiles + "supercell_POSCAR") superce_poscar = Poscar(supercell) superce_poscar.write_file(supercell_filepath, significant_figures=15) return phonon
tm_arr.append(tm) ucf_arr.append(ucf) ehull_arr.append(ehull) comment = str("bulk@") + str(x) folder2 = str( os.getcwd()) + str("/") + str(comment) + str("_fold") if not os.path.exists(folder2): os.makedirs(str(folder2)) print("folder2=", folder2) cwd2 = str(os.getcwd()) os.chdir(str(folder2)) p = Poscar(structure) p.comment = comment p.write_file("POSCAR") poscar_file = str(os.getcwd()) + str("/POSCAR") pair_coeff = str(cwd1) + str("/") + str(file) # pair_coeff=str('/data/knc6/JARVIS-FF-NEW/ALLOY')+str("/")+str(file) parameters = { "pair_style": "eam/fs", "pair_coeff": pair_coeff, "atom_style": "charge", "control_file": "/users/knc6/inelast.mod", } main_file = open("setup.py", "w") line = str("from NEW_LAMMPS10 import main_func") + "\n" main_file.write(line) line = str( "from pymatgen.io.vasp.inputs import Poscar") + "\n"
for j in range(len(sym_point)): if sym_point[j] == 0: bnds += (structure.frac_coords[i][j], structure.frac_coords[i][j]), else: bnds += ((-1*max_fractional_displacement)+structure.frac_coords[i][j],\ max_fractional_displacement+structure.frac_coords[i][j]), '''Print space goup number. This should be in the output file''' print("The space group of the structure is {}".format(space_group)) '''Flatten fractional coordinates of intial (input) structure to vector. Vectors are the standard format that the minimizer can understand. ''' x0 = structure.frac_coords.flatten() '''Now the actual mimimizer is "Sequential Least SQuares Programming optimization" (SLSQP) algorithm. This method allows us to simply use constraints and bounds. I tried other methods including Limited-memory Broyden-Fletcher-Goldfarb-Shanno algorithm but they tend to be unstable. More testing may be needed if other algorithms are to be used''' res = minimize(minime, x0, args=myargs, method='SLSQP', bounds=bnds, options={'disp': True}) '''Outputs: These should be written to file''' #output ion coordinates after minimization must be reshaped relaxed_coordinates = res.x.reshape(num_atoms, 3) '''output relaxed structure as POSCAR type file''' out_structure = Structure(lattice, Species_list, relaxed_coordinates) w = Poscar(out_structure) w.write_file("out_ErNiO3_ions-l-b.vasp") print(time.time() - start_time)