def nebef(ediffg): """ Run nebef.pl Args: ediffg (float): specified EDIFFG vlaue in VASP Returns: neb_conv (bool): True if NEB converged within EDIFFG """ ediffg = abs(ediffg) clean_files(['POSCAR']) open('nebef.dat','w').close() os.system('nebef.pl > nebef.dat') max_F = 0 if os.stat('nebef.dat').st_size == 0: raise ValueError('nebef.dat not written') with open('nebef.dat','r') as rf: for line in rf: line = line.strip() max_F_temp = np.fromstring(line,dtype=float,sep=' ')[1] if max_F_temp > max_F: max_F = max_F_temp if max_F == 0.0: neb_conv = False elif max_F <= ediffg: neb_conv = True else: neb_conv = False return neb_conv
def isif2_medacc(self): """ Run medium accuracy ISIF2 Returns: mof (ASE Atoms object): updated ASE Atoms object """ acc_levels = self.acc_levels outcar_paths = self.outcar_paths error_outcar_paths = self.error_outcar_paths spin_label = self.spin_label kpts_lo = self.kpts_dict['kpts_lo'] kpts_hi = self.kpts_dict['kpts_hi'] acc_level = acc_levels[self.run_i] calcs = self.calcs prior_results_path = os.path.join( self.results_partial_paths[self.run_i - 1], spin_label) if os.path.isfile(outcar_paths[self.run_i - 1]) and not os.path.isfile( outcar_paths[self.run_i]) and not os.path.isfile( error_outcar_paths[self.run_i]): mof = prep_new_run(self) if sum(kpts_lo) == 3 and sum(kpts_hi) > 3: clean_files(['CHGCAR', 'WAVECAR']) else: manage_restart_files(prior_results_path) pprint('Running ' + spin_label + ', ' + acc_level) mof, self.calc_swaps = mof_run(self, mof, calcs('isif2_medacc'), kpts_hi) if mof is not None and mof.calc.scf_converged and mof.calc.converged: write_success(self) else: write_errors(self, mof) elif os.path.isfile(outcar_paths[self.run_i]): pprint('COMPLETED: ' + spin_label + ', ' + acc_level) mof = prep_next_run(self) if mof is None: pprint('Skipping rest because of errors') return None return mof
def mof_run(workflow, mof, calc, kpts, images=None, force_nupdown=False): """ Run an atoms.get_potential_energy() calculation Args: workflow (class): pymofscreen.screen_phases.worfklow class mof (ASE Atoms object): ASE Atoms object for MOF calc (dict): ASE Vasp calculator kpts (list of ints): k-point grid images (int): number of NEB images force_nupdown (bool): force NUPDOWN to nearest int Returns: mof (ASE Atoms object): updated ASE Atoms object calc_swaps (list of strings): calc swaps """ nprocs = workflow.nprocs ppn = workflow.ppn calc_swaps = workflow.calc_swaps refcode = workflow.refcode stdout_file = workflow.stdout_file calc_swaps = workflow.calc_swaps gamma = workflow.kpts_dict['gamma'] if force_nupdown: init_mags = mof.get_initial_magnetic_moments() summed_mags = np.sum(np.abs(init_mags)) nupdown = int(np.round(summed_mags, 0)) calc.int_params['nupdown'] = nupdown elif workflow.nupdown is not None: calc.int_params['nupdown'] = workflow.nupdown if sum(kpts) == 3: gpt_version = True else: gpt_version = False if images is not None: neb = True calc.int_params['images'] = images else: neb = False if not neb: try: nprocs = check_nprocs(len(mof), nprocs, ppn) except: pass choose_vasp_version(gpt_version, nprocs) calc.input_params['kpts'] = kpts calc.input_params['gamma'] = gamma if calc.int_params['ncore'] is None and calc.int_params['npar'] is None: calc.int_params['ncore'] = int(ppn / 2.0) calc, calc_swaps = update_calc(calc, calc_swaps) mof.set_calculator(calc) success = False try: mof.get_potential_energy() niter = get_niter('OUTCAR') if niter < mof.calc.int_params['nsw'] and mof.calc.converged != True: raise SystemError('VASP stopped but did not die') success = True except: if not os.path.isfile('STOPCAR') and not neb: old_error_len = 0 restart_files = ['WAVECAR', 'CHGCAR'] while True: errormsg = get_error_msgs('OUTCAR', refcode, stdout_file) print(errormsg) calc, calc_swaps = update_calc_after_errors( calc, calc_swaps, errormsg) error_len = len(errormsg) if error_len == old_error_len: break clean_files(restart_files) mof = continue_mof() choose_vasp_version(gpt_version, nprocs) mof.set_calculator(calc) try: mof.get_potential_energy() niter = get_niter('OUTCAR') if (niter < mof.calc.int_params['nsw'] and mof.calc.converged != True): raise SystemError('VASP stopped but did not die') success = True except: pass old_error_len = error_len if not success: mof = None return mof, calc_swaps
def mof_bfgs_run(workflow, mof, calc, kpts, steps=100, fmax=0.05, force_nupdown=False): """ Run ASE BFGSLineSearch calculation Args: workflow (class): pymofscreen.screen_phases.worfklow class mof (ASE Atoms object): ASE Atoms object for MOF calc (dict): ASE Vasp calculator kpts (list of ints): k-point grid steps (int): maximum number of steps fmax (int): force tolerance force_nupdown (bool): force NUPDOWN to nearest int Returns: mof (ASE Atoms object): updated ASE Atoms object dyn (class): ASE dynamics class calc_swaps (list of strings): calc swaps """ nprocs = workflow.nprocs ppn = workflow.ppn calc_swaps = workflow.calc_swaps refcode = workflow.refcode stdout_file = workflow.stdout_file calc_swaps = workflow.calc_swaps gamma = workflow.kpts_dict['gamma'] if force_nupdown: init_mags = mof.get_initial_magnetic_moments() summed_mags = np.sum(np.abs(init_mags)) nupdown = int(np.round(summed_mags, 0)) calc.int_params['nupdown'] = nupdown elif workflow.nupdown is not None: calc.int_params['nupdown'] = workflow.nupdown if sum(kpts) == 3: gpt_version = True else: gpt_version = False nprocs = check_nprocs(len(mof), nprocs, ppn) choose_vasp_version(gpt_version, nprocs) calc.input_params['kpts'] = kpts calc.input_params['gamma'] = gamma if calc.int_params['ncore'] is None and calc.int_params['npar'] is None: calc.int_params['ncore'] = int(ppn / 2.0) calc, calc_swaps = update_calc(calc, calc_swaps) mof.set_calculator(calc) dyn = BFGSLineSearch(mof, trajectory='opt.traj') success = False try: dyn.run(fmax=fmax, steps=steps) success = True except: if not os.path.isfile('STOPCAR'): old_error_len = 0 restart_files = ['WAVECAR', 'CHGCAR'] while True: errormsg = get_error_msgs('OUTCAR', refcode, stdout_file) print(errormsg) calc, calc_swaps = update_calc_after_errors( calc, calc_swaps, errormsg) error_len = len(errormsg) if error_len == old_error_len: break clean_files(restart_files) mof = continue_mof() mof.set_calculator(calc) dyn = BFGSLineSearch(mof, trajectory='opt.traj') try: dyn.run(fmax=fmax, steps=steps) success = True except: pass old_error_len = error_len if not success: mof = None return mof, dyn, calc_swaps
def dimer(self): """ Run dimer Returns: mof (ASE Atoms object): updated ASE Atoms object """ acc_levels = self.acc_levels outcar_paths = self.outcar_paths error_outcar_paths = self.error_outcar_paths spin_level = self.spin_level spin_label = self.spin_label prior_spin = self.prior_spin acc_level = acc_levels[self.run_i] prior_acc_level = acc_levels[self.run_i - 1] results_partial_paths = self.results_partial_paths pwd = os.getcwd() if 'lowacc' in acc_level: kpts = self.kpts_dict['kpts_lo'] else: kpts_lo = self.kpts_dict['kpts_lo'] kpts = self.kpts_dict['kpts_hi'] calcs = self.calcs if 'neb' in prior_acc_level and prior_spin is None: prior_results_path = os.path.join( results_partial_paths[self.run_i - 1]) prior_results_file = os.path.join(prior_results_path, 'neb.tar.gz') elif 'lowacc' in acc_level and prior_spin is not None: prior_results_path = os.path.join(results_partial_paths[-1], prior_spin) prior_results_file = os.path.join(prior_results_path, 'OUTCAR') else: prior_results_file = outcar_paths[self.run_i - 1] prior_results_path = os.path.join( results_partial_paths[self.run_i - 1], spin_label) if os.path.isfile(prior_results_file) and not os.path.isfile( outcar_paths[self.run_i]) and not os.path.isfile( error_outcar_paths[self.run_i]): if 'scf_test' in prior_acc_level: mof = prep_new_run(self) manage_restart_files(prior_results_path, dimer=False) elif 'neb' in prior_acc_level and prior_spin is None: manage_restart_files(prior_results_path, neb=True) mof = neb2dim() mof = set_initial_magmoms(mof, spin_level) elif 'lowacc' in acc_level and prior_spin is not None: mof = read(prior_results_file) mof = set_initial_magmoms(mof, spin_level) manage_restart_files(prior_results_path, dimer=True, wavechg=False) else: mof = prep_new_run(self) manage_restart_files(prior_results_path, dimer=True) if 'medacc' in acc_level and sum( kpts_lo) == 3 and sum(kpts) > 3: clean_files(['CHGCAR', 'WAVECAR']) if 'highacc' in acc_level and 'large_supercell' in self.calc_swaps: self.calc_swaps.remove('large_supercell') pprint('Running ' + spin_label + ', ' + acc_level) mof, self.calc_swaps = mof_run(self, mof, calcs(acc_level), kpts) if mof is not None and mof.calc.scf_converged and mof.calc.converged: write_success(self) else: write_errors(self, mof) vtst_cleanup() elif os.path.isfile(outcar_paths[self.run_i]): pprint('COMPLETED: ' + spin_label + ', ' + acc_level) mof = prep_next_run(self) os.chdir(pwd) if mof is None: pprint('Skipping rest because of errors') return None return mof
def isif3_highacc(self): """ Run high accuracy ISIF3 Returns: mof (ASE Atoms object): updated ASE Atoms object """ acc_levels = self.acc_levels outcar_paths = self.outcar_paths error_outcar_paths = self.error_outcar_paths spin_label = self.spin_label kpts_lo = self.kpts_dict['kpts_lo'] kpts_hi = self.kpts_dict['kpts_hi'] acc_level = acc_levels[self.run_i] calcs = self.calcs prior_results_path = os.path.join( self.results_partial_paths[self.run_i - 1], spin_label) if os.path.isfile(outcar_paths[self.run_i - 1]) and not os.path.isfile( outcar_paths[self.run_i]) and not os.path.isfile( error_outcar_paths[self.run_i]): mof = prep_new_run(self) converged = False loop_i = 0 n_runs = 15 V_diff = np.inf V_cut = 0.01 V0 = mof.get_volume() if sum(kpts_lo) == 3 and sum(kpts_hi) > 3: clean_files(['CHGCAR', 'WAVECAR']) else: manage_restart_files(prior_results_path) while (not converged or V_diff > V_cut) and loop_i < n_runs: if loop_i == 10 and 'fire' not in self.calc_swaps and 'zbrent' not in self.calc_swaps: self.calc_swaps.append('fire') pprint('Running ' + spin_label + ', ' + acc_level + ': iteration ' + str(loop_i) + '/' + str(n_runs - 1)) mof, self.calc_swaps = mof_run(self, mof, calcs('isif3_highacc'), kpts_hi) if mof is None: break if loop_i > 0: converged = mof.calc.converged mof = read('OUTCAR') V = mof.get_volume() mof = continue_magmoms(mof, 'INCAR') if loop_i > 0: V_diff = np.abs((V - V0)) / V0 V0 = V loop_i += 1 if mof is not None and converged and V_diff <= V_cut and 'large_supercell' in self.calc_swaps: self.calc_swaps.append('nsw=100') self.calc_swaps.remove('large_supercell') pprint('Running ' + spin_label + ', ' + acc_level + ' (LREAL=False)') mof, self.calc_swaps = mof_run(self, mof, calcs('isif3_highacc'), kpts_hi) self.calc_swaps.remove('nsw=100') if mof is not None and mof.calc.converged: write_success(self) else: write_errors(self, mof) else: write_errors(self, mof) if mof is not None and V_diff > V_cut: pprint('^ Change in V of ' + str(V_diff) + ' percent') if 'fire' in self.calc_swaps: self.calc_swaps.remove('fire') elif os.path.isfile(outcar_paths[self.run_i]): pprint('COMPLETED: ' + spin_label + ', ' + acc_level) mof = prep_next_run(self) if mof is None: pprint('Skipping rest because of errors') return None return mof
def __init__(self, screener, cif_file, kpts_dict, spin_level, prior_spin=None, vasp_files=None): """ Initialize variables that should be used on all MOFs in a database Args: screener (class): pymofscreen.screen.screener class cif_file (string): name of CIF file kpts_dict (dict): dictionary containing kpoint and gamma information spin_level (string): name of spin level prior_spin (string): name of previous spin level (if applicable) vasp_files (list of strings): VASP files to save """ self.cif_file = cif_file self.kpts_dict = kpts_dict self.spin_level = spin_level self.acc_levels = screener.acc_levels self.spin_label = screener.spin_label if vasp_files is None: self.vasp_files = [ 'INCAR', 'POSCAR', 'KPOINTS', 'POTCAR', 'OUTCAR', 'CONTCAR', 'CHGCAR', 'WAVECAR', 'EIGENVAL' ] self.calc_swaps = [] self.run_i = 0 if '.cif' in cif_file: self.refcode = cif_file.split('.cif')[0] elif 'POSCAR_' in cif_file: self.refcode = cif_file.split('POSCAR_')[1] else: self.refcode = cif_file self.stdout_file = screener.stdout_file self.mofpath = screener.mofpath self.submit_script = screener.submit_script self.basepath = screener.basepath self.niggli = screener.niggli self.calcs = screener.calcs self.nprocs, self.ppn = get_nprocs(self.submit_script) self.nupdown = screener.nupdown clean_files(self.vasp_files + ['CHG', 'AECCAR0', 'AECCAR1', 'AECCAR2']) results_partial_paths = [] error_partial_paths = [] error_outcar_paths = [] outcar_paths = [] for acc_level in self.acc_levels: results_partial_paths.append( os.path.join(self.basepath, 'results', self.refcode, acc_level)) error_partial_paths.append( os.path.join(self.basepath, 'errors', self.refcode, acc_level)) self.results_partial_paths = results_partial_paths self.error_partial_paths = error_partial_paths for results_partial_path in results_partial_paths: outcar_paths.append( os.path.join(results_partial_path, self.spin_label, 'OUTCAR')) for error_partial_path in error_partial_paths: error_outcar_paths.append( os.path.join(error_partial_path, self.spin_label, 'OUTCAR')) self.outcar_paths = outcar_paths self.error_outcar_paths = error_outcar_paths self.prior_spin = prior_spin if prior_spin is None: self.spin1_final_mof_path = None else: self.spin1_final_mof_path = os.path.join(results_partial_paths[-1], prior_spin, 'OUTCAR')
def isif2_lowacc(self): """ Run low accuracy ISIF2 Returns: mof (ASE Atoms object): updated ASE Atoms object """ acc_levels = self.acc_levels outcar_paths = self.outcar_paths error_outcar_paths = self.error_outcar_paths spin_level = self.spin_level spin_label = self.spin_label cif_file = self.cif_file mofpath = self.mofpath prior_spin = self.prior_spin spin1_final_mof_path = self.spin1_final_mof_path kpts_lo = self.kpts_dict['kpts_lo'] acc_level = acc_levels[self.run_i] niggli = self.niggli calcs = self.calcs prior_results_path = os.path.join( self.results_partial_paths[self.run_i - 1], spin_label) if os.path.isfile(outcar_paths[self.run_i - 1]) and not os.path.isfile( outcar_paths[self.run_i]) and not os.path.isfile( error_outcar_paths[self.run_i]): if prior_spin is None: mof = cif_to_mof(os.path.join(mofpath, cif_file), niggli) else: mof = read(spin1_final_mof_path) manage_restart_files(prior_results_path) mof = set_initial_magmoms(mof, spin_level) fmax = 5.0 pprint('Running ' + spin_label + ', ' + acc_level) mof, dyn, self.calc_swaps = mof_bfgs_run(self, mof, calcs('ase_bfgs'), kpts_lo, fmax=fmax) if mof is not None and dyn: loop_i = 0 converged = False clean_files(['opt.traj']) while mof is not None and loop_i < 4 and not converged and mof.calc.scf_converged: if loop_i == 2 and 'fire' not in self.calc_swaps and 'zbrent' not in self.calc_swaps: self.calc_swaps.append('fire') mof = read('OUTCAR') mof = continue_magmoms(mof, 'INCAR') mof, self.calc_swaps = mof_run(self, mof, calcs('isif2_lowacc'), kpts_lo) if mof is None: break converged = mof.calc.converged loop_i += 1 if 'fire' in self.calc_swaps: self.calc_swaps.remove('fire') if mof is not None and mof.calc.scf_converged and mof.calc.converged: write_success(self) else: write_errors(self, mof) elif os.path.isfile(outcar_paths[self.run_i]): pprint('COMPLETED: ' + spin_label + ', ' + acc_level) mof = prep_next_run(self) if mof is None: pprint('Skipping rest because of errors') return None return mof