def optimize_wrapper(cl, ise, add=0, show_fit=1, params=None): #wrapper for optimization function up_res = 'up1' readfiles = 1 check_job = 1 id_res = (cl.id[0] + '.su', ise, 100) if add: add_loop(*cl.id, ise_new=ise, up='up2', calc_method='uniform_scale', scale_region=(-4, 4), input_st=cl.end, show='', run=0, inherit_option='inherit_xred', it_folder=cl.sfolder + '/scaled/', params=params) else: if show_fit: res_loop(*id_res[0:2], list(range(0 + 1, 0 + 8)) + [100], up=up_res, readfiles=readfiles, analys_type='fit_a', show='fitfo') else: res_loop(*id_res, up=up_res, show='fo', check_job=check_job)
def run_wrapper(sts, ise = None, add = 0, cl = None, suf = 'w', it_folder = None, ngkpt = None, acc = None, ise1= None, acc2 = None, ise2 = None): """ Add Several structures """ folder = suf.replace('.', '') # print(folder) # sys.exit() if ise1 is None: ise1 = ise for i, st in enumerate(sts): itn = cl.id[0]+suf+ str(i) # del header.struct_des[itn] # continue if add: add_loop(itn, ise, 1, show = 'fo', up = 'up2', input_st = st, ngkpt = ngkpt, it_folder = cl.sfolder+'/'+folder+'/', ) # else: '' if acc: if acc2: db[itn+'.ifc', ise1, 1].run(ise2, show = 'fo', iopt = 'full_chg', add = 0, up = 'up2', ngkpt = ngkpt) else: db[itn, ise, 1].run(ise1, show = 'fo', iopt = 'full_chg', add = 0, up = 'up2', ngkpt = ngkpt) else: res_loop(itn, ise, 1, up = 'up2') return
def calc_bulk_list(data_list, spacegroup='', ise_nomag='8', ise_mag='8m', status=None, up=None, corenum=1): """ function can add or res for set of bulk calculations data_list = read_pmg_info() of some csv file ise - set of calculation. Usually use '8' for nonmag calc and '8m' for mag calc status = add or res """ spacegroup = '.' + spacegroup for i in data_list: st = get_matproj_st(i) if float(i['total_magnetization']): mag_flag = 1 ise = ise_mag else: mag_flag = 0 ise = ise_nomag if status == 'add': add_loop(i['pretty_formula'] + spacegroup, ise, 1, it_folder='bulk', input_st=st, corenum=corenum) if status == 'res': try: res_loop(i['pretty_formula'] + spacegroup, ise, 1, it_folder='bulk', up=up) except KeyError: print(i['total_magnetization'])
def run_wrapper(sts, ise=None, add=0, cl=None, suf='w', it_folder=None, cls=None, ngkpt=None, acc=None, ise1=None, acc2=None, ise2=None, params=None): """ Add Several structures params - pass to add_loop if add == 0: read results RETURN cl with lowest energy """ if params is None: params = {} folder = suf.replace('.', '') # print(folder) # sys.exit() if ise1 is None: ise1 = ise if cls is None: cls = [cl] * len(sts) energies = [] for i, st, cl_i in zip(range(len(sts)), sts, cls): itn = cl_i.id[0] + suf + str(i) # del header.struct_des[itn] # continue if add: # add_loop(itn, ise, 1, show = 'fo', up = 'up2', input_st = st, ngkpt = ngkpt, it_folder = cl.sfolder+'/'+folder+'/', **params ) # add_loop(itn, ise, 1, show='fo', up='up2', input_st=st, ngkpt=ngkpt, it_folder=cl.sfolder, **params) # else: '' if acc: if acc2: db[itn + '.ifc', ise1, 1].run(ise2, show='fo', iopt='full_chg', add=0, up='up1', ngkpt=ngkpt) cln = db[itn + '.ifc.ifc', ise2, 1] else: # db[itn, ise, 1].run(ise1, show = 'fo', iopt = 'full_chg', add = 0, up = 'up1', ngkpt = ngkpt) cln = db[itn + '.ifc', ise1, 1] cln.res(choose_outcar=0, show='fo') suf_acc = '.ifc' else: suf_acc = '' res_loop(itn, ise, 1, up='up1') cln = db[itn, ise, 1] if hasattr(cln, 'e0'): energies.append(cln.e0) for i, e in enumerate(energies): print(i, e) if not add and len(energies) > 0: i_min = energies.index(min(energies)) print('Minimum energy is for ', i_min, energies[i_min]) itn = cl.id[0] + suf + str(i_min) + suf_acc db[itn, ise, 1].res() return db[itn, ise, 1] else: return None
def make_defect(cl, el, st_type='end', option='vac', pos=None, ise=None, opt_vol=0, suf='', it_folder=None, el_rep='', pos_rep=1, pos_rep2=None, polaron_pos=None, occ_matrix=None, up=0, fit=0, outcar=None, only_read=0, Eref=0, compat1=False, add_loop_arg={}): """ Function allow to create point defects and run them previous name: make_vacancy() cl - starting Calculation st_type - starting structure of cl: 'init' or 'end' el - element to be removed or replaced option - 'vac' - make vacancy 'rep' - replace one atom with 'el_rep', 'pair' - make vacancy -Ti complex for V-Ti project pos - unique position of el if non-eqivalent atoms exist - for vac pos_rep - number of position to replace from 0 ise - new set opt_vol (bool) - optimize volume suf (str) - mannually added suffix it_folder - mannually provided it_folder up (bool) - [ 0, 1 ] update current calculation fit = 0, outcar = None, only_read = 0 - flow control as usual polaron_pos - choose polaron position occ_matrix - list of lists see format in classes compat1 - compatability with previous calculations, which were used for Na2FePO4F project Eref - reference energy for solution energy TODO: rename to ?_point_defects() """ from siman.project_funcs import e_bind if pos == None: pos = '' if polaron_pos == None: pol_suf = '' else: pol_suf = '.p' + str(polaron_pos) # polaron suffix ssuf = el + str(pos) + el_rep + pol_suf + suf if 'su' in cl.id[0] and not 'su.' in cl.id[0]: it_new = cl.id[0].replace('su', option) + ssuf else: it_new = cl.id[0] + option + ssuf if compat1: # no element in name it_new = cl.id[0].replace('su', 'vac') + str(pos) id_new, st, it_folder = prepare(it_new, opt_vol, it_folder, ise, cl, st_type, option) occfile = None if not only_read and (up or id_new not in calc): # it_new if 'vac' in option: st_del1, i_del = remove_one_atom(st, el, pos) st_vis = st.replace_atoms([i_del], 'U') st_vis.name = it_new + '_visual' st_vis.write_xyz() #possible polaron positions tr = st.get_transition_elements(fmt='z') i_tr = st.get_transition_elements(fmt='n') # dist = [] max_d = 0 i_max_d = None for i in i_tr: d1, d2 = image_distance(st.xcart[i], st.xcart[i_del], st.rprimd) # print(i+1, d1, d2) if d1 < d2: if d1 > max_d: max_d = d1 i_max_d = i if i_max_d is not None: print( 'The longest distance to transition metal in current supercell is ', max_d, 'A for atom', i_max_d + 1, st.get_elements()[i_max_d]) numb = st.nn(i_del, from_one=0, n=len(tr) + 5, only=list(set(tr)))['numbers'][1:] printlog( 'Choose polaron position starting from 1 using *polaron_pos*', imp='y') if polaron_pos: i_pol = numb[polaron_pos - 1] printlog('atom', i_pol + 1, st.get_elements()[i_pol], 'is chosen', imp='y') # print(numb) # sys.exit() #take_occupation matrices from cl print('substitution occupation matrix of atom', i_pol + 1) occ_matrices = copy.deepcopy(cl.occ_matrices) occ_matrices[i_pol] = occ_matrix # print(pd.DataFrame(cl.occ_matrices[i_pol])) occfile = write_occmatrix(occ_matrices, cl.dir + '/occ/') # print(occfile) # sys.exit() else: occfile = None elif 'rep' in option: st_del1 = st.replace_atoms([pos_rep], el_rep) print( 'Atom', str(pos_rep), st.get_elements()[pos_rep], ' replaced with', el_rep, ) print(st_del1.get_elements()[pos_rep]) st_del1.name = it_new elif 'pair' in option: st_del1 = st.replace_atoms([1], el_rep) if 'pair2' in option: st_del1 = st_del1.replace_atoms([pos_rep2], el_rep) st_del1 = remove_one_atom(st_del1, el, pos) print('Atom 1 replaced with', el, 'and atom removed') st_del1.name = it_new st_del1.write_xyz() if opt_vol: it = add_loop(it_new, ise, 1, calc_method='uniform_scale', scale_region=(-4, 4), inherit_option='inherit_xred', input_st=st_del1, it_folder=it_folder, params={'occmatrix': occfile}, **add_loop_arg) else: it = add_loop(it_new, ise, 1, input_st=st_del1, it_folder=it_folder, params={'occmatrix': occfile}, **add_loop_arg) else: if opt_vol and fit: res_loop(it_new + '.su', ise, list(range(1, 8)) + [100], analys_type='fit_a', show='fitfo', up='2', choose_outcar=outcar) else: res_loop(*id_new, up='2', choose_outcar=outcar, show='fo') # calc[it_new+'.su', ise, 100].end.jmol() cl_v = calc[id_new] if '4' not in cl.state: cl.res() if not hasattr(cl_v, 'e0'): printlog('Warning', cl_v.id, 'is bad') return calc_redox(cl_v, cl) # print(cl_v.end.vol, cl.end.vol) dE = None if option == 'vac': cl_v.res() cl.res() print('Evac = {:3.2f} eV'.format(cl_v.e0 - cl.e0 / cl.end.natom * cl_v.end.natom)) elif option == 'rep': diffE, diffV = matrix_diff(cl_v, cl) print('Esol = {:3.2f} eV'.format(diffE - Eref)) elif 'pair' in option: '' cl_bulk = cl cl_pair = cl_v it = cl.id[0] if 'V54' in it: it = it.replace('.su', '.') id_vac = (it + 'vacV', cl.id[1], 1) id_sol = (it + 'repTi', cl.id[1], 1) cl_vac = calc[id_vac] cl_sol = calc[id_sol] # print(id_vac, id_sol) # if option == 'pair': dE = e_bind(cl_bulk, cl_vac, cl_sol, cl_pair) print('Ecomplex = {:3.2f} eV'.format(dE)) # elif '2' in option: return {'dE': dE, 'N': cl_v.end.natom, 'Name': cl.id}
def create_segregation_cases(it, ise, verlist, dist_gb, gbpos=None, ise_new=None, option=None, precip_folder=None, use_init=False, precision=None): """ Written for Ti-Fe project. Allows to create segregation by substituting atoms; dist_gb - distance from gb inside which the atoms are included option = 'precip'- adding additional impurities to the already existing at gb. Please use 'precip_folder' use_init - allows to use initial structure. !Warning PBC are not used in determination of seg positions """ # hstring = ("%s #on %s"% (traceback.extract_stack(None, 2)[0][3], datetime.date.today() ) ) # try: # if hstring != header.history[-1]: header.history.append( hstring ) # except: # header.history.append( hstring ) def write_local(cl, it_new, it_new_path, el_sub, main_path): cl.version = v # it_new_path cl.name = it_new cl.des = 'Obtained from end state of ' + str( (it, ise, v) ) + ' by substitution of one atom near gb with ' + el_sub + ' impurity ' path_new_geo = it_new_path + "/" + it_new + "/" + it_new + '.imp.' + el_sub + '.' + str( cl.version) + '.' + 'geo' cl.init.name = it_new + ".init." + str(cl.version) xyzpath = it_new_path + "/" + it_new cl.path["input_geo"] = path_new_geo print(path_new_geo) cl.write_geometry("init", cl.des, override=1) write_xyz(cl.init, xyzpath) return it_new_path if 0: res_loop(it, ise, verlist, up=0) cl = header.calc[(it, ise, verlist[0])] znucl_sub = 3 #atom to be added """1. Create list of atoms near gb to substitue""" cl.gbpos = gbpos # print cl.gbpos seg_pos_list = [] # numbers of segregation positions if use_init: st = cl.init else: st = cl.end # print(st.xcart) if len(st.xcart) == 0: print( 'Warning!, xcart is empty', cl.id, ) for i, x in enumerate(st.xcart): z_cur = st.znucl[st.typat[i] - 1] print('z_cur', z_cur) if z_cur == znucl_sub: printlog('Skipping znucl_sub atom\n') continue if abs(x[0] - gbpos) < dist_gb: print('adding possible seg position') seg_pos_list.append(i) """2. Substitue""" el_sub = invert(znucl_sub) base_name = it main_path = header.struct_des[it].sfolder based_on = it + '.' + ise des_list = [] add_list = [] cl_list = [] sumr_list = [] i = 0 # print(seg_pos_list) for j, replace_atom in enumerate(seg_pos_list): # v = verlist[0] # the first version from list is used cl = calc[(it, ise, v)] cl.gbpos = gbpos new = copy.deepcopy(cl) if use_init: new.end = new.init else: new.init = new.end #replace init structure by the end structure if 1: #atom substitution !make function; see TODO if znucl_sub not in new.init.znucl: new.init.znucl.append(znucl_sub) new.init.ntypat += 1 new.init.typat[replace_atom] = new.init.ntypat else: ind = new.init.znucl.index(znucl_sub) new.init.typat[replace_atom] = ind + 1 new.init.nznucl = [] for typ in range(1, new.init.ntypat + 1): new.init.nznucl.append(new.init.typat.count(typ)) printlog("Impurity with Z=" + str(znucl_sub) + " has been substituted in " + new.name + "\n\n") it_new = base_name + el_sub + 'is' + str( i + 1) #interface substitution if option == 'precip': it_new_path = precip_folder else: it_new_path = main_path + '/' + base_name + '_segreg' #Check if configuration is unique add = 1 # for cl in cl_list: st = new.end st_replic = replic(st, (2, 2, 2)) st_replic = replic(st_replic, (2, 2, 2), -1) #replic in negative direction also sumr = local_surrounding( st.xcart[replace_atom], st_replic, n_neighbours=6) # sum of distances to surrounding atoms print("sumr", sumr) for ad_sumr in sumr_list: if abs(ad_sumr - sumr) < precision: add = 0 printlog("The void is non-equivalent; skipping\n") if add: i += 1 sumr_list.append(sumr) # cl_list.append(new) write_local(new, it_new, it_new_path, el_sub, main_path) for v in verlist[1:]: #write files; versions are scaled cl = calc[(it, ise, v)] rprimd_scaled = cl.end.rprimd new_scaled = copy.deepcopy(new) new_scaled.init.rprimd = copy.deepcopy(rprimd_scaled) new_scaled.init.xred2xcart() write_local(new_scaled, it_new, it_new_path, el_sub, main_path) #create names des_list.append( "struct_des['{0:s}'] = des('{1:s}', 'segregation configurations; made from {2:s}' )" .format(it_new, it_new_path, based_on)) add_list.append("add_loop('" + it_new + "','" + ise_new + "'," + "range(1,6)" + ", up = 'up1', it_folder = '" + it_new_path + "')") for d in des_list: print(d) for d in add_list: print(d) return
def process_modified(cl, mod_dic=None, scale_region=(-4, 4), opt_vol=1, fit=0, st_type='end', name=None, el_new=None, run=0, ise=None, it_folder=None, mode=None, add_loop_arg=None): """ inherited from create_charges - functionality is extended The utility allows to (contrlolled by mode parameter): 1) create charged cells by removing specific atoms provided in del_dic 2) replace specific atoms add_loop res_loop mode - delete remove None mod_dic - dic of configurations with atom numbers starting from 1 """ # if not del_dic: if add_loop_arg == None: add_loop_arg = {} if mod_dic == None: mod_dic = {1: 1} for key in mod_dic: mod_pos = mod_dic[key] if mode: mod_pos = [p - 1 for p in mod_pos] if mode: suf = '.' + mode[0] + str(key) else: suf = '' it_new = cl.id[0] + suf id_new, stA, it_folder = prepare(it_new, opt_vol, it_folder, ise, cl, st_type, mode) if run: if mode == 'delete': st = stA.remove_atoms(mod_pos) elif mode == 'replace': st = stA.replace_atoms(atoms_to_replace=mod_pos, el_new=el_new) else: st = stA st.name += suf st.write_xyz() # sys.exit() if opt_vol: add_loop(it_new, id_new[1], 1, calc_method='uniform_scale', scale_region=scale_region, inherit_option='inherit_xred', input_st=st, it_folder=it_folder, **add_loop_arg) else: add_loop(it_new, id_new[1], 1, input_st=st, it_folder=it_folder, **add_loop_arg) else: if 'check_job' in add_loop_arg: cj = add_loop_arg['check_job'] else: cj = None if opt_vol and fit: # res_loop(id_new[0], id_new[1], list(range(1,8))+[100], analys_type = 'fit_a', show = 'fitfo', up = '2', choose_outcar = None) res_loop(id_new[0], id_new[1], list(range(1, 8)) + [100], analys_type='fit_a', show='fitfo', up='2', choose_outcar=None, check_job=cj) else: res_loop(*id_new, up='1', choose_outcar=None, show='fo') return
def run_wrapper(sts, ise=None, add=0, cl=None, suf='w', it_folder=None, cls=None, ngkpt=None, acc=None, ise1=None, acc2=None, ise2=None, params=None): """ Add Several structures params - pass to add_loop """ if params is None: params = {} folder = suf.replace('.', '') # print(folder) # sys.exit() if ise1 is None: ise1 = ise if cls is None: cls = [cl] * len(sts) for i, st, cl in zip(range(len(sts)), sts, cls): itn = cl.id[0] + suf + str(i) # del header.struct_des[itn] # continue if add: add_loop(itn, ise, 1, show='fo', up='up2', input_st=st, ngkpt=ngkpt, it_folder=cl.sfolder + '/' + folder + '/', **params) # else: '' if acc: if acc2: db[itn + '.ifc', ise1, 1].run(ise2, show='fo', iopt='full_chg', add=0, up='up2', ngkpt=ngkpt) else: db[itn, ise, 1].run(ise1, show='fo', iopt='full_chg', add=0, up='up2', ngkpt=ngkpt) else: res_loop(itn, ise, 1, up='up2') return
def calc_suf_stoich_mat(self, ise='9sm', bulk_cl_name=None, it_folder='bulk/', status='create', suf_list=None, min_slab_size=12, only_stoich=1, corenum=4, cluster='cee', conv=1, create=1, reset_old_polar=0, reset_old_nonpolar=0, suffix=None, polar=1, nonpolar=1): from siman.header import db from siman.geo import create_surface2, stoichiometry_criteria, stoichiometry_criteria2, symmetry_criteria, calc_k_point_mesh from siman.calc_manage import add_loop, res_loop if not bulk_cl_name: bulk_cl_name = ['it', 'ise', '1'] if not suf_list: suf_list = [[1, 1, 0], [1, 1, 1]] st_bulk = db[self.bulk_cl_scale].end.get_conventional_cell() # if conv: # st_bulk = st_bulk.get_conventional_cell() st_name = '.'.join( [self.pretty_formula, self.sg_crystal_str, self.sg_symbol]) st_name = st_name.replace('/', '_') # st_bulk.printme() try: # print(self.suf) self.suf_pol.keys() except AttributeError: self.suf_pol = {} self.suf_pol_status = {} try: # print(self.suf) self.suf_nonpol.keys() except AttributeError: self.suf_nonpol = {} self.suf_nonpol_status = {} try: self.suf_pol_cl.keys() except AttributeError: self.suf_pol_cl = {} try: self.suf_nonpol_cl.keys() except AttributeError: self.suf_nonpol_cl = {} try: self.suf_en_pol.keys() except AttributeError: self.suf_en_pol = {} try: self.suf_en_nonpol.keys() except AttributeError: self.suf_en_nonpol = {} if reset_old_polar: self.suf_pol = {} self.suf_pol_status = {} self.suf_pol_cl = {} self.suf_en_pol = {} if reset_old_nonpolar: self.suf_nonpol = {} self.suf_nonpol_status = {} self.suf_nonpol_cl = {} self.suf_en_nonpol = {} ##################### create slab if status == 'create': try: for surface in suf_list: print(surface) if self.suf_pol == {} or ''.join( [str(surface[0]), str(surface[1]), str(surface[2])]) not in self.suf_pol.keys(): ###############polar if polar: print('Polar_suf') slabs_polar = create_surface2( st_bulk, miller_index=surface, min_slab_size=min_slab_size, min_vacuum_size=15, surface_i=0, symmetrize=0, lll_reduce=1, primitive=1) for sl_i in slabs_polar: st = st_bulk sl = st.update_from_pymatgen(sl_i) print(' Stoichoimetry:', stoichiometry_criteria2(st, sl), ' Eqvuivalent:', sl_i.have_equivalent_surfaces()) ############nonpolar if nonpolar: print('Nonpolar_suf') slabs_nonpolar = create_surface2( st_bulk, miller_index=surface, min_slab_size=min_slab_size, min_vacuum_size=15, surface_i=0, symmetrize=1, lll_reduce=1, primitive=1) for sl_i in slabs_nonpolar: st = st_bulk sl = st.update_from_pymatgen(sl_i) print(' Stoichoimetry:', stoichiometry_criteria2(st, sl), ' Eqvuivalent:', sl_i.have_equivalent_surfaces()) if create: ###############polar if polar: if len(slabs_polar): s_i = 0 n = 0 for sl_i in slabs_polar: st = st_bulk sl = st.update_from_pymatgen(sl_i) if stoichiometry_criteria2( st, sl ) and sl_i.have_equivalent_surfaces( ) == False: # if sl.natom < 31: suf_name = str(surface[0]) + str( surface[1]) + str( surface[2]) + '.' + str(s_i) # if self.suf_pol_status == 'Zero slabs constructed': # self.suf_pol_status = {} self.suf_pol[suf_name] = sl self.suf_pol_status[ suf_name] = 'created' n += 1 s_i += 1 print(st_name + ' Polar\n', surface, n, ' from ', len(slabs_polar), ' slabs\n', sl.natom, ' atoms\n') else: suf_name = str(surface[0]) + str( surface[1]) + str( surface[2]) + '.' + str(0) self.suf_pol_status[ suf_name] = 'Zero slabs constructed' print('\nWarning! Zero slabs constructed!\n') ###############nonpolar if nonpolar: if len(slabs_nonpolar): s_i = 0 n = 0 for sl_i in slabs_nonpolar: st = st_bulk sl = st.update_from_pymatgen(sl_i) if stoichiometry_criteria2( st, sl ) and sl_i.have_equivalent_surfaces( ) == True: # if sl.natom < 31: suf_name = str(surface[0]) + str( surface[1]) + str( surface[2]) + '.' + str(s_i) # if self.suf_nonpol_status == 'Zero slabs constructed': # self.suf_nonpol_status = {} self.suf_nonpol[suf_name] = sl self.suf_nonpol_status[ suf_name] = 'created' n += 1 s_i += 1 print(st_name + ' Nonolar\n', surface, n, ' from ', len(slabs_nonpolar), ' slabs\n', sl.natom, ' atoms\n') else: suf_name = str(surface[0]) + str( surface[1]) + str( surface[2]) + '.' + str(0) self.suf_nonpol_status[ suf_name] = 'Zero slabs constructed' print('\nWarning! Zero slabs constructed!\n') except AttributeError: self.suf_pol_status = 'Bulk calculation has some problems' self.suf_nonpol_status = 'Bulk calculation has some problems' print('\nWarning! Bulk calculation of {} has some problems!!\n'. format(st_name)) ##################### add slab calc if status == 'add': for suf_name in self.suf_pol_status.keys(): if self.suf_pol_status[suf_name] != 'Zero slabs constructed': suffix = '.polar' if self.suf_pol_status[suf_name] in ['created']: sl = self.suf_pol[suf_name] if only_stoich: if stoichiometry_criteria2(sl, st_bulk): print(sl.rprimd) ngkpt = calc_k_point_mesh(sl.rprimd, kspacing=0.2) ngkpt = ngkpt[:2] + (1, ) add_loop(st_name + '.sl.' + suf_name + suffix, ise, 1, ngkpt=ngkpt, input_st=sl, it_folder='slabs_new/' + st_name, up='up2', cluster=cluster, corenum=corenum) self.suf_pol_status[suf_name] = 'added' self.suf_pol_cl[suf_name] = '.'.join([ st_name + '.sl.' + suf_name + suffix, ise, '1' ]) else: print('Non-stoichiometric slab') else: None else: print('\nThis slab hasn\'t been created yet!\n') print(self.suf_pol_status[suf_name]) print(self.suf_nonpol_status) for suf_name in self.suf_nonpol_status.keys(): if self.suf_nonpol_status[suf_name] != 'Zero slabs constructed': suffix = '.nonpolar' if self.suf_nonpol_status[suf_name] in ['created']: sl = self.suf_nonpol[suf_name] if only_stoich: if stoichiometry_criteria2(sl, st_bulk): # print(st_name+'.sl.'+ suf_name, ise, 1, suf_name) ngkpt = calc_k_point_mesh(sl.rprimd, kspacing=0.2) ngkpt = ngkpt[:2] + (1, ) add_loop(st_name + '.sl.' + suf_name + suffix, ise, 1, ngkpt=ngkpt, input_st=sl, it_folder='slabs_new/' + st_name, up='up2', cluster=cluster, corenum=corenum) self.suf_nonpol_status[suf_name] = 'added' self.suf_nonpol_cl[suf_name] = '.'.join([ st_name + '.sl.' + suf_name + suffix, ise, '1' ]) else: print('Non-stoichiometric slab') else: None else: print('\nThis slab hasn\'t been created yet!\n') print(self.suf_nonpol_status[suf_name]) ##################### res slab calc if status == 'res': # # print('1111') print(self.suf_pol.keys(), self.suf_pol_status) suffix = '.polar' for suf_name in self.suf_pol.keys(): s_hkl = suf_name.split('.')[0] # # print(s_hkl) key = [] delta = 0 for i in range(0, 3): i += delta if s_hkl[i] != '-': key.append(int(s_hkl[i])) else: key.append(-int(s_hkl[i + 1])) delta = 1 # hkl = [int(s_hkl[0]), int(s_hkl[1]), int(s_hkl[2])] hkl = key if self.suf_pol_status[suf_name] in ['added', 'calculated' ] and hkl in suf_list: try: try: res_loop(st_name + '.sl.' + suf_name + suffix, ise, 1, up='up2') except ValueError: self.suf_pol_status[suf_name] = 'Error' self.suf_en_pol[suf_name] = 'Error' break except KeyError: break self.suf_pol_status[suf_name] = 'calculated' from siman.analysis import suf_en try: print(self.suf_pol_cl[suf_name]) except KeyError: self.suf_pol_cl[suf_name] = '.'.join( [st_name + '.sl.' + suf_name, ise, '1']) try: e = '-' if db[self.suf_pol_cl[suf_name]]: # in db.keys(): e = suf_en(db[self.suf_pol_cl[suf_name]], db[self.bulk_cl_scale]) # self.suf_en = {} try: self.suf_en_pol[suf_name] = round(float(e), 3) except ValueError: self.suf_en_pol[suf_name] = e except AttributeError: self.suf_en_pol[suf_name] = 'Error' if self.suf_pol_status == 'Zero slabs constructed': self.suf_en_pol = 'Zero slabs constructed' print(self.suf_nonpol.keys(), self.suf_nonpol_status) suffix = '.nonpolar' for suf_name in self.suf_nonpol.keys(): s_hkl = suf_name.split('.')[0] # # print(s_hkl) key = [] delta = 0 for i in range(0, 3): i += delta if s_hkl[i] != '-': key.append(int(s_hkl[i])) else: key.append(-int(s_hkl[i + 1])) delta = 1 # hkl = [int(s_hkl[0]), int(s_hkl[1]), int(s_hkl[2])] hkl = key if self.suf_nonpol_status[suf_name] in ['added', 'calculated' ] and hkl in suf_list: try: try: res_loop(st_name + '.sl.' + suf_name + suffix, ise, 1, up='up2') except ValueError: self.suf_nonpol_status[suf_name] = 'Error' self.suf_en_nonpol[suf_name] = 'Error' break except KeyError: break self.suf_nonpol_status[suf_name] = 'calculated' from siman.analysis import suf_en try: print(self.suf_nonpol_cl[suf_name]) except KeyError: self.suf_nonpol_cl[suf_name] = '.'.join( [st_name + '.sl.' + suf_name, ise, '1']) try: e = '-' if db[self.suf_nonpol_cl[suf_name]]: # in db.keys(): e = suf_en(db[self.suf_nonpol_cl[suf_name]], db[self.bulk_cl_scale]) # self.suf_en = {} try: self.suf_en_nonpol[suf_name] = round(float(e), 3) except ValueError: self.suf_en_nonpol[suf_name] = e except AttributeError: self.suf_en_nonpol[suf_name] = 'Error' if self.suf_nonpol_status == 'Zero slabs constructed': self.suf_en_nonpol = 'Zero slabs constructed'
def calc_suf_mat(self, ise='9sm', bulk_cl_name=None, it_folder='bulk/', status='create', suf_list=None, min_slab_size=12, only_stoich=1, symmetrize=True, corenum=4, cluster='cee', conv=1, create=1, reset_old=0, suffix=None): ''' ''' from siman.header import db from siman.geo import create_surface2, stoichiometry_criteria, stoichiometry_criteria2 from siman.calc_manage import add_loop, res_loop if not bulk_cl_name: bulk_cl_name = ['it', 'ise', '1'] if not suf_list: suf_list = [[1, 1, 0], [1, 1, 1]] st_bulk = db[self.bulk_cl_scale].end if conv: st_bulk = st_bulk.get_conventional_cell() st_name = '.'.join( [self.pretty_formula, self.sg_crystal_str, self.sg_symbol]) st_name = st_name.replace('/', '_') # st_bulk.printme() try: # print(self.suf) self.suf.keys() except AttributeError: self.suf = {} self.suf_status = {} try: self.suf_cl.keys() except AttributeError: self.suf_cl = {} try: self.suf_en.keys() except AttributeError: self.suf_en = {} if reset_old: self.suf = {} self.suf_status = {} self.suf_cl = {} self.suf_en = {} ##################### create slab if status == 'create': try: for surface in suf_list: print(surface) if self.suf == {} or ''.join( [str(surface[0]), str(surface[1]), str(surface[2])]) not in self.suf.keys(): slabs = create_surface2(st_bulk, miller_index=surface, min_slab_size=min_slab_size, min_vacuum_size=15, surface_i=0, symmetrize=symmetrize, lll_reduce=1, primitive=1) for sl_i in slabs: st = st_bulk sl = st.update_from_pymatgen(sl_i) stoichiometry_criteria2(st, sl) s_i = 0 if create: if len(slabs): for sl_i in slabs: st = st_bulk sl = st.update_from_pymatgen(sl_i) stoichiometry_criteria2(st, sl) suf_name = str(surface[0]) + str( surface[1]) + str( surface[2]) + '.' + str(s_i) if self.suf_status == 'Zero slabs constructed': self.suf_status = {} self.suf[suf_name] = sl self.suf_status[suf_name] = 'created' print(st_name + '\n', surface, s_i + 1, ' from ', len(slabs), ' slabs\n', sl.natom, ' atoms') s_i += 1 else: self.suf_status = 'Zero slabs constructed' print('\nWarning! Zero slabs constructed!\n') except AttributeError: self.suf_status = 'Bulk calculation has some problems' print('\nWarning! Bulk calculation of {} has some problems!!\n'. format(st_name)) ##################### add slab calc if status == 'add': # for surface in suf_list: for suf_name in self.suf_status.keys(): if self.suf_status[suf_name] in ['created']: sl = self.suf[suf_name] if only_stoich: if stoichiometry_criteria2(sl, st_bulk): # print(st_name+'.sl.'+ suf_name, ise, 1, suf_name) add_loop(st_name + '.sl.' + suf_name + suffix, ise, 1, input_st=sl, it_folder='slabs_new/' + st_name, up='up2', cluster=cluster, corenum=corenum) self.suf_status[suf_name] = 'added' self.suf_cl[suf_name] = '.'.join( [st_name + '.sl.' + suf_name, ise, '1']) else: print('Non-stoichiometric slab') else: None else: print('\nThis slab hasn\'t been created yet!\n') print(self.suf_status[suf_name]) ##################### res slab calc if status == 'res': # print('1111') print(self.suf.keys(), self.suf_status) for suf_name in self.suf.keys(): s_hkl = suf_name.split('.')[0] # print(s_hkl) key = [] delta = 0 for i in range(0, 3): i += delta if s_hkl[i] != '-': key.append(int(s_hkl[i])) else: key.append(-int(s_hkl[i + 1])) delta = 1 # hkl = [int(s_hkl[0]), int(s_hkl[1]), int(s_hkl[2])] hkl = key if self.suf_status[suf_name] in ['added', 'calculated' ] and hkl in suf_list: try: try: res_loop(st_name + '.sl.' + suf_name + suffix, ise, 1, up='up2') except ValueError: self.suf_status[suf_name] = 'Error' self.suf_en[suf_name] = 'Error' break except KeyError: break self.suf_status[suf_name] = 'calculated' from siman.analysis import suf_en try: print(self.suf_cl[suf_name]) except KeyError: self.suf_cl[suf_name] = '.'.join( [st_name + '.sl.' + suf_name, ise, '1']) try: e = '-' if self.suf_cl[suf_name] in db.keys(): e = suf_en(db[self.suf_cl[suf_name]], db[self.bulk_cl_scale]) # self.suf_en = {} self.suf_en[suf_name] = e except AttributeError: self.suf_en[suf_name] = 'Error' if self.suf_status == 'Zero slabs constructed': self.suf_en = 'Zero slabs constructed' return
def calc_suf_list_sg(data_list, sg, suf_list, flag=0): """ to run a set of slabs for every str from matproj data_list sg - 'spacegroup.symbol' """ # print('start') for i in data_list: if i['spacegroup.symbol'] == sg: print(i['spacegroup.symbol']) st_name = i['pretty_formula'] + '.' + i['spacegroup.crystal_system'] print(st_name) if float(i['total_magnetization']): mag_flag = 1 ise = '9sm' st_bulk = db[st_name, '8m', 1].end else: mag_flag = 0 ise = '9s' st_bulk = db[st_name, '8', 1].end try: for surface in suf_list: slabs = create_surface2(st_bulk, miller_index=surface, min_slab_size=10, min_vacuum_size=10, surface_i=0, symmetrize=True) s_i = 0 if len(slabs): for sl_i in slabs: st = st_bulk sl = st.update_from_pymatgen(sl_i) if stoichiometry_criteria(sl, st_bulk): if flag == 'add': add_loop( st_name + '.cubic.' + i['spacegroup.symbol'] + '.' + str(surface[0]) + str(surface[1]) + str(surface[2]) + '.' + str(s_i), ise, 1, input_st=sl, it_folder='slab/' + st_name + '.cubic.' + i['spacegroup.symbol'], up='up2') elif flag == 'res': res_loop(st_name + '.cubic.' + i['spacegroup.symbol'] + '.' + str(surface[0]) + str(surface[1]) + str(surface[2]) + '.' + str(s_i), ise, 1, up='up2') else: print(st_name + '\n', surface, s_i + 1, ' from ', len(slabs), ' slabs\n', sl.natom, ' atoms') s_i += 1 if s_i == 3: break else: print('Non-stoichiometric slab') else: print('\nWarning! Zero slabs constructed!\n') except AttributeError: print( '\nWarning! Bulk calculation of {} has some problems!!\n'. format(st_name))