def get_zr_range(st, thickness, zr): red_thick = thickness/np.linalg.norm(st.rprimd[2]) # z_range = [z2 - thickness, z2] zr_range = [zr - red_thick, zr] printlog('zr_range is ', zr_range) return zr_range
def suf_en(cl1, cl2, silent=0): """Calculate surface energy cl1 - supercell with surface cl2 - comensurate bulk supercell the area is determined from r[0] and r[1];- i.e they lie in surface """ st1 = cl1.end st2 = cl2.end # pm = st1.convert2pymatgen(oxidation = {'Y':'Y3+', 'Ba':'Ba2+', 'Co':'Co2.25+', 'O':'O2-'}) A = np.linalg.norm(np.cross(st1.rprimd[0], st1.rprimd[1])) # print(A) if st1.natom % st2.natom > 0: printlog( 'Warning! non-stoichiometric slab, check system sizes: natom1 = ', st1.natom, 'natom2 = ', st2.natom, st1.natom / st2.natom) mul = st1.natom / st2.natom gamma = (cl1.e0 - cl2.e0 * mul) / 2 / A * header.eV_A_to_J_m if not silent: print('Surface energy = {:3.2f} J/m2 | {:} | {:} '.format( gamma, cl1.id, cl2.id)) return gamma
def gunzip_file(filename): printlog('unzipping file', filename) with open(filename.replace('.gz', ''), 'wb') as f_out: with gzip.open(filename, 'rb') as f_in: shutil.copyfileobj(f_in, f_out) return
def file_exists_on_server(file, addr): file = file.replace('\\', '/') # make sure is POSIX printlog('Checking existence of file', file, 'on server', addr) exist = run_on_server(' ls ' + file, addr) # if header.ssh_object: # exist = header.ssh_object.fexists(file) # else: # exist = runBash('ssh '+addr+' ls '+file) if 'No such file' in exist: exist = '' else: exist = 'file exists' if exist: res = True else: res = False printlog('File exist? ', res) return res
def set_potential(self, znucl, arg=''): # print arg if not arg: arg = header.PATH2POTENTIALS + '/' + invert(znucl) printlog('Attention!, Default potentials is chosen from ', header.PATH2POTENTIALS, 'for', invert(znucl), imp='Y') if type(arg) not in (str, ): # sys.exit("\nset_potential error\n") raise RuntimeError if znucl in self.potdir: if arg == self.potdir[znucl]: print_and_log( "Warning! You already have the same potential for " + str(znucl) + " element\n") # print type(self.potdir) self.potdir[znucl] = arg self.history += "Potential for " + str( znucl) + " was changed to " + arg + "\n" print_and_log("Potential for " + str(znucl) + " was changed to " + arg + "\n") # self.update() return
def write_occmatrix(occs, folder): #create OCCMATRIX makedir(folder) printlog('I create OCCMATRIX in ', folder, imp='y') filename = folder + '/OCCMATRIX' with open(filename, 'w', newline='') as f: numat = len(occs) f.write(str(numat) + ' #num of atoms to be specified\n') at_nums = occs.keys() at_spin = [] # # 2 or 1 at_ltyp = [] # l - orbital type, 1 - s, 2 - d, 3 - f for key in occs: occ = occs[key] if len(occ) == 10: # spin polarized, d orbital at_spin.append(2) at_ltyp.append(2) else: raise RuntimeError # please write by yourself for other cases for i, l, s in zip(at_nums, at_spin, at_ltyp): f.write(list2string([i + 1, l, s]) + ' #i, l, s\n') # for sp in range(s): f.write('spin 1\n') for row in occs[i][0:len(occs[i]) // s]: f.write(list2string(row) + '\n') if s == 2: f.write('spin 2\n') for row in occs[i][len(occs[i]) // s:]: f.write(list2string(row) + '\n') f.write('\n') return filename
def insert_atom( st, el, i_void=None, r_imp=1.6, ): """Simple Wrapper for inserting atoms """ r_impurity = r_imp st_pores, sums, avds = determine_voids(st, r_impurity) insert_positions = determine_unique_voids(st_pores, sums, avds) printlog('To continue please choose *i_void* from the list above', imp='y') if i_void == None: sys.exit() # st.name = st.name.split('+')[0] xc = insert_positions[i_void] st_new, i_add = st.add_atoms([xc], el, return_ins=True) st_new.name += '+' + el + str(i_void) st_new.des += ';Atom ' + el + ' added to ' + str(xc) printlog(st.des, imp='y') st_new.write_xyz() st_new.magmom = [None] return st_new, i_add
def printme(self): for key in self.vasp_params: if self.vasp_params[key] == None: continue print_and_log( "{:30s} = {:s} ".format("s.vasp_params['"+key+"']", str(self.vasp_params[key]) ), imp = 'Y', end = '\n' ) printlog('ngkpt:', self.ngkpt, imp = 'Y') printlog('POTDIR:', self.potdir, imp = 'Y', end = '\n' )
def vasp_step(v, msg, rm=0): printlog('Calculating ' + msg + ' point!\n', imp='y') copyfile(str(v) + '.POSCAR', 'POSCAR') cl = vasp_run(3, msg, vasprun_command=vasprun_command) copy_vasp_files(v) if rm: runBash('rm CHGCAR CHG WAVECAR') return cl
def chgsum(cll, el, site, silent=1): """ calculate sum of Bader charges for particular atoms """ for cl in cll: # print(cl.id, end = ' ') try: cl.chgsum[(el, site)] = 0 except: pass if not hasattr(cl, 'charges') or len(cl.charges) == 0: cl.get_bader_ACF() # determine_symmetry_positions(cl.end, el, silent = 0) # print('') try: pos = determine_symmetry_positions(cll[0].end, el, silent=1) except: printlog('chgsum() Warning!', cll[0].id, 'is broken!') return 0 for p in pos[site]: '' for cl in cll: if not hasattr(cl, 'chgsum'): cl.chgsum = {} cl.chgsum[(el, site)] = 0 cl.chgsum[(el, site)] += cl.charges[p] # print('{:5.3f}'.format(cl.charges[p]), end = ' ') # print('') if not silent: print('Sum of charges for ', el + str(site + 1), ':') el_ind = cl.init.znucl.index( invert(el)) # index of element in znucl and zval and nznucl zval = cl.init.zval[el_ind] # number of electrons in chosen potential for cl in cll: cl.chgsum[(el, site)] /= len(pos[site]) chgsum = zval - cl.chgsum[(el, site)] if cl == cll[0]: chgsum_ref = chgsum if not silent: print('{:5.2f}({:4.2f})'.format(chgsum, chgsum_ref - chgsum), ) if not silent: print('\n') # print(cl.charges) return chgsum
def setting_sshpass(cl): if hasattr(cl , 'cluster'): # print(cl.cluster) # clust = header.CLUSTERS[cl.cluster] if 'sshpass' in cl.cluster and cl.cluster['sshpass']: printlog('setting sshpass to True', imp = '') # sys.exit() header.sshpass = cl.cluster['sshpass'] else: header.sshpass = None
def makedir(path): """ *path* - path to some file Make dirname(path) directory if it does not exist """ dirname = os.path.dirname(path) if dirname and not os.path.exists(dirname): os.makedirs(dirname) printlog("Directory", dirname, " was created", imp = 'y') return
def set_ngkpt(self,arg): if not is_list_like(arg): printlog("Error! set_ngkpt type error") old = copy.copy(self.ngkpt) self.ngkpt = copy.copy(arg) self.kpoints_file = True self.vasp_params['KSPACING'] = None if old == arg: print_and_log( "Warning! You did not change one of your parameters in new set", imp = 'y') return self.history += "ngkpt was changed from "+str(old)+" to "+str(arg) + " and KPOINTS file was swithed on\n" return
def run_on_server(command, addr = None): printlog('Running', command, 'on server ...') command = command.replace('\\', '/') # make sure is POSIX # sys.exit() # print(header.sshpass) # sys.exit() if addr is None: addr = header.cluster_address if header.ssh_object: # printlog('Using paramiko ...', imp = 'y') # if 'ne' in header.warnings: # sys.exit() out = header.ssh_object.run(command, noerror = True, printout = 'ne' in header.warnings) elif header.sshpass and header.sshpass == 'proxy': com = 'ssh -tt sdv sshpass -f '+ header.path2pass +' ssh '+addr+' "'+command+'"' # print(com) # sys.exit() out = runBash(com) # print(out) out = out.split('Connection to')[0] # remove last message Connection to ipaddress closed # sys.exit() elif header.sshpass: com = 'sshpass -f '+header.path2pass+' ssh '+addr+' "'+command+'"' # print(com) # sys.exit() out = runBash(com) # sys.exit() else: bash_comm = 'ssh '+addr+' "'+command+'"' # print(bash_comm) # sys.exit() out = runBash(bash_comm) out = out.split('#')[-1].strip() printlog(out) # print(out) # sys.exit() return out
def update_var(st): if st.natom != len(st.xred) != len(st.xcart) != len(st.typat) or len( st.znucl) != max(st.typat): printlog("Error! write_xyz: check your arrays.\n\n") if st.xcart == [] or len(st.xcart) != len(st.xred): printlog( "Warining! write_xyz: len(xcart) != len(xred) making xcart from xred.\n" ) st.xcart = xred2xcart(st.xred, st.rprimd) #print xcart[1] return st.rprimd, st.xcart, st.xred, st.typat, st.znucl, len(st.xred)
def vasp_run(n, des): #allows to run vasp several times, here fireworks can be used #n - number of attempts #des - description of run for i in range(n): # max three attempts out = runBash(vasprun_command) printlog(des, 'attempt', i, 'out is', out) cl = CalculationVasp(output='OUTCAR') out = cl.read_results(show='fo') printlog('Results are', imp='y') printlog(out, imp='y') status = check(cl) if status == 0: break else: if os.path.exists('CONTCAR'): copyfile('CONTCAR', 'POSCAR') else: printlog( 'No CONTCAR was found. No further attempts to run VASP', imp='y') break return cl
def inherit_iset(ise_new, ise_from, varset, override=False, newblockfolder=None): """ Create new set copying from existing and update some fields. If ise_from does not exist create new""" ise_new = ise_new.strip() ise_from = ise_from.strip() if ise_from not in varset: printlog("\nWarning! Set " + ise_from + " does not exist. I return new empty set\n") return InputSet(ise_new) old = varset[ise_from] for key in vasp_electronic_keys + vasp_ionic_keys + vasp_other_keys: #check if new keys was added if key not in old.vasp_params: old.vasp_params[key] = None if override: print_and_log("\nAttention! You have chosen to override set " + ise_new + "\n") elif ise_new in varset: print_and_log( "\nSet " + ise_new + " already exists. I return it without changes. Be carefull not to spoil it\n" ) return varset[ise_new] new = copy.deepcopy(old) new.ise = ise_new new.compare_with = ise_from + " " new.des = "no description for these set, see history" new.conv = {} print_and_log("New set " + ise_new + " was inherited from set " + ise_from + "\n") new.history = old.history + "\nSet " + ise_new + " was inherited from: " + ise_from + "\n" if newblockfolder: new.history += 'blockfolder changed from ' + new.blockfolder + ' to ' + newblockfolder + '\n' new.blockfolder = newblockfolder varset[ise_new] = new return new
def form_en(sources, products, norm_el=None): """ Calculate formation energy of reaction. sources, products - list of tuples (x, cl), where x is multiplier and cl is calculation norm_el - which element to use for normalization 'all' - normalize by total number of atoms 'el' - normalize by this element int - divide by this number """ El = [] Nzl = [] for ls in [sources, products]: E = 0 Nz = {} for x, cl in ls: E += x * cl.e0 for i, z in enumerate(cl.end.znucl): if z not in Nz: Nz[z] = 0 Nz[z] += x * cl.end.nznucl[i] El.append(E) Nzl.append(Nz) for z in Nzl[0]: if abs(Nzl[0][z] - Nzl[1][z]) > 1e-5: printlog('Error! Number of', invert(z), 'atoms in source and product are different!') # norm = 1 if 'all' == norm_el: norm = sum(Nzl[0].values()) elif type(norm_el) == str: norm = Nzl[0][invert(norm_el)] elif norm_el != None: norm = norm_el else: norm = 1 print('Normalizing by ', norm_el, norm, 'atoms') dE = (El[1] - El[0]) / norm print('dE = {:4.2f} eV'.format(dE)) return dE
def makedir(path, renew_folder=False): """ *path* - path to some file Make dirname(path) directory if it does not exist """ import shutil as S dirname = os.path.dirname(path) if renew_folder and os.path.exists(dirname): S.rmtree(path) else: pass if dirname and not os.path.exists(dirname): os.makedirs(dirname) printlog("Directory", dirname, " was created", imp = 'y') return
def download(file, to_file): # print(header.sshpass) if header.ssh_object: exist = file_exists_on_server(file, addr) # try: if exist: printlog('Using paramiko: ssh_object.get(): from to ', file, to_file) header.ssh_object.get(file, to_file ) out = '' # except FileNotFoundError: else: out = 'error, file not found' elif header.sshpass and header.sshpass == 'proxy': # com = 'ssh sdv "sshpass -f ~/.ssh/p ssh ' + addr + ' \\"tar zcf - '+ file +'\\"" | tar zxf - '+to_file # does not work? com = 'ssh sdv "sshpass -f ~/.ssh/p ssh ' + addr + ' \\"tar cf - '+ file +'\\"" > '+to_file # print('sshpass',com) # sys.exit() out = runBash(com) elif header.sshpass: #com = 'rsync --rsh='+"'sshpass -f /home/aksenov/.ssh/p ssh' " +' -uaz '+addr+':'+file+ ' '+to_file com = 'rsync --rsh='+"'sshpass -f "+header.path2pass+" ssh' " +' -uaz '+addr+':'+file+ ' '+to_file out = runBash(com) # print(addr) # sys.exit() else: # print(addr,file,to_file) out = runBash('rsync -uaz '+addr+':'+file+ ' '+to_file) if 'error' in out: res = out else: res = 'OK' out = '' printlog('Download result is ', res) return out
def interface_en(cl, cl1, cl2, mul1=1, mul2=1, silent=0, n_intefaces=1): """ Calculate surface energy cl - slab or cell with interface cl1 - slab or cell with phase 1, usually substrate cl2 - slab or cell with phase 2, usually film mul1, mul2, - multiply cells n_intefaces - number of similar interfaces in the system Interface is assumed to be normal to R3! """ st = cl.end st1 = cl1.end st2 = cl2.end natom = st.natom natom1 = st1.natom natom2 = st2.natom A = np.linalg.norm(np.cross(st.rprimd[0], st.rprimd[1])) A1 = np.linalg.norm(np.cross(st1.rprimd[0], st1.rprimd[1])) * mul1 A2 = np.linalg.norm(np.cross(st2.rprimd[0], st2.rprimd[1])) * mul2 print('Sets are {:} {:} {:}'.format(cl.id[1], cl1.id[1], cl2.id[1])) print('Max forces are {:.1f} {:.1f} {:.1f} meV/A'.format( cl.maxforce, cl1.maxforce, cl2.maxforce)) print('Surface areas: {:.1f} {:.1f} {:.1f} A^2'.format(A, A1, A2)) mul = natom / (natom1 * mul1 + natom2 * mul2 ) # natom1 and natom2 should be scaled equally # print(mul) if natom != (natom1 * mul1 + natom2 * mul2) * mul: printlog('Error! Number of atoms are different:', st.natom, st1.natom, st2.natom) diff = cl.e0 - (cl1.e0 * mul1 + cl2.e0 * mul2) * mul gamma = diff / A * header.eV_A_to_J_m / n_intefaces # inteface if not silent: print('Interface energy = {:3.2f} J/m2 | {:3.2f} eV '.format( gamma, diff)) return gamma
def setting_sshpass(cl=None, clust=None): """ Creates some variables for sshpass mode cl (Caluculation) - object, should contain cluster dict, has higher priority clust (dict) - cluster dicts """ if cl and hasattr(cl, 'cluster'): clust = cl.cluster # print(clust.get('sshpass')) if clust and clust.get('sshpass') is True: printlog('setting sshpass to True', imp='') header.sshpass = clust['sshpass'] header.path2pass = clust.get('path2pass') else: header.sshpass = None header.path2pass = None
def check_output(filename, check_string, load): """ Check if file exist and it is finished by search for check_string """ if filename and os.path.exists(filename): out = grep_file(check_string, filename, reverse = True) printlog('The grep result of',filename, 'is:', out) # sys.exit() if check_string in out or 'un' in load: state = '4. Finished' else: state = '5. Broken outcar' else: state = '5. no OUTCAR' return state
def cal_chg_diff(cl1, cl2, wcell, chg = 'CHGCAR'): """1. Calculate differences of charge densities Works on local computer wcell = 0 or 1 - which cell to use to show chg (str) - which file to use CHGCAR - the name as outcar if not exist CHG is used PARCHG - partial charge, the name without any additions TO DO: instead of paths to files, work with objects d = d(cl1) - d(cl2) d is calculated on server """ files = [] for cl in cl1, cl2: if chg == 'CHGCAR': file = cl.get_chg_file(nametype = 'asoutcar') if not file: printlog('No CHGCAR for cl',cl.id[0], 'trying CHG', imp = 'Y') file = cl.get_chg_file('CHG', nametype = 'asoutcar') elif chg == 'PARCHG': file = cl.get_file('PARCHG') files.append(file) file1 = files[0] file2 = files[1] if file1 == None or file2 == None: printlog('Error!, chg not found for one cl:', file1, file2) working_dir = cl1.dir dendiff_filename = working_dir + (chg+'_'+str(cl1.id[0])+'-'+str(cl2.id[0])).replace('.', '_') printlog('Diff =', file1, '-', file2) chgarith(file1, file2, '-', dendiff_filename, wcell) printlog('Charge difference saved to', dendiff_filename, imp = 'Y') return dendiff_filename
def wrapper_cp_on_server(file, to, new_filename = None): """ tries iterativly scratch and gz """ copy_to = to copy_file = file filename = os.path.basename(file) if new_filename: app = 'with new name '+new_filename else: app = '' for s, gz in product([0,1], ['', '.gz']): printlog('scratch, gz:', s, gz) out = server_cp(copy_file+gz, to = to, gz = gz, scratch = s, new_filename = new_filename) if out == '': printlog('File', filename, 'was succesfully copied to',to, app, imp = 'y') break # else: else: printlog('Warning! File was not copied, probably it does not exist. Try using header.warnings = "neyY" for more details', imp = 'y') return
def server_cp(copy_file, to, gz = True, scratch = False, new_filename = None): if scratch: if not header.PATH2ARCHIVE: printlog('Warning! PATH2ARCHIVE is empty! Please put path archive in ~/simanrc.py or ./project_conf.py ') copy_file = header.PATH2ARCHIVE + '/' + copy_file else: copy_file = header.project_path_cluster + '/' + copy_file filename = os.path.basename(copy_file) if new_filename is None: new_filename = filename if gz: command = 'cp '+copy_file + ' ' + to +'/'+new_filename + '.gz ; gunzip -f '+ to+ '/'+new_filename+'.gz' else: command = 'cp '+copy_file + ' ' + to +'/'+new_filename printlog('Running on server', command, imp = '') if file_exists_on_server(copy_file, header.cluster_address): out = run_on_server(command, addr = header.cluster_address) printlog('Output of run_on_server', out, imp = '') else: out = 'error, file does not exist on server: '+copy_file return out
def push_to_server(files = None, to = None, addr = None): """ if header.ssh_object then use paramiko to (str) - path to remote folder ! """ if not is_list_like(files): files = [files] to = to.replace('\\', '/') # make sure is POSIX files_str = ' '.join(np.array(files )) command = ' mkdir -p {:}'.format( to ) # print('asfsadfdsf', to) printlog('push_to_server():', command, run_on_server(command, addr)) # sys.exit() printlog('push_to_server(): uploading files ', files, 'to', addr, to) if header.ssh_object: for file in files: # print(file, to) header.ssh_object.put(file, to+'/'+os.path.basename(file) ) out = '' elif header.sshpass and header.sshpass == 'proxy': com = 'tar cf - '+ files_str + ' | ssh sdv "sshpass -f ~/.ssh/p ssh '+addr+' \\"cd '+header.cluster_home+' && tar xvf -\\"" ' # print(com) # sys.exit() out = runBash(com) # print(out) # sys.exit() elif header.sshpass: # if '@' not in addr: # printlog('Error! Please provide address in the form user@address') # l = addr.split('@') # print(l) # user = l[0] # ad = l[1] # com = 'rsync --rsh='+"'sshpass -f /home/aksenov/.ssh/p ssh' " +' -uaz '+files_str+ ' '+addr+':'+to com = 'rsync --rsh='+"'sshpass -f "+header.path2pass+" ssh' " +' -uaz '+files_str+ ' '+addr+':'+to # print(com) # sys.exit() out = runBash(com) else: out = runBash('rsync -uaz '+files_str+ ' '+addr+':'+to) printlog(out) return out
def insert_atom( st, el, i_void=None, i_void_list=None, r_imp=1.6, ): """Simple Wrapper for inserting atoms i_void (int) has higher priority than i_void_list return st_new, i_add, sts_by_one st_new - all positions are filled i_add - the number of last inserted atom sts_by_one - list of structures with only one inserted atom in all found positions """ r_impurity = r_imp st_pores, sums, avds = determine_voids(st, r_impurity) insert_positions = determine_unique_voids(st_pores, sums, avds) printlog('To continue please choose *i_void* from the list above', imp='y') # st.name = st.name.split('+')[0] if i_void: i_void_list = [i_void] if i_void_list is None: i_void_list = list(range(len(insert_positions))) printlog('No i_void was provided, I insert all', imp='y') st_new = st.copy() sts_by_one = [] for i in i_void_list: xc = insert_positions[i] st_new, i_add = st_new.add_atoms([xc], el, return_ins=True) st_one, _ = st.add_atoms([xc], el, return_ins=True) st_one.name += '+' + el + str(i) sts_by_one.append(st_one) st_new.name += '+' + el + str(i) st_new.des += ';Atom ' + el + ' added to ' + str(xc) printlog(st.des, imp='y') st_new.write_poscar() st_new.magmom = [None] return st_new, i_add, sts_by_one
def check(cl, exit=0): # return 0 if ok, return 1 if failed if hasattr(cl, 'e0'): printlog('outcar is ok', imp='y') out = 0 else: printlog('outcar is broken ', imp='y') out = 1 if exit: printlog('exiting...', imp='y') sys.exit() return out
def metropolis(E1, E2, T=1): """ Metropolis algorithm """ decrease = False # energy reduction # kb = 1.3806488*10**-23 / 1.6 * 10 **19 dE = E2 - E1 printlog("metropolis(): dE is ", dE) if dE < -0.000001: printlog("dE is ", dE, "Accept!") decrease = True elif 1 > math.exp(-dE / kb / T) > random(): printlog("Accepted due to the temperature; exponent is ", math.exp(-dE / kb / T)) decrease = True else: printlog('Not accepted') return decrease