def convergence_check(target,be1,be2,ENCONV,PRCONV,FOCONV): path_list = [target,be1,be2] nion = int(pygrep('NION',target+'/OUTCAR',0,0).splitlines()[-1].split()[11]) # nion = int(subprocess.check_output(['grep','NION',target+'/OUTCAR']).splitlines()[-1].split()[11]) # Read energy, pressure and force ENERGY = [] PRESS = [] FORCE = [] for path in path_list: if ENCONV > 0: ENERGY.append(float(pygrep('free ',path+'/OUTCAR',0,0).splitlines()[-1].split()[4])) # ENERGY.append(float(subprocess.check_output(['grep','free ',path+'/OUTCAR']).splitlines()[-1].split()[4])) if PRCONV > 0: line = pygrep('in kB',path+'/OUTCAR',0,0).splitlines()[-1].split() # line = subprocess.check_output(['grep','in kB',path+'/OUTCAR']).splitlines()[-1].split() if len(line) == 8: PRESS.append([float(x) for x in line[2:]]) else: PRESS.append([99999.,99999.,99999.,99999.,99999.,99999.]) if FOCONV > 0: force_lines = pygrep('TOTAL-F',path+'/OUTCAR',0,nion+1).splitlines()[2:nion+2] # force_lines = subprocess.check_output(['grep','TOTAL-F',path+'/OUTCAR','-A',str(nion+1)]).splitlines()[2:nion+2] FORCE_one_sample = [] for line in force_lines: if len(line.split()) == 6: FORCE_one_sample.append([float(x) for x in line.split()[3:6]]) else: FORCE_one_sample.append([999.,999.,999.]) FORCE.append(FORCE_one_sample) converge = 0 # Convergence check for energy/atom if ENCONV > 0 and (abs(ENERGY[0]-ENERGY[1])/nion > ENCONV or abs(ENERGY[0]-ENERGY[2])/nion > ENCONV) : make_amp2_log(target,'Energy is not yet converged') return 1 sys.exit() # Convergence check for pressure if PRCONV > 0 : for i in range(6) : if abs(PRESS[0][i]-PRESS[1][i]) > PRCONV or abs(PRESS[0][i]-PRESS[2][i]) > PRCONV : # if abs(PRESS[0][i]-PRESS[1][i])/abs(PRESS[0][i]) > 0.1 or abs(PRESS[0][i]-PRESS[2][i])/abs(PRESS[0][i]) > 0.1: # make_amp2_log(target,'Pressure is not yet converged') # return 1 # sys.exit() make_amp2_log(target,'Pressure is not yet converged') return 1 sys.exit() # Convergence check for force if FOCONV > 0 : for i in range(nion): for j in range(3) : if abs(FORCE[0][i][j]-FORCE[1][i][j]) > FOCONV or abs(FORCE[0][i][j]-FORCE[2][i][j]) > FOCONV : make_amp2_log(target,'Force is not yet converged') return 1 sys.exit() return 0
def max_force(outcar_path): nion = int(pygrep('NION',outcar_path,0,0).split()[-1]) force_list = pygrep('TOTAL-FORCE',outcar_path,0,nion+1).splitlines() max_f = [0,[0,0,0]] for line in force_list[2:]: if len(line.split()) == 6: force = [float(x) for x in line.split()[3:6]] else: force = [999.,999.,999.] if dist_point(force,[0,0,0]) > max_f[0]: max_f = [dist_point(force,[0,0,0]),force] return max_f
def max_force(outcar_path): nion = int(pygrep('NION',outcar_path,0,0).split()[-1]) # nion = int(subprocess.check_output(['grep','NION',outcar_path]).split()[-1]) force_list = pygrep('TOTAL-FORCE',outcar_path,0,nion+1).splitlines() # force_list = subprocess.check_output(['grep','-A'+str(nion+1),'TOTAL-FORCE',outcar_path]).splitlines() max_f = [0,[0,0,0]] for line in force_list[2:]: if len(line.split()) == 6: force = [float(x) for x in line.split()[3:6]] else: force = [999.,999.,999.] if dist_point(force,[0,0,0]) > max_f[0]: max_f = [dist_point(force,[0,0,0]),force] return max_f
def write_conv_result(target,logfile): head = target.split('/')[-1] energy = float(pygrep('free ',target+'/OUTCAR',0,0).splitlines()[-1].split()[4]) line = pygrep('in kB',target+'/OUTCAR',0,0).splitlines()[-1].split() if len(line) == 8: press = [float(x) for x in line[2:]] else: press = [99999.,99999.,99999.,99999.,99999.,99999.] with open(logfile,'a') as log: log.write(head+': '+str(energy)+' eV') log.write('\t/ ') for ll in press: log.write(str(ll)+' ') log.write('kB\n')
def make_incar(poscar, target, src_path, max_nelm): from module_vasprun import wincar pos = open(poscar, 'r').readlines() atom_z = pos[5].split() atom_cnt = pos[6].split() nelect = 0 for j in range(len(atom_z)): pot_line = pygrep('ZVAL', target + '/INPUT0/POTCAR_GGA', 0, 0).splitlines()[j].split()[5] # pot_line = subprocess.check_output(['grep','ZVAL',target+'/INPUT0/POTCAR_GGA']).splitlines()[j].split()[5] nelect = nelect + int(atom_cnt[j]) * int(float(pot_line)) # Set maximum number of electronic steps nelm = max_nelm # if nelect > int(max_nelm/3) : # nelm = max_nelm # else : # nelm = nelect*3 # if nelm < 30: # nelm = 30 wincar(src_path + '/INCAR0', target + '/INPUT0/INCAR0', [['SYSTEM', target.split('/')[-1]], ['NELM', str(nelm)]], []) with open(target + '/INPUT0/INCAR', 'w') as out_inc: with open(target + '/INPUT0/INCAR0', 'r') as f: out_inc.write(f.read()) with open(target + '/INPUT0/U_note', 'r') as f: out_inc.write(f.read()) with open(target + '/INPUT0/spin_note', 'r') as f: out_inc.write(f.read())
def check_half_metal(target): spin = pygrep('ISPIN', target + '/OUTCAR', 0, 0).split()[2] ncl = pygrep('NONCOL', target + '/OUTCAR', 0, 0).split()[2] if not (spin == '2' and ncl == 'F'): half_metal = 0 else: [KPT, Band, nelect] = EIGEN_to_array(target + '/EIGENVAL', spin) fermi = get_fermi_level(Band, nelect, ncl) half_metal = 0 for i in range(int(spin)): metal = 0 for n in range(len(Band)): single_band = [Band[n][x][i] for x in range(len(KPT))] band_max = max(single_band) band_min = min(single_band) if band_max > fermi and band_min < fermi: metal = 1 if metal == 0: half_metal = 1 return half_metal
def plot_band_structure(spin, Band, fermi, xtic_file, xlabel_file, plot_range, target): # make band.dat make_band_dat(xtic_file, Band, spin, target) # make band.in nband = len(Band) if pyhead(target + '/Band_gap.log', 1).split()[2] == 'is': gap = 0 fermi = str(fermi) else: gap = round(float(pyhead(target + '/Band_gap.log', 1).split()[2])) fermi = pygrep('VBM', target + '/Band_gap.log', 0, 0).splitlines()[0].split()[-2] title = target.split('/')[-2] make_band_in(title, xlabel_file, fermi, gap, nband, spin, plot_range, target)
def make_incar_note(poscar, target, soc_target, u_value, magmom_def, src_path): # U-J values for LDA+U method TMU = yaml.safe_load(open(src_path + '/U_table.yaml', 'r')) if not u_value is None: if 'All' in u_value.keys(): for u_key in TMU.keys(): TMU[u_key] = u_value['All'] elif 'all' in u_value.keys(): for u_key in TMU.keys(): TMU[u_key] = u_value['all'] for u_key in u_value.keys(): TMU[u_key] = u_value[u_key] for u_key in TMU.keys(): if TMU[u_key] == 0: TMU.pop(u_key) if soc_target is None: SOC = [] else: SOC = soc_target TMd = [ 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Y', 'Zr', 'Nb', 'Mo', 'Tc', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg' ] TMf = [ 'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', 'Yb', 'Lu' ] NVAL = { 'H': 1, 'He': 0, 'Li': 1, 'Be': 2, 'B': 3, 'C': 4, 'N': 5, 'O': 6, 'F': 7, 'Ne': 0, 'Na': 1, 'Mg': 2, 'Al': 3, 'Si': 4, 'P': 5, 'S': 6, 'Cl': 7, 'Ar': 0, 'K': 1, 'Ca': 2, 'Sc': 3, 'Ti': 4, 'V': 5, 'Cr': 6, 'Mn': 7, 'Fe': 8, 'Co': 9, 'Ni': 10, 'Cu': 11, 'Zn': 2, 'Ga': 3, 'Ge': 4, 'As': 5, 'Se': 6, 'Br': 7, 'Kr': 0, 'Rb': 1, 'Sr': 2, 'Y': 3, 'Zr': 4, 'Nb': 5, 'Mo': 6, 'Tc': 7, 'Ru': 8, 'Rh': 9, 'Pd': 10, 'Ag': 11, 'Cd': 2, 'In': 3, 'Sn': 4, 'Sb': 5, 'Te': 6, 'I': 7, 'Xe': 0, 'Cs': 1, 'Ba': 2, 'La': 3, 'Ce': 4, 'Pr': 5, 'Nd': 6, 'Pm': 7, 'Sm': 8, 'Eu': 9, 'Gd': 10, 'Tb': 11, 'Dy': 12, 'Ho': 13, 'Er': 14, 'Tm': 15, 'Yb': 16, 'Lu': 17, 'Hf': 4, 'Ta': 5, 'W': 6, 'Re': 7, 'Os': 8, 'Ir': 9, 'Pt': 10, 'Au': 11, 'Hg': 12, 'Tl': 3, 'Pb': 4, 'Bi': 5, 'Po': 6, 'At': 7, 'Rn': 0, 'Ac': 3, 'Th': 4, 'Pa': 5, 'U': 6, 'Pu': 8, 'No': 16 } pos = open(poscar, 'r').readlines() atom_z = pos[5].split() atom_cnt = pos[6].split() # Check U_note for 3d transition metals u_note = "" u_val1 = "" u_val2 = "" u_on = 0 mag_on = 0 soc_on = 0 nelect = 0 for j in range(len(atom_z)): pot_line = pygrep('ZVAL', target + '/INPUT0/POTCAR_GGA', 0, 0).splitlines()[j].split()[5] # pot_line = subprocess.check_output(['grep','ZVAL',target+'/INPUT0/POTCAR_GGA']).splitlines()[j].split()[5] nelect = nelect + int(atom_cnt[j]) * int(float(pot_line)) if atom_z[j] in TMd: if atom_z[j] in TMU: if u_on == 0: u_on = 1 u_note = u_note + ' 2' u_val1 = u_val1 + ' ' + str(TMU[atom_z[j]] + 1.0) u_val2 = u_val2 + ' 1.0' else: u_note = u_note + ' -1' u_val1 = u_val1 + ' 0.0' u_val2 = u_val2 + ' 0.0' mag_on = 1 elif atom_z[j] in TMf: if atom_z[j] in TMU: u_on = 2 u_note = u_note + ' 3' u_val1 = u_val1 + ' ' + str(TMU[atom_z[j]] + 1.0) u_val2 = u_val2 + ' 1.0' else: u_note = u_note + ' -1' u_val1 = u_val1 + ' 0.0' u_val2 = u_val2 + ' 0.0' mag_on = 1 else: u_note = u_note + ' -1' u_val1 = u_val1 + ' 0.0' u_val2 = u_val2 + ' 0.0' if atom_z[j] in SOC: soc_on = 1 # Checking metallic compounds (If all components are metallic elements, we do not impose +U.) non_metal = [ 'H', 'He', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Si', 'P', 'S', 'Cl', 'Ar', 'Ge', 'As', 'Se', 'Br', 'Kr', 'Sb', 'Te', 'I', 'Xe', 'At', 'Rn' ] if not any([x in non_metal for x in atom_z]): u_on = 0 maxmix = str(2 + 2 * u_on) with open(target + '/INPUT0/U_note', 'w') as out: if not u_on == 0: out.write( '\n LDA+U calculation:\n LDAU = .TRUE. !Treat L(S)DA+U\n LDAUTYPE = 2\n' ) out.write(' LDAUL =' + u_note + '\n') out.write(' LDAUU =' + u_val1 + '\n') out.write(' LDAUJ =' + u_val2 + '\n') out.write(' LDAUPRINT = 0\n LMAXMIX = ' + maxmix + '\n\n') oxi_check = 0 # 0: no spin-polarizaton, 1: use MAGMOM, 2: no MAGMOM tot_atom = sum([int(x) for x in atom_cnt]) if mag_on == 1 and os.path.isfile(target + '/INPUT0/final.dat'): make_amp2_log(target + '/INPUT0', 'MAGMOM is set by cif file\n') with open(target + '/INPUT0/final.dat', 'r') as fin_file: final = [] for line in fin_file.readlines(): final.append(line.split()) if len(final[0]) == 3: mag = [] # [atom_oxi, atom, mag, n_mag] fin_idx = 0 for pos_idx in range(9, tot_atom + 9): if pos_idx != 9 and pos[pos_idx].split()[-1] == mag[-1][0]: mag[-1][3] = mag[-1][3] + 1 else: # if len(final[fin_idx][2]) < 2 : if len(final[fin_idx][2]) < 2 or float( final[fin_idx][2][:-1]) == 0.0: oxi_check = 2 # No oxi information break mag.append([ final[fin_idx][1], final[fin_idx][0], float(final[fin_idx][2][-1] + final[fin_idx][2][:-1]), 1 ]) # float part: number sign --> sign number fin_idx = fin_idx + 1 if oxi_check != 2: for j in range(len(mag)): if mag[j][2] > 0: mag[j][2] = NVAL[mag[j][1]] - mag[j][2] if mag[j][1] in TMd and mag[j][2] > 5 and mag[j][ 2] <= 10: mag[j][2] = 10 - mag[j][2] elif mag[j][1] in TMf and mag[j][2] > 7 and mag[j][ 2] <= 14: mag[j][2] = 14 - mag[j][2] elif (not mag[j][1] in TMd) and (not mag[j][1] in TMf): if mag[j][2] == 2: mag[j][2] = 0.0 if mag[j][2] > 0: mag[j][2] = mag[j][2] + 0.5 oxi_check = 1 else: mag[j][2] = 0.0 # write spin note for unpaired spin electrons if mag_on == 1: if not os.path.isfile(target + '/INPUT0/final.dat') or not len( final[0]) == 3 or oxi_check == 2: make_amp2_log(target + '/INPUT0', 'MAGMOM is set by magmom default value\n') oxi_check = 1 mag = [] for j in range(len(atom_z)): mag.append([atom_z[j], '', 0, atom_cnt[j]]) if atom_z[j] in TMd: mag[-1][2] = magmom_def elif atom_z[j] in TMf: mag[-1][2] = magmom_def with open(target + '/INPUT0/spin_note', 'w') as out2: if oxi_check == 1: out2.write( " Spin polarized caculation w/ initial magnetic moment:\n") out2.write(" ISPIN = 2\n MAGMOM = ") for j in range(len(mag)): out2.write( str(mag[j][3]) + "*" + str(round(mag[j][2], 2)) + " ") out2.write('\n') elif oxi_check == 2: # Manual setting part out2.write(" ISPIN = 2\n ") with open(target + '/valence_notice!', 'w') as out3: out3.write( "Unpaired spin atoms can not be clearly identified!\n") elif nelect % 2 != 0: out2.write(" Spin polarized caculation:\n") out2.write(" ISPIN = 2\n ") if soc_on == 1: out2.write("# LSORBIT = .True.\n") if u_on == 1: out2.write("# LMAXMIX = " + maxmix + "\n")