def collect_data(self, entry_id, workdir): if os.path.isfile(workdir + '/OUTCAR'): vo = VaspOutput(workdir + '/OUTCAR') if 'energy' in vo.final_data: if 'free_energy' in vo.final_data['energy']: energy = vo.final_data['energy']['free_energy'] print('Uploading energy data for %s' % entry_id) self.set_in_properties(entry_id, 'energy', energy) return True else: return False else: return False else: return False
def update(self, workdir): """ This routine determines how to proceed with the relaxation for one specific work directory :param workdir: (str) String representation of the id in the mongodb :return: """ # workdir = self.basedir + os.sep + entry_id entry_id = os.path.basename(workdir) vj = self.vasp_jobs[entry_id] runj = self.runs[entry_id] if os.path.isfile(workdir + os.sep + 'OUTCAR'): vj.get_outputs() self.update_history(entry_id) if os.path.isfile(workdir + os.sep + 'RELAXED'): self.add_status(entry_id, 'RELAXED') elif not os.path.isfile(workdir + os.sep + 'PROCAR'): self.add_status(entry_id, 'NOPROCAR') else: self.del_status(entry_id, 'NOPROCAR') if not os.path.isfile(workdir + os.sep + 'OUTCAR'): self.add_status(entry_id, 'NOOUTCAR') else: self.del_status(entry_id, 'NOOUTCAR') print('-') vo = VaspOutput(workdir + os.sep + 'OUTCAR') relaxation_info = vo.relaxation_info() if len(relaxation_info) != 3: print('[' + str(entry_id) + ']' + ' Missing some data in OUTCAR (forces or stress)') self.add_status(entry_id, 'NOOUTCAR') print('[' + str(entry_id) + ']' + 'Results:') for i in relaxation_info: print('[' + str(entry_id) + '] %20s %12.5e' % (i, relaxation_info[i])) # Conditions to consider the structure relaxed if relaxation_info['avg_force'] < self.target_force: if relaxation_info['avg_stress_diag'] < self.target_stress: if relaxation_info[ 'avg_stress_non_diag'] < self.target_stress: wf = open(workdir + os.sep + 'RELAXED', 'w') for i in relaxation_info: wf.write("%15s %12.3f" % (i, relaxation_info[i])) wf.close() wf = open(workdir + os.sep + 'COMPLETE', 'w') for i in relaxation_info: wf.write("%15s %12.3f" % (i, relaxation_info[i])) wf.close() self.add_status(entry_id, 'RELAXED') if self.modify_input(entry_id): # How to change ISIF if relaxation_info['avg_force'] < 0.1: if relaxation_info['avg_stress_diag'] < 0.1: if relaxation_info['avg_stress_non_diag'] < 0.1: vj.input_variables.variables['ISIF'] = 3 else: vj.input_variables.variables['ISIF'] = 3 else: vj.input_variables.variables['ISIF'] = 3 else: vj.input_variables.variables['ISIF'] = 2 # How to change IBRION # if info['avg_force'] < 0.1 and info['avg_stress_diag'] < 0.1 and info['avg_stress_non_diag'] < 0.1: # vj.input_variables.variables['IBRION'] = 1 # elif info['avg_force'] < 1 and info['avg_stress_diag'] < 1 and info['avg_stress_non_diag'] < 1: # vj.input_variables.variables['IBRION'] = 2 # else: # vj.input_variables.variables['IBRION'] = 3 # How to change EDIFF if vj.input_variables.variables['EDIFF'] > 2 * 1E-4: vj.input_variables.variables['EDIFF'] = round_small( vj.input_variables.variables['EDIFF'] / 2) else: vj.input_variables.variables['EDIFF'] = 1E-4 # How to change EDIFFG if vj.input_variables.variables['EDIFFG'] < -2 * self.target_force: vj.input_variables.variables['EDIFFG'] = round_small( vj.input_variables.variables['EDIFFG'] / 2) else: vj.input_variables.variables['EDIFFG'] = -self.target_force # Print new values print('[' + str(entry_id) + ']' + 'New Values:') for i in ['ISIF', 'IBRION', 'EDIFF', 'EDIFFG']: print('[' + str(entry_id) + ']' + i + ' : ', vj.input_variables.variables[i]) print('-') for i in ['OUTCAR']: if not os.path.exists(workdir + os.sep + i): wf = open(workdir + os.sep + i, 'w') wf.write('') wf.close() log = logging.handlers.RotatingFileHandler(workdir + os.sep + i, maxBytes=1, backupCount=1000) log.doRollover() try: vj.structure = read_poscar(workdir + os.sep + 'CONTCAR') except ValueError: print('Error reading CONTCAR') vj.set_inputs() properties = vj.outcar status = self.status[entry_id] newentry = self.population.db.update(entry_id, structure=vj.structure, properties=properties, status=status) vj.save_json(workdir + os.sep + 'vaspjob.json') wf = open(workdir + os.sep + 'entry.json', 'w') json.dump(newentry, wf, sort_keys=True, indent=4, separators=(',', ': ')) wf.close() return True else: vj.set_inputs() status = self.status[entry_id] newentry = self.population.db.update(entry_id, structure=vj.structure, status=status) vj.save_json(workdir + os.sep + 'vaspjob.json') wf = open(workdir + os.sep + 'entry.json', 'w') json.dump(newentry, wf, sort_keys=True, indent=4, separators=(',', ': ')) wf.close() return True