def write_structure(structure, filename): """ Write a structure to a file based on file extension. For example, anything ending in a "cif" is assumed to be a Crystallographic Information Format file. Supported formats include CIF, POSCAR, CSSR and pymatgen's JSON serialized structures. Args: structure (Structure/IStructure): Structure to write filename (str): A filename to write to. """ fname = os.path.basename(filename) if fnmatch(fname, "*.cif*"): writer = CifWriter(structure) elif fnmatch(fname, "POSCAR*") or fnmatch(fname, "CONTCAR*"): writer = Poscar(structure) elif fnmatch(fname.lower(), "*.cssr*"): writer = Cssr(structure) elif fnmatch(fname, "*.json*") or fnmatch(fname, "*.mson*"): with zopen(filename, "wt") as f: f.write(str2unicode(json.dumps(structure, cls=MontyEncoder))) return else: raise ValueError("Unrecognized file extension!") writer.write_file(filename)
def write_structure(structure, filename): """ Write a structure to a file based on file extension. For example, anything ending in a "cif" is assumed to be a Crystallographic Information Format file. Supported formats include CIF, POSCAR, CSSR and pymatgen's JSON serialized structures. Args: structure (Structure/IStructure): Structure to write filename (str): A filename to write to. """ fname = os.path.basename(filename) if fnmatch(fname, "*.cif*"): writer = CifWriter(structure) elif fnmatch(fname, "POSCAR*") or fnmatch(fname, "CONTCAR*"): writer = Poscar(structure) elif fnmatch(fname.lower(), "*.cssr*"): writer = Cssr(structure) elif fnmatch(fname, "*.json*") or fnmatch(fname, "*.mson*"): with zopen(filename, "wt") as f: f.write(str2unicode(json.dumps(structure, cls=MontyEncoder))) return else: raise ValueError("Unrecognized file extension!") writer.write_file(filename)
def write_symmetry_cifs(self, properties): ''' Computes symmetry of structure using Pymatgen Then writes cit to out_folder ''' count = 1 for struct, en, ID in properties: # identify space group structp = struct.get_pymatgen_structure() sg = SGA(structp, symprec=self.symprec).get_space_group_number() # Pymatgen CIFwriter cw = CifWriter(structp, symprec=self.symprec) # Name output cif file if count < 10: count = "0" + str(count) # makes, e.g. 1 be 01 if not isdir(self.out_folder): mkdir(self.out_folder) name = join(self.out_folder, str(count) + "_" + str(ID) + "_" + str(sg) + ".cif") cw.write_file(name) # Increment count count = int(count) count += 1 print("Done with struct %s" % (ID))
def in_struc(fin, tolerance=0.001): natot = get_natot(fin) lines_cell = extract_cell_parameters(fin) lines_atom = extract_atomic_positions(fin, natot) structure = from_lines(lines_cell, lines_atom) # pymatgen format structure.to(fmt='poscar', filename='in_struc.vasp') cif = CifWriter(structure, symprec=tolerance) cif.write_file('in_struc.cif')
def cif(src): """ cifファイルを作成 """ srcpos = Poscar.from_file(src) finder = SpacegroupAnalyzer(srcpos.structure) std_str = finder.get_conventional_standard_structure() std_cif = CifWriter(std_str, symprec=0.1) std_cif.write_file("poscar.cif")
def cif(src='POSCAR'): """ cifファイルを作成 """ srcpos = Poscar.from_file(src) finder = SpacegroupAnalyzer(srcpos.structure) std_str = finder.get_conventional_standard_structure() cif_obj = CifWriter(std_str, symprec=0.1) cif_obj.write_file('poscar.cif')
def get_cif(filename, tolerance=0.1): if filename[-5:] == '.vasp': with open(filename, 'r') as f: struc_str = f.read() struc = Structure.from_str(struc_str, fmt='poscar') else: struc = Structure.from_file(filename) cif = CifWriter(struc, symprec=tolerance) cif.write_file(filename + '.cif')
def prim_cif(self, dst): """ primitive cellでのcifフォーマットをgetする """ finder = SpacegroupAnalyzer(self.structure) structure = finder.get_primitive_standard_structure() structure = finder.get_conventional_standard_structure() cif = CifWriter(structure, symprec=0.1) cif.write_file(dst)
def write_cif_input(self): cif_writer = CifWriter(struct=self.input_structure, symprec=None, write_magmoms=True, significant_figures=8, angle_tolerance=5.0, refine_struct=True) cif_writer.write_file(self.input_filename_cif)
def out_struc(fin, fout, tolerance=0.1): natot = get_natot(fin) lines_cell = extract_cell_parameters(fout) if lines_cell is None: # 'relax' --> no CELL_PARAMETERS lines_cell = extract_cell_parameters(fin) # get from input lines_atom = extract_atomic_positions(fout, natot) structure = from_lines(lines_cell, lines_atom) # pymatgen format structure.to(fmt='poscar', filename='out_struc.vasp') cif = CifWriter(structure, symprec=tolerance) cif.write_file('out_struc.cif')
def predict_structure(species, struc_list, check_dir=False, threshold=0.00001): """ Predicted structures for set of pymatgen species using the Pymatgen structure predictor and save as cif file. TODO: This will be superceded by our own implementation of the structure prediction algorithm in future versions of SMACT. Args: species (list): Pymatgen Species for which structure should be predicted. struc_list (list): Pymatgen Structure objects to consider as parent structures in the substitution algorithm. check_dir (bool): check if directory already exists and only carry out prediction and write new files if it doesn't. threshold (float): Log-probability threshold for the Pymatgen structure predictor. Returns: Saves cif files of possible structures in new directory along with a summary .txt file containing info including probabilities. """ sub = Substitutor(threshold=0.00001) print('{} ........'.format(species)) dirname = ''.join([str(i) for i in species]) path_exists = True if os.path.exists( './SP_results/{0}'.format(dirname)) else False if (check_dir and path_exists): print('Already exists') else: print('{} not already there'.format(dirname)) suggested_strucs = sub.pred_from_structures(target_species=species, structures_list=struc_list, remove_existing=False, remove_duplicates=True) suggested_strucs = sorted(suggested_strucs, key=lambda k: k.other_parameters['proba'], reverse=True) # Save the structures as cifs if not path_exists: os.makedirs('./SP_results/{0}'.format(dirname)) for i, d in enumerate(suggested_strucs): cw = CifWriter(d.final_structure) cw.write_file("SP_results/{0}/{1}_BasedOn_{2}.cif".format( dirname, i, d.history[0]['source'])) # Save the summary as a text file with open('SP_results/{0}/{0}_summary.txt'.format(dirname), 'w') as f: f.write('Formula, Probability, Based on, Substitutions \n') for i, struc in enumerate(suggested_strucs): f.write( ' {0}, {1:12}, {2:.5f}, {3:9}, {4} \n'.format( i, struc.composition.reduced_formula, struc.other_parameters['proba'], struc.history[0]['source'], re.sub('Specie', '', str(struc.history[1]['species_map'])))) print('Done.')
def struct2ase(struct): """ convert pymatgen sructure to ASE structure """ from ase.io import read from pymatgen.io.cif import CifWriter w = CifWriter(struct) w.write_file("temp.cif") structure = read("temp.cif",format="cif") subprocess.call(["rm", "temp.cif"]) return structure
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 convert_fmt(args): iformat = args.input_format[0] oformat = args.output_format[0] filename = args.input_filename[0] out_filename = args.output_filename[0] try: if iformat == "POSCAR": p = Poscar.from_file(filename) structure = p.structure elif iformat == "CIF": r = CifParser(filename) structure = r.get_structures()[0] elif iformat == "CONVENTIONAL_CIF": r = CifParser(filename) structure = r.get_structures(primitive=False)[0] elif iformat == "CSSR": structure = Cssr.from_file(filename).structure else: structure = Structure.from_file(filename) if oformat == "smart": structure.to(filename=out_filename) elif oformat == "POSCAR": p = Poscar(structure) p.write_file(out_filename) elif oformat == "CIF": w = CifWriter(structure) w.write_file(out_filename) elif oformat == "CSSR": c = Cssr(structure) c.write_file(out_filename) elif oformat == "VASP": ts = TransformedStructure( structure, [], history=[{"source": "file", "datetime": str(datetime.datetime.now()), "original_file": open(filename).read()}]) ts.write_vasp_input(MPRelaxSet, output_dir=out_filename) elif oformat == "MITVASP": ts = TransformedStructure( structure, [], history=[{"source": "file", "datetime": str(datetime.datetime.now()), "original_file": open(filename).read()}]) ts.write_vasp_input(MITRelaxSet, output_dir=out_filename) except Exception as ex: print("Error converting file. Are they in the right format?") print(str(ex))
def predict_structure(species, struc_list, check_dir=False): """ Save cif files of predicted structures for set of pymatgen species. Args: species (list): pymatgen species to predict structures for struc_list (list): pymatgen structures to substitute species into check_dir (bool): check if directory already exists and only carry out prediction if it doesn't. """ sub = Substitutor(threshold=0.00001) print('{} ........'.format(species)) dirname = ''.join([str(i) for i in species]) path_exists = True if os.path.exists( './SP_results/{0}'.format(dirname)) else False if (check_dir and path_exists): print('Already exists') else: print('{} not already there'.format(dirname)) suggested_strucs = sub.pred_from_structures(target_species=species, structures_list=struc_list, remove_existing=False, remove_duplicates=True) suggested_strucs = sorted(suggested_strucs, key=lambda k: k.other_parameters['proba'], reverse=True) # Save the structures as cifs if not path_exists: os.makedirs('./SP_results/{0}'.format(dirname)) for i, d in enumerate(suggested_strucs): cw = CifWriter(d.final_structure) cw.write_file("SP_results/{0}/{1}_BasedOn_{2}.cif".format( dirname, i, d.history[0]['source'])) # Save the summary as a text file with open('SP_results/{0}/{0}_summary.txt'.format(dirname), 'w') as f: f.write('Formula, Probability, Based on, Substitutions \n') for i, struc in enumerate(suggested_strucs): f.write( ' {0}, {1:12}, {2:.5f}, {3:9}, {4} \n'.format( i, struc.composition.reduced_formula, struc.other_parameters['proba'], struc.history[0]['source'], re.sub('Specie', '', str(struc.history[1]['species_map'])))) print('Done.')
def batch_write_vasp_input( transformed_structures, vasp_input_set=MPRelaxSet, output_dir=".", create_directory=True, subfolder=None, include_cif=False, **kwargs, ): """ Batch write vasp input for a sequence of transformed structures to output_dir, following the format output_dir/{group}/{formula}_{number}. Args: transformed_structures: Sequence of TransformedStructures. vasp_input_set: pymatgen.io.vaspio_set.VaspInputSet to creates vasp input files from structures. output_dir: Directory to output files create_directory (bool): Create the directory if not present. Defaults to True. subfolder: Function to create subdirectory name from transformed_structure. e.g., lambda x: x.other_parameters["tags"][0] to use the first tag. include_cif (bool): Boolean indication whether to output a CIF as well. CIF files are generally better supported in visualization programs. """ for i, s in enumerate(transformed_structures): formula = re.sub(r"\s+", "", s.final_structure.formula) if subfolder is not None: subdir = subfolder(s) dirname = os.path.join(output_dir, subdir, "{}_{}".format(formula, i)) else: dirname = os.path.join(output_dir, "{}_{}".format(formula, i)) s.write_vasp_input(vasp_input_set, dirname, create_directory=create_directory, **kwargs) if include_cif: from pymatgen.io.cif import CifWriter writer = CifWriter(s.final_structure) writer.write_file(os.path.join(dirname, "{}.cif".format(formula)))
def out_cif(struc, cID, tmp_path, fpath, symprec=0.1): # ---------- opt_CIFS cif = CifWriter(struc, symprec=symprec) cif.write_file(tmp_path + 'tmp.cif') # ---------- correct title for VESTA (need to delete '_chemical_formula_sum') with open(tmp_path + 'tmp.cif', 'r') as fcif: ciflines = fcif.readlines() ciflines[1] = 'data_ID_{}\n'.format(cID) if ciflines[11][:21] == '_chemical_formula_sum': ciflines.pop(11) else: raise ValueError('ciflines[11] is not _chemical_formula_sum, have to fix bag') # ---------- cif --> opt_cifs with open(fpath, 'a') as foptcif: for line in ciflines: foptcif.write(line) # ---------- clean tmp.cif os.remove(tmp_path + 'tmp.cif')
def out_opt_cif(opt_struc, current_id, work_path): # ---------- opt_CIFS cif = CifWriter(opt_struc, symprec=rin.symtoleR) cif.write_file(work_path + 'tmp.cif') # ---------- correct title (need to delete '_chemical_formula_sum') with open(work_path + 'tmp.cif', 'r') as fcif: ciflines = fcif.readlines() ciflines[1] = 'data_ID_{}\n'.format(current_id) if ciflines[11][:21] == '_chemical_formula_sum': ciflines.pop(11) else: raise ValueError( 'ciflines[11] is not _chemical_formula_sum, have to fix bag') # ---------- cif --> opt_cifs with open('./data/opt_CIFS.cif', 'a') as foptcif: for line in ciflines: foptcif.write(line) # ---------- clean tmp.cif os.remove(work_path + 'tmp.cif')
def batch_write_vasp_input(transformed_structures, vasp_input_set=MPRelaxSet, output_dir=".", create_directory=True, subfolder=None, include_cif=False, **kwargs): """ Batch write vasp input for a sequence of transformed structures to output_dir, following the format output_dir/{group}/{formula}_{number}. Args: transformed_structures: Sequence of TransformedStructures. vasp_input_set: pymatgen.io.vaspio_set.VaspInputSet to creates vasp input files from structures. output_dir: Directory to output files create_directory (bool): Create the directory if not present. Defaults to True. subfolder: Function to create subdirectory name from transformed_structure. e.g., lambda x: x.other_parameters["tags"][0] to use the first tag. include_cif (bool): Boolean indication whether to output a CIF as well. CIF files are generally better supported in visualization programs. """ for i, s in enumerate(transformed_structures): formula = re.sub(r"\s+", "", s.final_structure.formula) if subfolder is not None: subdir = subfolder(s) dirname = os.path.join(output_dir, subdir, "{}_{}".format(formula, i)) else: dirname = os.path.join(output_dir, "{}_{}".format(formula, i)) s.write_vasp_input(vasp_input_set, dirname, create_directory=create_directory, **kwargs) if include_cif: from pymatgen.io.cif import CifWriter writer = CifWriter(s.final_structure) writer.write_file(os.path.join(dirname, "{}.cif".format(formula)))
def write_cif(path, structure): writer = CifWriter(structure) writer.write_file(path)
row.append(i['volume']) row.append(i['density']) row.append(i['energy_per_atom']) row.append(i['formation_energy_per_atom']) # save cif and csv files c = CifWriter(i['structure']) # add G_Voigt_Reuss_Hill, K_Voigt_Reuss_Hill, elastic_anisotropy, poisson_ratio if search_key == 'elasticity': elasticity = i['elasticity'] row.append(elasticity['G_Voigt_Reuss_Hill']) row.append(elasticity['K_Voigt_Reuss_Hill']) row.append(elasticity['elastic_anisotropy']) row.append(elasticity['poisson_ratio']) cif_file = './training/elasticity/data/' + material_id + '.cif' c.write_file(cif_file) csv_writer_warnings.writerow(row) if elasticity['warnings']: continue else: csv_writer.writerow(row) # add eij_max elif search_key == 'piezo': piezo = i['piezo'] row.append(piezo['eij_max']) # add n - dielectric constant, poly_electronic - refractive index, poly_total - ferroelectricity elif search_key == 'diel': diel = i['diel'] row.append(diel['n'])
#!/usr/bin/python3 from pymatgen import Structure from pymatgen.transformations.standard_transformations import OrderDisorderedStructureTransformation from pymatgen.transformations.advanced_transformations import EnumerateStructureTransformation from pymatgen.io.cif import CifWriter import sys try: cif_filename = sys.argv[1] except ValueError: print("please give the cif file name as the 1st argument!") s = Structure.from_file(cif_filename) prim = s.get_primitive_structure() # Merge sites that are less than 1A apart. prim.merge_sites(1) prim = prim.get_sorted_structure() t = EnumerateStructureTransformation() ordered = t.apply_transformation(prim, 5) print(len(ordered)) for i in range(len(ordered)): c = CifWriter(ordered[i]['structure'], symprec=0.01) c.write_file("LLZO_ordered-" + str(i) + ".cif")
def cif_lib_build(self, crystal_system, size_limit=None): ''' function to build cif and pdf library based on space group symbol Parameters ---------- crystal_system: str name of crystal system. It capitalized, like CUBIC. space group symbol will be generated by get_symbol_list method size_list : int optional. Uppder limit of data pulled out per symbol ''' self.crystal_system = crystal_system space_group_symbol = self.get_symbol_list(crystal_system) if isinstance(space_group_symbol, list): space_group_symbol_set = space_group_symbol else: space_group_symbol_set = list(spac_group_symbol) ## changing dir data_dir = os.path.join(self.working_dir, crystal_system) self.data_dir = data_dir self._makedirs(data_dir) os.chdir(data_dir) if os.getcwd() == data_dir: print('Library will be built at %s' % data_dir) else: e = 'Werid, return' raise RuntimeError(e) # summary lists missed_list = [] # reference m_id_list = [] # reference for searchs have been done in the past time_info = time.strftime('%Y-%m-%d') # create dirs, cif and calculated dir cif_dir = os.path.join(data_dir, 'cif_data') self._makedirs(cif_dir) self.cif_dir = cif_dir # looping for space_group_symbol in space_group_symbol_set: print('Building library with space_group symbol: {}'.format(space_group_symbol)) ## search query m = MPRester(self.API_key) search = m.query(criteria = {"spacegroup.symbol": space_group_symbol}, properties = ["material_id"]) if search: ## crazy looping if size_limit: dim = 400 # 400 data sets per symbol else: dim = len(search) print('Pull out %s data sets' % dim) print('Now, starts to save cif and compute pdf...') for i in range(dim): # part 1: grab cif files from data base m_id = search[i]['material_id'] m_id_list.append(m_id) m_struc = m.get_structure_by_material_id(m_id) m_formula = m_struc.formula m_name = m_formula.replace(' ', '') # material name cif_w = CifWriter(m_struc) cif_name = '{}_{}.cif'.format(space_group_symbol, m_name) cif_w_name = os.path.join(cif_dir, cif_name) if os.path.isfile(cif_w_name): print('already have {}, skip'.format(cif_name)) pass # skip files already exist else: cif_w.write_file(cif_w_name) print('{} has been saved'.format(cif_name)) else: print('Hmm, no reasult. Something wrong') missed_list.append(space_group_symbol) pass m_id_list_name = '{}_{}_material_id.txt'.format(crystal_system, time_info) m_id_list_w_name = os.path.join(data_dir, m_id_list_name) np.savetxt(m_id_list_w_name, m_id_list) print('''SUMMARY: for {} cystsal sytem, Symbols {} can't be found from data base'''.format(crystal_system, missed_list)) return cif_dir
continue ss = 0 if checkDistance(i / fft[0], j / fft[1], k / fft[2], pos, 0.01, scale, a, b, c): # print ('too close to the structure') n += 1 chg.pop() continue charge = chg.pop() writeStructureLocalEnvironandAddAnAtom(i, j, k, n, title, scale, a, b, c, at_labels, nElements, ats, ntot, pos, fft) p = Poscar.from_file('POSCAR_%s' % (str(n))) w = CifWriter(p.structure, symprec=1e-6) w.write_file('%s/%s%08d.cif' % (root_dir, struct, n)) os.system('rm POSCAR*') print( '%s: %d %d %d finished with charge %f and index %d, %d %d %d remained' % (struct, i, j, k, charge, n, fft[0] - i, fft[1] - j, fft[2] - k)) print('%s%08d,%4f' % (struct, n, charge), file=open('%s/id_prop.csv' % (root_dir), 'a') ) #for the convenience of recovering from .csv to CHGCAR n += 1 m += 1 Charge[i][j][k] = charge equ_points = [] #record equivalent points of i,j,k1 for ops in symmops: equ_points.append( ops.operate([i / fft[0], j / fft[1], k / fft[2]]))
def __init__(self): self.CIFDIR = "cifdir/" self.key = input.APIKEY # Import API key from input self.MaterialID = input.MATERIALID # Set class variable MaterialID from input self.seedname = str( input.SEEDNAME) # set class variable SEEDNAME from input file self.Ecut = input.ECUT #Class variable; in Ryberg, transfer from input file self.kpts = input.KMESH ### KPTS from input file for a generator, class variable self.SEEDDIR = "OUTPUT/" + 'STA-' + self.seedname + '/' #set the seed directory #self.pseudodir = "ABINIT/ABINITPP/ATOMICDATA/" # Set the directory for pseudopotentials self.EMAIL = input.EMAIL #Class variable; set email for SLURM from input file self.NCORE = input.ncore #Class Variable; number of cores, taken from input file self.SOC = input.SOC self.nbnd = input.NUMBANDS # MAKE DIRECTORIES if not os.path.exists(self.SEEDDIR): os.makedirs(self.SEEDDIR) if not os.path.exists(self.SEEDDIR + "WT"): os.makedirs(self.SEEDDIR + "WT") #import structure from PYMATGEN with matproj.MPRester(self.key) as m: struct = m.get_structure_by_material_id( self.MaterialID, final=True, conventional_unit_cell=False ) # GET STRUCT FROM MATERIALS PROJECT self.struct = m.get_structure_by_material_id( self.MaterialID, final=True, conventional_unit_cell=False ) # GET STRUCT FROM MATERIALS PROJECT C = Composition(str(struct.formula)) ########## MAKE A CIF FILE ### cif = CifWriter(struct) # Start generator cif.write_file(self.CIFDIR + self.seedname + ".cif") #write cif file to directory ciffile = self.CIFDIR + self.seedname + ".cif" # define ciffile cif = open(ciffile) # open cif file parser = CifParser(ciffile) #Start Parser ####### PARSE VARIABLES FROM CIF ########## chk_a = "_cell_length_a" chk_b = "_cell_length_b" chk_c = "_cell_length_c" chk_alpha = "_cell_angle_alpha" chk_beta = "_cell_angle_beta" chk_gamma = "_cell_angle_gamma" chk_name = "_chemical_formula_structural" for x in cif: if chk_a in x: self.a = x.replace(chk_a, '').replace('\n', '') if chk_b in x: self.b = x.replace(chk_b, '').replace('\n', '') if chk_c in x: self.c = x.replace(chk_c, '').replace('\n', '') if chk_alpha in x: self.alpha = x.replace(chk_alpha, '').replace('\n', '') if chk_beta in x: self.beta = x.replace(chk_beta, '').replace('\n', '') if chk_gamma in x: self.gamma = x.replace(chk_gamma, '').replace('\n', '') #if chk_name in x: # seedname = x.replace(chk_name, '') # seedname = seedname.replace('\n', '').translate( # {ord(i): None for i in ' '}) self.UNIQUE_ATOMS = np.unique(struct.species) self.cord = struct.frac_coords self.ntypat = np.unique(struct.atomic_numbers).size self.natom = np.array(struct.atomic_numbers).size self.numlist = np.array(struct.atomic_numbers)[::1] self.atomnum = np.unique(struct.atomic_numbers)[::1] self.typat = "" for x in struct.atomic_numbers: for at in self.atomnum: if at == x: self.typat += ''.join( map(str, np.where(self.atomnum == at)[0] + 1)) + " " # SOC CASE num_bands = input.NUMBANDS # for x in struct.species: # PP = gb.glob(self.pseudodir + str(x) + ".*") # readpp = minidom.parse(''.join(map(str,PP))) # items = readpp.getElementsByTagName('atom') # num_bands += float(items[0].attributes['valence'].value) num_wann = num_bands - (num_bands % 2) # FORCE EVEN self.wan = num_wann if self.SOC: self.WTwan = self.wan / 2
# initialize a list to store all the structures struct_lst = [] with mg.MPRester(api_key) as m: for formula, spacegroup_number in zip(mp_query_df.formula, mp_query_df.spacegroup_number): try: # query structures based on the pretty formula and spacegroup number struct = m.query(criteria={"pretty_formula": formula, "spacegroup.number": spacegroup_number}, properties=["structure"])[0]["structure"] except IndexError: # if there isn't an exact, get the pretty formula struct = formula struct_lst.append(struct) # %% examine the query result # check which compounds don't have an exact match in Materials Project unmatched_struct = [structure for structure in struct_lst if isinstance(structure, str)] print("Number of unmatched structures: {}\n {}".format(len(unmatched_struct), unmatched_struct)) # there are 15 out of 90 unmatched structures # get the compound structures with a match matched_struct = [structure for structure in struct_lst if isinstance(structure, mg.Structure)] # write the structures as CIF files for structure in matched_struct: pretty_formula = structure.composition.reduced_formula cif = CifWriter(structure) cif.write_file(STRUCT_PATH + pretty_formula + ".cif")
os.chdir(prev_dir) with open("../data.pickle", "rb") as fr: data = pickle.load(fr) x_train = data["x_train"] y_train = data["y_train"] x_val = data["x_val"] y_val = data["y_val"] x_test = data["x_test"] y_test = data["y_test"] train_mpids = data["train_mpids"] val_mpids = data["val_mpids"] test_mpids = data["test_mpids"] all_x = np.concatenate((x_train, x_val, x_test), axis=0) all_y = np.concatenate((y_train, y_val, y_test), axis=0) all_mpids = np.concatenate((train_mpids, val_mpids, test_mpids), axis=0) id_prop = [] with alive_bar(len(all_x)) as bar: for x, y, mp in zip(all_x, all_y, all_mpids): if x.state == [[600]]: id_prop.append([f"mp-{mp}", y]) cw = CifWriter(x, symprec=0.001) cw.write_file(f"structures/mp-{mp}.cif") bar() np.savetxt("structures/id_prop.csv", id_prop, delimiter=",", fmt="%s")
def find_unique_structures(base_crystal_path, directory): """ DESCRIPTION: Given a base crystal structure along with a directory containing CIF structures, determine how many unique configurations are in the directory, and assign a configuration ID number to each CIF structure in the directory. Results can be seen in the outputted unique.csv file. The function uses the base crystal structure provided to find the space group and associated symmetry operations, which are then used to see whether the CIF structures in the directory are equivalent. PARAMETERS: base_crystal_path: string The path to the base crystal CIF structure. Note that this structure should contain the space group that you want to check all other structures to. If the symmetry of this structure is incorrect, you will get unexpected results. directory: string The path to the directory containing the CIF structures to compare. Note that this function assumes that the CIF names are all prefixed by a dash and followed by an interger, ie "LiCoO2-1", "LiCoO2-2", "LiCoO2-3"..., ect. RETURNS: None """ # convert all files (they should all be cif files) in the directory into Structures and place them into a list cif_file_names = [ os.path.splitext(os.path.basename(path))[0] for path in os.listdir(directory) if path.endswith('.cif') ] cif_files = [ directory + path for path in os.listdir(directory) if path.endswith('.cif') ] cif_files = sorted(cif_files, key=lambda x: int(x.split("-")[-1].replace(".cif", ""))) cif_file_names = sorted(cif_file_names, key=lambda x: int(x.split("-")[-1])) structures = [IStructure.from_file(path) for path in cif_files] print(cif_file_names) # Get the base crystal structure base_crystal = IStructure.from_file(base_crystal_path) # Get the space group of the base crystal analyzer = SpacegroupAnalyzer(base_crystal) spacegroup = analyzer.get_space_group_operations() print(spacegroup) id = 1 num_structures = len(structures) config_dict = {} unique_structs = [] for i in range(num_structures): config1 = structures[i] unique_cif_name = cif_file_names[i] if not unique_cif_name in config_dict: config_dict[unique_cif_name] = id print("%s Unique Structures Found..." % (id)) unique_structs.append(config1) id += 1 for j in range(num_structures): cif_name = cif_file_names[j] config2 = structures[j] if not cif_name in config_dict: isEquivalent = spacegroup.are_symmetrically_equivalent( config1, config2) if isEquivalent: config_dict[cif_name] = config_dict[unique_cif_name] print("----------------------------------------------") print("%s Total Unique Structures Found" % (id - 1)) print("----------------------------------------------") with open('unique.csv', 'w') as f: for key in config_dict.keys(): f.write("%s,%s\n" % (key, config_dict[key])) crystal_name = os.path.splitext(os.path.basename(base_crystal_path))[0] directory_path = "{}-unique".format(crystal_name) if not os.path.isdir(directory_path): os.mkdir(directory_path) num_unique_structures = len(unique_structs) for i in range(num_unique_structures): config = unique_structs[i] #Save to CIF filename = crystal_name + '_ewald' + '_{}'.format(i + 1) w = CifWriter(config) w.write_file(directory_path + '/' + filename + '.cif') # print("Cif file saved to {}.cif".format(filename)) #Save to POSCAR poscar = Poscar(config) poscar.write_file(directory_path + '/' + filename)
def generate_ewald_orderings(path, choose_file, oxidation_states, num_structures): """ DESCRIPTION: Given a disordered CIF structure with at least one crystallographic site that is shared by more than one element, all permutations will have their electrostatic energy calculated via an Ewald summation, given that all ion charges are specified. Ordered CIF structures will be generated, postpended with a number that indicates the stability ranking of the structure. For example, if a CIF file called "Na2Mn2Fe(VO4)3.cif" is inputted with num_structures=3, then the function will generate 3 ordered output files, "Na2Mn2Fe(VO4)3-ewald-1", "Na2Mn2Fe(VO4)3-ewald-2", and "Na2Mn2Fe(VO4)3-ewald-3", with "Na2Mn2Fe(VO4)3-ewald-1" being the most stable and "Na2Mn2Fe(VO4)3-ewald-3" being the least stable. Note that this function does not take into account the symmetry of the crystal, and thus it may give several structures which are symmetrically identical under a space group. Use "find_unique_structures" to isolate unique orderings. PARAMETERS: path: string The file path to the CIF file. The CIF file must be a disordered structure, or else an error will occur. A disordered structure will have one site that is occupied by more than one element, with occupancies less than 1: i.e. Fe at 0,0,0.5 with an occupancy of 0.75, and Mn at the same site 0,0,0.5 with an occupancy of 0.25. This function cannot handle multivalent elements, for example it cannot handle a structure that has Mn in both the 2+ and 3+ redox state. choose_file: boolean Setting this parameter to True brings up the file explorer dialog for the user to manually select the CIF file oxidation_states: dictionary A dictionary that maps each element in the structure to a particular oxidation state. E.g. {"Fe": 3, "Mn": 2, "O": -2, "V": 5, "Na": 1, "Al":3} Make sure that all elements in the structure is assigned an oxidation state. It is ok to add more elements than needed. num_structures: int The number of strcutures to be outputted by the function. There can be hundreds or thousands of candidate structures, however in practice only the first few (or even only the first, most stable) structures are needed. RETURNS: None """ # open file dialog if file is to be manually chosen if choose_file: root = tk.Tk() root.withdraw() path = filedialog.askopenfilename() #Read cif file cryst = Structure.from_file(path) analyzer = SpacegroupAnalyzer(cryst) space_group = analyzer.get_space_group_symbol() print(space_group) symm_struct = analyzer.get_symmetrized_structure() cryst = TransformedStructure(symm_struct) #Create Oxidation State Transform oxidation_transform = OxidationStateDecorationTransformation( oxidation_states) #Create Ewald Ordering Transform object which will be passed into the transmuter ordering_transform = OrderDisorderedStructureTransformation( symmetrized_structures=True) # apply the order-disorder transform on the structure for any site that has fractional occupancies transmuter = StandardTransmuter([cryst], [oxidation_transform, ordering_transform], extend_collection=num_structures) print("Ewald optimization successful!") num_structures = len(transmuter.transformed_structures) for i in range(num_structures): newCryst = transmuter.transformed_structures[i].final_structure #Save to CIF structure_name = os.path.splitext(os.path.basename(path))[0] save_directory = structure_name if not os.path.isdir(save_directory): os.mkdir(save_directory) filename = structure_name + '/' + structure_name + '-ewald' + '-%i' % ( i + 1) w = CifWriter(newCryst) w.write_file(filename + '.cif') print("Cif file saved to {}.cif".format(filename)) #Save to POSCAR poscar = Poscar(newCryst) poscar.write_file(filename) print("POSCAR file saved to {}".format(filename))
# In[5]: from pymatgen import Structure from pymatgen import symmetry from pymatgen.ext.matproj import MPRester from pymatgen.io.cif import CifWriter from pymatgen.symmetry.analyzer import SpacegroupAnalyzer from pymatgen.core.operations import SymmOp from IPython.display import Image with MPRester("izD7mJmnjhUOKyWGtZ") as m: # Structure for material id structure = m.get_structure_by_material_id("mp-27869") w = CifWriter(structure) w.write_file('mp-27869.cif') sGP = SpacegroupAnalyzer(structure) print("2ème élément de symétrie (Ci:0 0 0):") Op1 = SymmOp.from_xyz_string("-x, -y, -z") print("Effet sur P1 #2:") Eff1 = Op1.operate((0, 0, 1 / 2)) print(Eff1) display(Image(filename='sym1.jpg')) print("4ème élément de symétrie (3-bar axis:y,-x+y,-z):") Op2 = SymmOp.from_xyz_string("y,-x+y,-z") print("Effet sur BaO1 #4:") Eff2 = Op2.operate((0, 0, 0.24)) print(Eff2) display(Image(filename='sym2.jpg')) print("5ème élément de symétrie (3-bar axis:-x+y,-x,z):") Op3 = SymmOp.from_xyz_string("-x+y,-x,z")
from pymatgen.io.cif import CifWriter def get_struc(infile, cid): with open(infile, 'rb') as f: struc_dict = pickle.load(f) return struc_dict[cid] if __name__ == '__main__': ''' extract a structure from init_struc_data.pkl or opt_struc_data.pkl and output cif file ''' # ---------- argparse parser = argparse.ArgumentParser() parser.add_argument('-s', '--symmetrized', help='flag for symmetrized structure', action='store_true') parser.add_argument('infile', help='input file') parser.add_argument('cid', help='structure ID', type=int) args = parser.parse_args() # ---------- get structure struc = get_struc(args.infile, args.cid) # ---------- write cif if args.symmetrized: cw = CifWriter(struc, symprec=0.1) else: cw = CifWriter(struc, symprec=None) cw.write_file('{}.cif'.format(args.cid))
a=sys.argv[2].split(',') b=sys.argv[3].split(',') c=sys.argv[4].split(',') sp =[a,b,c] l=sys.argv[2].replace(',','') m=sys.argv[3].replace(',','') n=sys.argv[4].replace(',','') size=l+"x"+m+"x"+n else: print("Check input formatting") ## compatbility with QE input/output #if filname.endswith(".in"): # with open("fil.xsf","w") as outfile: # subprocess.check_call(["pwi2xsf",filname],stdout=outfile) # filname="fil.xsf" #elif filname.endswith(".out"): # subprocess.check_call(["pwo2xsf",filname," > fil.xsf"]) # filname="fil.xsf" # Read structure from PWscf file, xsf format structure = Structure.from_file(filname) # make supercell structure.make_supercell(sp,to_unit_cell=True) # output to cif w = CifWriter(structure) w.write_file("super-"+size+"-"+outname[0]+".cif")
def get_cif(filename, tolerance=0.1): struc = Structure.from_file(filename) cif = CifWriter(struc, symprec=tolerance) cif.write_file(filename + '.cif')
def add_to_archive_database(cl, subgroup): """ cl is Calculation which should be added to database subgroup (str) - subgroup folder """ from pymatgen.core.composition import Composition from pymatgen.io.cif import CifWriter from pymatgen.symmetry.analyzer import SpacegroupAnalyzer join = os.path.join basename = os.path.basename dirname = os.path.dirname save_format = 'azh' dbpath = header.PATH2DATABASE it = cl.id[0] # print(cl.path) sub_folder = cl.path['output'].split('/')[ 0] # usually basic chemical formula # sub_folder = header.struct_des[it].sfolder.split('/')[0] # usually basic chemical formula print('Processing ', cl.id) cl.read_results() if '4' not in cl.state: return st = cl.end # print(cl.end.typat) # sys.exit() if 1: #determine x #universal method, supports several alkali elements #requires cl.base_formula in 'Na2FePO4F' format #requires pymatgen, would be nice to remove dependency cmb = Composition(cl.base_formula) cm = st.get_pm_composition() rc = cl.end.get_reduced_composition().as_dict( ) #reduced composition dict rcb = cmb.reduced_composition.as_dict() # print(rc, rcb) alk = list(set(st.get_specific_elements( header.ALKALI_ION_ELEMENTS))) # list of unique alkali elements tra = list(set(st.get_specific_elements(header.TRANSITION_ELEMENTS))) # print(alk, tra) el_for_norm = tra[0] #first element used for normalization nnb = rcb[el_for_norm] #number of norm elements in base nn = rc[el_for_norm] #number of norm elements in interesting structure # print(nb, n) mul = nn / nnb # multiplier that garanties normalization # print(rcb) nab = sum([ rcb[invert(z)] for z in header.ALKALI_ION_ELEMENTS if invert(z) in rcb ]) na = sum([rc[el] for el in alk]) x = na / mul / nab # determine formula # cm = st.get_pm_composition() #get pymatgen composition class # print( (cm/4).formula) # print('Material detected:', formula, 'sub_folder:', sub_folder) #obtain base without alk formula = (cm.reduced_composition / mul).formula # formula = formula.replace('1 ', '').replace(' ', '') # print(formula) cl.formula = formula # print(Composition('Na0.75')) print('Material detected:', formula, 'sub_folder:', sub_folder) # sys.exit() if 0: #Old method, not robust at all! #determine x for alkali ion from structure name parsed = re.findall(r'([A-Z][a-z]*)(\d*)', formula) parsed = [(el, x if x else '1') for (el, x) in parsed] print(parsed) print('detected element is ', parsed[0][0]) if parsed[0][0] in [invert(z) for z in header.ALKALI_ION_ELEMENTS]: x = parsed[0][0] if hasattr(cl, 'max_alk_ion_content'): x = float(x) / cl.max_alk_ion_content else: x = '1' else: x = '0' sfolder = os.path.join(dbpath, sub_folder) name = [] if 'azh' in save_format: #1. Single point calculation of total energy # print(sfolder) makedir(join(sfolder, 'dummy')) if x < 1: x = int(round(100 * x, 0)) else: x = int(round(x, 0)) print('Concentration x:', x) name.append('x' + str(x)) # sys.exit() # if formula in ['LiCoO2', 'LiTiO2', 'LiFePO4', 'NaFePO4', 'LiMnPO4', # 'LiNiO2', 'LiTiS2', 'LiMn2O4', 'LiVP2O7', 'LiVPO4F', # 'NaMnAsO4', 'Na2FePO4F', 'Na2FeVF7', 'KFeSO4F', 'NaLiCoPO4F', 'KVPO4F' ]: sfolder = join(sfolder, subgroup) makedir(join(sfolder, 'dummy')) cl.set.update() # print(cl.potcar_lines) potcar1_m = cl.potcar_lines[0][0] if '_' in potcar1_m: (pot, _) = potcar1_m.split('_') else: pot = potcar1_m xc = cl.xc_inc if '-' in xc: xc = cl.xc_pot if xc == 'PE': func = 'PBE' elif xc == 'CA': func = 'LDA' elif xc == 'PS': func = 'PBEsol' else: print('uknown xc type:', xc) sys.exit() if cl.set.spin_polarized: func = 'U' + func #unrestricted u_ramping_flag = False if hasattr(cl.set, 'u_ramping_nstep') and cl.set.u_ramping_nstep: func += '-UR' u_ramping_flag = True elif cl.set.dftu: func += '-U' else: func += '-' func += pot.lower() ecut = str(round(cl.set.ecut)) func += ecut # print(func) name.append(func) name.extend([it.replace('.', '_')] + [cl.id[1]] + [str(cl.id[2])]) name_str = '_'.join(name) # print('_'.join(name) ) # sys.exit() outcar_name = name_str + '.out' shutil.copyfile(cl.path["output"], join(sfolder, outcar_name)) if u_ramping_flag: print(cl.associated_outcars) for i, u_outcar in enumerate( cl.associated_outcars[:-1] ): # except the last one, which was copied above u = u_outcar.split('.')[1] # print(u) path_to_outcar = join(dirname(cl.path["output"]), u_outcar) cl.read_results(load='o', choose_outcar=i + 1, only_load=1) shutil.copyfile(path_to_outcar, join(sfolder, name_str + '_' + u + '.out')) # sys.exit() cl.end.write_xyz(path=sfolder, filename=name_str) pickle_file = cl.serialize(os.path.join(sfolder, 'bin', name_str)) # cl #write input, problem with fitted version 100, which does not have input geometry, since they are created on cluster # makedir(sfolder+'input/dummy') # shutil.copyfile(cl.path["input_geo"], sfolder+'input/'+name_str+'.geo') st_mp = cl.end.convert2pymatgen() sg_before = st_mp.get_space_group_info() # from pymatgen.symmetry.finder import SymmetryFinder # sf = SymmetryFinder(st_mp_prim) symprec = 0.1 sf = SpacegroupAnalyzer(st_mp, symprec=symprec) st_mp_prim = sf.find_primitive() # st_mp_prim = sf.get_primitive_standard_structure() # st_mp_prim = sf.get_conventional_standard_structure() # st_mp_conv = sf.get_conventional_standard_structure() # print(st_mp_conv) # print(st_mp_conv.lattice.matrix) # print(st_mp_prim) # print(st_mp_prim.lattice) sg_after = st_mp_prim.get_space_group_info() if sg_before[0] != sg_after[0]: printlog( 'Attention! the space group was changed after primitive cell searching', sg_before, sg_after) printlog('I will save supercell in cif and reduce symprec to 0.01') st_mp_prim = st_mp symprec = 0.01 if st_mp_prim: cif = CifWriter(st_mp_prim, symprec=symprec) cif_name = name_str + '.cif' cif.write_file(join(sfolder, cif_name)) printlog('Writing cif', cif_name) if 0: #get multiplication matrix which allows to obtain the supercell from primitive cell. #however this matrix is not integer which is not convinient. print(st_mp.lattice.matrix.round(2)) print(st_mp_prim.lattice.matrix.round(2)) mul_matrix = np.dot(st_mp.lattice.matrix, np.linalg.inv(st_mp_prim.lattice.matrix)) print(mul_matrix.round(1)) rprimd = np.dot(mul_matrix, st_mp_prim.lattice.matrix) print(rprimd.round(2)) #write chg if 1: path_to_chg = cl.get_chg_file('CHGCAR') if path_to_chg: makedir(join(sfolder, 'bin', 'dummy')) printlog('path to chgcar', path_to_chg) gz = '.gz' if gz not in path_to_chg: gz = '' shutil.copyfile(path_to_chg, join(sfolder, 'bin', name_str + '.chg' + gz)) #write dos if subgroup in ['dos', 'DOS']: DOSCAR = cl.get_file('DOSCAR', nametype='asoutcar') if DOSCAR: printlog('path to DOSCAR', DOSCAR) gz = '.gz' if gz not in path_to_chg: gz = '' shutil.copyfile(DOSCAR, join(sfolder, 'bin', name_str + '.dos' + gz)) if subgroup in ['BAD']: #bader cl.get_bader_ACF() acf = cl.get_file(basename(cl.path['acf'])) # print(acf) # sys.exit() if acf: shutil.copyfile(acf, join(sfolder, 'bin', name_str + '.acf')) if subgroup in ['ph', 'PH']: #bader # cl.get_bader_ACF() xml = cl.get_file('vasprun.xml', nametype='asoutcar') # print(acf) # sys.exit() if xml: shutil.copyfile(xml, join(sfolder, 'bin', name_str + '.xml')) #make dat #incars makedir(join(sfolder, 'dat', 'dummy')) incars = glob.glob(join(cl.dir, '*INCAR*')) # print(incars) for inc in incars: dest = join(sfolder, 'dat') # inc_name = if not os.path.exists(join(dest, basename(inc))): shutil.copy(inc, dest) #kpoints if it in header.struct_des: with open(join(sfolder, 'dat', 'kpoints_for_kspacings.json'), 'w', newline='') as fp: json.dump( header.struct_des[it].ngkpt_dict_for_kspacings, fp, ) else: printlog('Warning!, it not in struct_des:', it) # print(cl.set.toJSON()) #prepare for neb # makedir(sfolder+'neb_'+name_str+'/dummy') return
# import structure into pymatgen strucbin = "/home/wwwennie/[email protected]/bin/pos_tmp/" #filname = strucbin+"tet.in" #bivo4 = struct_import(ubin,filname) # #filname = strucbin+"pseudotet.in" # volume expansion, not quite hydrostatic #bivo4comp = struct_import(filname) filname = strucbin + "Ov-s15v20.in" bivo4surf = struct_import(filname) ########### polaron bias ######### struct = bias_polaron(bivo4surf, 121, 1.9, bias=1.05) w = CifWriter(struct) w.write_file("bias.cif") ########### surface structure histogram ####### #title="Bond length distribution" #legend=["Bi-O","V-O"] #len_BiO,surfBiatoms = bonds.surf_spec_bond_len(bivo4surf,2.8,'Bi','O',n=2) #len_VO,surfVatoms = bonds.surf_spec_bond_len(bivo4surf,2.8,'V','O',n=2) #plot.hist_plot([len_BiO,len_VO], title,legend,xlim=[1.6,2.65]) # #title="Bond angle distribtion" #legend=["O-Bi-O","O-V-O"] #ang_BiO = bonds.surf_spec_bond_angle(bivo4,2.8,'Bi','O',n=2) #ang_VO = bonds.surf_spec_bond_angle(bivo4,2.8,'V','O',n=2) #plot.hist_plot([ang_BiO,ang_VO], title,legend,xlim=[65,165]) # ###### effect of relaxation #######
def upload_file(): stamp = "" if request.method == 'POST': #request.environ['REMOTE_ADDR'] if request.environ.get('HTTP_X_FORWARDED_FOR') is None: ip = request.environ['REMOTE_ADDR'] else: ip = request.environ['HTTP_X_FORWARDED_FOR'] # if behind a proxy #substrate information# f1 = request.files['POSCAR_sub'] stamp = time.strftime("%Y%m%d-%H%M%S") + '-' + ip poscar_sub = stamp + '-' + f1.filename f1.save(upload_dir + os.sep + secure_filename(poscar_sub)) h_sub = int(request.form["h_sub"]) k_sub = int(request.form["k_sub"]) l_sub = int(request.form["l_sub"]) nlayers_substrate = int(request.form["nlayers_substrate"]) min_thick_sub = float(request.form["min_thick_sub"]) min_vac_sub = float(request.form["min_vac_sub"]) #is_primitive = request.form.get["is_primitive"] hkl_sub = [h_sub, k_sub, l_sub] #2d information# f2 = request.files['POSCAR_2d'] poscar_2d = stamp + '-' + f2.filename f2.save(upload_dir + os.sep + secure_filename(poscar_2d)) h_2d = int(request.form["h_2d"]) k_2d = int(request.form["k_2d"]) l_2d = int(request.form["l_2d"]) nlayers_2d = int(request.form["nlayers_2d"]) hkl_2d = [h_2d, k_2d, l_2d] #General information# separation = float(request.form["separation"]) max_area = float(request.form["max_area"]) max_mismatch = float(request.form["max_mismatch"]) max_angle_diff = float(request.form["max_angle_diff"]) #Matching# try: substrate_bulk = pymatgen.Structure.from_file(upload_dir + os.sep + poscar_sub) sa_sub = pymatgen.symmetry.analyzer.SpacegroupAnalyzer( substrate_bulk) substrate_bulk = sa_sub.get_conventional_standard_structure() substrate_slab = Interface(substrate_bulk, hkl=hkl_sub, min_thick=min_thick_sub, min_vac=min_vac_sub, primitive=False, from_ase=True) mat2d_slab = utils.slab_from_file(hkl_2d, upload_dir + os.sep + poscar_2d) operation_dir = "static" + os.sep + "operations" + os.sep + stamp if not os.path.exists(operation_dir): os.makedirs(operation_dir) mat2d_slab.to(fmt="poscar", filename=operation_dir + "POSCAR_mat2d_slab.vasp") sd_flags = CalibrateSlab.set_sd_flags(interface=substrate_slab, n_layers=nlayers_substrate, top=True, bottom=False) poscar = pymatgen.io.vasp.inputs.Poscar( substrate_slab, selective_dynamics=sd_flags) poscar.write_file(filename=operation_dir + os.sep + "POSCAR_substrate_slab.vasp") substrate_slab_aligned, mat2d_slab_aligned, mismatch = transformations.get_aligned_lattices( substrate_slab, mat2d_slab, max_area=max_area, max_mismatch=max_mismatch, max_angle_diff=max_angle_diff, r1r2_tol=0.01) substrate_slab_aligned.to(fmt="poscar", filename=operation_dir + os.sep + "POSCAR_substrate_aligned.vasp") mat2d_slab_aligned.to(fmt="poscar", filename=operation_dir + os.sep + "POSCAR_mat2d_aligned.vasp") hetero_interfaces = transformations.generate_all_configs( mat2d_slab_aligned, substrate_slab_aligned, nlayers_2d, nlayers_substrate, separation) for i, iface in enumerate(hetero_interfaces): sd_flags = CalibrateSlab.set_sd_flags(interface=iface, n_layers=nlayers_2d + nlayers_substrate, top=True, bottom=False) poscar = pymatgen.io.vasp.inputs.Poscar( iface, selective_dynamics=sd_flags) poscar.write_file(filename=operation_dir + os.sep + 'POSCAR_final_{}.vasp'.format(i)) p = Poscar.from_file(operation_dir + os.sep + 'POSCAR_final_{}.vasp'.format(i)) w = CifWriter(p.structure) w.write_file(operation_dir + os.sep + 'POSCAR_final_{}.cif'.format(i)) # st = pychemia.code.vasp.read_poscar(operation_dir+os.sep+'POSCAR_final_{}.vasp'.format(i)) #rf = open("testing") #rf.write("reading succesful") #rf.close() # pychemia.io.cif.save(structure=st,filename=operation_dir+os.sep+'POSCAR_final_{}.xyz'.format(i)) except: #redirect(url_for("error",_id="matching",stamp=stamp)) return ("Error") return redirect(url_for('result', stamp=stamp)) return render_template("matching.html", _id="matching", test_var="test", stamp=stamp)