def prepare_entry(structure_type, tot_e, species): """ Prepare entries from total energy and species. Args: structure_type(str): "garnet" or "perovskite" tot_e (float): total energy in eV/f.u. species (dict): species in dictionary. Returns: ce (ComputedEntry) """ formula = spe2form(structure_type, species) composition = Composition(formula) elements = [el.name for el in composition] potcars = ["pbe %s" % CONFIG['POTCAR'][el] for el in elements] parameters = {"potcar_symbols": list(potcars), "oxide_type": 'oxide'} for el in elements: if el in LDAUU: parameters.update({"hubbards": {el: LDAUU[el]}}) ce = ComputedEntry(composition=composition, energy=0, parameters=parameters) ce.uncorrected_energy = tot_e compat = MaterialsProjectCompatibility() ce = compat.process_entry(ce) # Correction added return ce
def get_decomposed_entries(structure_type, species, oxides_table_path): """ Get decomposed entries for mix types Args:one species (dict): species in dictionary. structure_type(str): garnet or perovskite Returns: decompose entries(list): list of entries prepared from unmix garnets/perovskite decomposed from input mix garnet/perovskite """ def decomposed(specie_complex): """Decompose those have sub-dict to individual dict objects.""" for site, specie in specie_complex.items(): spe_copy = specie_complex.copy() if len(specie) > 1: for spe, amt in specie.items(): spe_copy[site] = {spe: 1} yield spe_copy decompose_entries = [] model, scaler, graph = load_model_and_scaler(structure_type, "unmix") std_formula = STD_FORMULA[structure_type] for unmix_species in decomposed(species): charge = sum([ spe.oxi_state * amt * SITE_INFO[structure_type][site]["num_atoms"] for site in SITE_INFO[structure_type].keys() for spe, amt in unmix_species[site].items() ]) if not abs(charge - 2 * std_formula['O']) < 0.1: continue formula = spe2form(structure_type, unmix_species) calc_entries = [entry for entry in CALC_ENTRIES[structure_type] if \ entry.name == Composition(formula).reduced_formula] if calc_entries: for entry in calc_entries: decompose_entries.append(entry) else: descriptors = get_descriptor(structure_type, unmix_species) with graph.as_default(): form_e = get_form_e(descriptors, model, scaler) # tot_e = get_tote(form_e * std_formula.num_atoms, unmix_species) tot_e = get_tote(structure_type, form_e * std_formula.num_atoms, unmix_species, oxides_table_path) entry = prepare_entry(structure_type, tot_e, unmix_species) compat = MaterialsProjectCompatibility() entry = compat.process_entry(entry) decompose_entries.append(entry) return decompose_entries
def get_pd(self): """ get the phase diagram object for this compound Returns: phase diagram, entry """ #make MP compatible entry from vasprun entry = self.vasprun.get_computed_entry() compat = MaterialsProjectCompatibility() entry = compat.process_entry(entry) el = [specie.symbol for specie in entry.composition.keys()] with MPRester(api_key=API_KEY) as mpr: entries = mpr.get_entries_in_chemsys(el) entries.append(entry) pd = PhaseDiagram(entries) return pd, entry
def get_pd(self): """ get the phase diagram object Returns: pd: the phase diagram object entry: entry contained in vasprun entries: all entries used to construct the phase diagram """ entry = self.vasprun.get_computed_entry() compat = MaterialsProjectCompatibility() entry = compat.process_entry(entry) el = [specie.symbol for specie in entry.composition.keys()] with MPRester(api_key="64JmsIV32c8lUaxu") as mpr: entries = mpr.get_entries_in_chemsys(el) entries.append(entry) pd = PhaseDiagram(entries) return pd, entry, entries
def calculate_phase_stability(args): #This initializes the REST adaptor. a = MPRester(args.api_key) drone = VaspToComputedEntryDrone() entry = drone.assimilate(args.directory) compat = MaterialsProjectCompatibility() entry = compat.process_entry(entry) if not entry: print "Calculation parameters are not consistent with Materials " + \ "Project parameters." sys.exit() syms = [el.symbol for el in entry.composition.elements] #This gets all entries belonging to the relevant system. entries = a.get_entries_in_chemsys(syms) entries.append(entry) #Process entries with Materials Project compatibility. entries = compat.process_entries(entries) print [e.composition.reduced_formula for e in entries]
def run_task(self, fw_spec): # import here to prevent import errors in bigger MPCollab # get the band structure and nelect from files """ prev_dir = get_loc(fw_spec['prev_vasp_dir']) vasprun_loc = zpath(os.path.join(prev_dir, 'vasprun.xml')) kpoints_loc = zpath(os.path.join(prev_dir, 'KPOINTS')) vr = Vasprun(vasprun_loc) bs = vr.get_band_structure(kpoints_filename=kpoints_loc) """ filename = get_slug( 'JOB--' + fw_spec['mpsnl'].structure.composition.reduced_formula + '--' + fw_spec['task_type']) with open(filename, 'w+') as f: f.write('') # get the band structure and nelect from DB block_part = get_block_part(fw_spec['prev_vasp_dir']) db_dir = os.environ['DB_LOC'] assert isinstance(db_dir, object) db_path = os.path.join(db_dir, 'tasks_db.json') with open(db_path) as f: creds = json.load(f) connection = MongoClient(creds['host'], creds['port']) tdb = connection[creds['database']] tdb.authenticate(creds['admin_user'], creds['admin_password']) props = { "calculations": 1, "task_id": 1, "state": 1, "pseudo_potential": 1, "run_type": 1, "is_hubbard": 1, "hubbards": 1, "unit_cell_formula": 1 } m_task = tdb.tasks.find_one({"dir_name": block_part}, props) if not m_task: time.sleep( 60) # only thing to think of is wait for DB insertion(?) m_task = tdb.tasks.find_one({"dir_name": block_part}, props) if not m_task: raise ValueError( "Could not find task with dir_name: {}".format(block_part)) if m_task['state'] != 'successful': raise ValueError( "Cannot run Boltztrap; parent job unsuccessful") nelect = m_task['calculations'][0]['input']['parameters']['NELECT'] bs_id = m_task['calculations'][0]['band_structure_fs_id'] print bs_id, type(bs_id) fs = gridfs.GridFS(tdb, 'band_structure_fs') bs_dict = json.loads(fs.get(bs_id).read()) bs_dict['structure'] = m_task['calculations'][0]['output'][ 'crystal'] bs = BandStructure.from_dict(bs_dict) print("find previous run with block_part {}".format(block_part)) print 'Band Structure found:', bool(bs) print(bs.as_dict()) print("nelect: {}".format(nelect)) # run Boltztrap doping = [] for d in [1e16, 1e17, 1e18, 1e19, 1e20]: doping.extend([1 * d, 2.5 * d, 5 * d, 7.5 * d]) doping.append(1e21) runner = BoltztrapRunner(bs, nelect, doping=doping) dir = runner.run(path_dir=os.getcwd()) # put the data in the database bta = BoltztrapAnalyzer.from_files(dir) # 8/21/15 - Anubhav removed fs_id (also see line further below, ted['boltztrap_full_fs_id'] ...) # 8/21/15 - this is to save space in MongoDB, as well as non-use of full Boltztrap output (vs rerun) """ data = bta.as_dict() data.update(get_meta_from_structure(bs._structure)) data['snlgroup_id'] = fw_spec['snlgroup_id'] data['run_tags'] = fw_spec['run_tags'] data['snl'] = fw_spec['mpsnl'] data['dir_name_full'] = dir data['dir_name'] = get_block_part(dir) data['task_id'] = m_task['task_id'] del data['hall'] # remove because it is too large and not useful fs = gridfs.GridFS(tdb, "boltztrap_full_fs") btid = fs.put(json.dumps(jsanitize(data))) """ # now for the "sanitized" data ted = bta.as_dict() del ted['seebeck'] del ted['hall'] del ted['kappa'] del ted['cond'] # ted['boltztrap_full_fs_id'] = btid ted['snlgroup_id'] = fw_spec['snlgroup_id'] ted['run_tags'] = fw_spec['run_tags'] ted['snl'] = fw_spec['mpsnl'].as_dict() ted['dir_name_full'] = dir ted['dir_name'] = get_block_part(dir) ted['task_id'] = m_task['task_id'] ted['pf_doping'] = bta.get_power_factor(output='tensor', relaxation_time=self.TAU) ted['zt_doping'] = bta.get_zt(output='tensor', relaxation_time=self.TAU, kl=self.KAPPAL) ted['pf_eigs'] = self.get_eigs(ted, 'pf_doping') ted['pf_best'] = self.get_extreme(ted, 'pf_eigs') ted['pf_best_dope18'] = self.get_extreme(ted, 'pf_eigs', max_didx=3) ted['pf_best_dope19'] = self.get_extreme(ted, 'pf_eigs', max_didx=4) ted['zt_eigs'] = self.get_eigs(ted, 'zt_doping') ted['zt_best'] = self.get_extreme(ted, 'zt_eigs') ted['zt_best_dope18'] = self.get_extreme(ted, 'zt_eigs', max_didx=3) ted['zt_best_dope19'] = self.get_extreme(ted, 'zt_eigs', max_didx=4) ted['seebeck_eigs'] = self.get_eigs(ted, 'seebeck_doping') ted['seebeck_best'] = self.get_extreme(ted, 'seebeck_eigs') ted['seebeck_best_dope18'] = self.get_extreme(ted, 'seebeck_eigs', max_didx=3) ted['seebeck_best_dope19'] = self.get_extreme(ted, 'seebeck_eigs', max_didx=4) ted['cond_eigs'] = self.get_eigs(ted, 'cond_doping') ted['cond_best'] = self.get_extreme(ted, 'cond_eigs') ted['cond_best_dope18'] = self.get_extreme(ted, 'cond_eigs', max_didx=3) ted['cond_best_dope19'] = self.get_extreme(ted, 'cond_eigs', max_didx=4) ted['kappa_eigs'] = self.get_eigs(ted, 'kappa_doping') ted['kappa_best'] = self.get_extreme(ted, 'kappa_eigs', maximize=False) ted['kappa_best_dope18'] = self.get_extreme(ted, 'kappa_eigs', maximize=False, max_didx=3) ted['kappa_best_dope19'] = self.get_extreme(ted, 'kappa_eigs', maximize=False, max_didx=4) try: from mpcollab.thermoelectrics.boltztrap_TE import BoltzSPB bzspb = BoltzSPB(ted) maxpf_p = bzspb.get_maximum_power_factor( 'p', temperature=0, tau=1E-14, ZT=False, kappal=0.5, otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', 'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu')) maxpf_n = bzspb.get_maximum_power_factor( 'n', temperature=0, tau=1E-14, ZT=False, kappal=0.5, otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', 'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu')) maxzt_p = bzspb.get_maximum_power_factor( 'p', temperature=0, tau=1E-14, ZT=True, kappal=0.5, otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', 'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu')) maxzt_n = bzspb.get_maximum_power_factor( 'n', temperature=0, tau=1E-14, ZT=True, kappal=0.5, otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', 'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu')) ted['zt_best_finemesh'] = {'p': maxzt_p, 'n': maxzt_n} ted['pf_best_finemesh'] = {'p': maxpf_p, 'n': maxpf_n} except: import traceback traceback.print_exc() print 'COULD NOT GET FINE MESH DATA' # add is_compatible mpc = MaterialsProjectCompatibility("Advanced") try: func = m_task["pseudo_potential"]["functional"] labels = m_task["pseudo_potential"]["labels"] symbols = ["{} {}".format(func, label) for label in labels] parameters = { "run_type": m_task["run_type"], "is_hubbard": m_task["is_hubbard"], "hubbards": m_task["hubbards"], "potcar_symbols": symbols } entry = ComputedEntry(Composition(m_task["unit_cell_formula"]), 0.0, 0.0, parameters=parameters, entry_id=m_task["task_id"]) ted["is_compatible"] = bool(mpc.process_entry(entry)) except: traceback.print_exc() print 'ERROR in getting compatibility, task_id: {}'.format( m_task["task_id"]) ted["is_compatible"] = None tdb.boltztrap.insert(jsanitize(ted)) update_spec = { 'prev_vasp_dir': fw_spec['prev_vasp_dir'], 'boltztrap_dir': os.getcwd(), 'prev_task_type': fw_spec['task_type'], 'mpsnl': fw_spec['mpsnl'].as_dict(), 'snlgroup_id': fw_spec['snlgroup_id'], 'run_tags': fw_spec['run_tags'], 'parameters': fw_spec.get('parameters') } return FWAction(update_spec=update_spec)
def assimilate(self, path, launches_coll=None): """ Parses vasp runs. Then insert the result into the db. and return the task_id or doc of the insertion. Returns: If in simulate_mode, the entire doc is returned for debugging purposes. Else, only the task_id of the inserted doc is returned. """ d = self.get_task_doc(path) if self.additional_fields: d.update(self.additional_fields) # always add additional fields, even for failed jobs try: d["dir_name_full"] = d["dir_name"].split(":")[1] d["dir_name"] = get_block_part(d["dir_name_full"]) d["stored_data"] = {} except: print 'COULD NOT GET DIR NAME' pprint.pprint(d) print traceback.format_exc() raise ValueError('IMPROPER PARSING OF {}'.format(path)) if not self.simulate: # Perform actual insertion into db. Because db connections cannot # be pickled, every insertion needs to create a new connection # to the db. conn = MongoClient(self.host, self.port) db = conn[self.database] if self.user: db.authenticate(self.user, self.password) coll = db[self.collection] # Insert dos data into gridfs and then remove it from the dict. # DOS data tends to be above the 4Mb limit for mongo docs. A ref # to the dos file is in the dos_fs_id. result = coll.find_one({"dir_name": d["dir_name"]}) if result is None or self.update_duplicates: if self.parse_dos and "calculations" in d: for calc in d["calculations"]: if "dos" in calc: dos = json.dumps(calc["dos"], cls=MontyEncoder) fs = gridfs.GridFS(db, "dos_fs") dosid = fs.put(dos) calc["dos_fs_id"] = dosid del calc["dos"] d["last_updated"] = datetime.datetime.today() if result is None: if ("task_id" not in d) or (not d["task_id"]): d["task_id"] = "mp-{}".format( db.counter.find_one_and_update( {"_id": "taskid"}, {"$inc": {"c": 1}} )["c"]) logger.info("Inserting {} with taskid = {}" .format(d["dir_name"], d["task_id"])) elif self.update_duplicates: d["task_id"] = result["task_id"] logger.info("Updating {} with taskid = {}" .format(d["dir_name"], d["task_id"])) #Fireworks processing self.process_fw(path, d) try: #Add oxide_type struct=Structure.from_dict(d["output"]["crystal"]) d["oxide_type"]=oxide_type(struct) except: logger.error("can't get oxide_type for {}".format(d["task_id"])) d["oxide_type"] = None #Override incorrect outcar subdocs for two step relaxations if "optimize structure" in d['task_type'] and \ os.path.exists(os.path.join(path, "relax2")): try: run_stats = {} for i in [1,2]: o_path = os.path.join(path,"relax"+str(i),"OUTCAR") o_path = o_path if os.path.exists(o_path) else o_path+".gz" outcar = Outcar(o_path) d["calculations"][i-1]["output"]["outcar"] = outcar.as_dict() run_stats["relax"+str(i)] = outcar.run_stats except: logger.error("Bad OUTCAR for {}.".format(path)) try: overall_run_stats = {} for key in ["Total CPU time used (sec)", "User time (sec)", "System time (sec)", "Elapsed time (sec)"]: overall_run_stats[key] = sum([v[key] for v in run_stats.values()]) run_stats["overall"] = overall_run_stats except: logger.error("Bad run stats for {}.".format(path)) d["run_stats"] = run_stats # add is_compatible mpc = MaterialsProjectCompatibility("Advanced") try: func = d["pseudo_potential"]["functional"] labels = d["pseudo_potential"]["labels"] symbols = ["{} {}".format(func, label) for label in labels] parameters = {"run_type": d["run_type"], "is_hubbard": d["is_hubbard"], "hubbards": d["hubbards"], "potcar_symbols": symbols} entry = ComputedEntry(Composition(d["unit_cell_formula"]), 0.0, 0.0, parameters=parameters, entry_id=d["task_id"]) d['is_compatible'] = bool(mpc.process_entry(entry)) except: traceback.print_exc() print 'ERROR in getting compatibility' d['is_compatible'] = None #task_type dependent processing if 'static' in d['task_type']: launch_doc = launches_coll.find_one({"fw_id": d['fw_id'], "launch_dir": {"$regex": d["dir_name"]}}, {"action.stored_data": 1}) for i in ["conventional_standard_structure", "symmetry_operations", "symmetry_dataset", "refined_structure"]: try: d['stored_data'][i] = launch_doc['action']['stored_data'][i] except: pass #parse band structure if necessary if ('band structure' in d['task_type'] or "Uniform" in d['task_type'])\ and d['state'] == 'successful': launch_doc = launches_coll.find_one({"fw_id": d['fw_id'], "launch_dir": {"$regex": d["dir_name"]}}, {"action.stored_data": 1}) vasp_run = Vasprun(zpath(os.path.join(path, "vasprun.xml")), parse_projected_eigen=False) if 'band structure' in d['task_type']: def string_to_numlist(stringlist): g=re.search('([0-9\-\.eE]+)\s+([0-9\-\.eE]+)\s+([0-9\-\.eE]+)', stringlist) return [float(g.group(i)) for i in range(1,4)] for i in ["kpath_name", "kpath"]: d['stored_data'][i] = launch_doc['action']['stored_data'][i] kpoints_doc = d['stored_data']['kpath']['kpoints'] for i in kpoints_doc: kpoints_doc[i]=string_to_numlist(kpoints_doc[i]) bs=vasp_run.get_band_structure(efermi=d['calculations'][0]['output']['outcar']['efermi'], line_mode=True) else: bs=vasp_run.get_band_structure(efermi=d['calculations'][0]['output']['outcar']['efermi'], line_mode=False) bs_json = json.dumps(bs.as_dict(), cls=MontyEncoder) fs = gridfs.GridFS(db, "band_structure_fs") bs_id = fs.put(bs_json) d['calculations'][0]["band_structure_fs_id"] = bs_id # also override band gap in task doc gap = bs.get_band_gap() vbm = bs.get_vbm() cbm = bs.get_cbm() update_doc = {'bandgap': gap['energy'], 'vbm': vbm['energy'], 'cbm': cbm['energy'], 'is_gap_direct': gap['direct']} d['analysis'].update(update_doc) d['calculations'][0]['output'].update(update_doc) coll.update_one({"dir_name": d["dir_name"]}, {'$set': d}, upsert=True) return d["task_id"], d else: logger.info("Skipping duplicate {}".format(d["dir_name"])) return result["task_id"], result else: d["task_id"] = 0 logger.info("Simulated insert into database for {} with task_id {}" .format(d["dir_name"], d["task_id"])) return 0, d
def assimilate(self, path, launches_coll=None): """ Parses vasp runs. Then insert the result into the db. and return the task_id or doc of the insertion. Returns: If in simulate_mode, the entire doc is returned for debugging purposes. Else, only the task_id of the inserted doc is returned. """ d = self.get_task_doc(path) if self.additional_fields: d.update(self.additional_fields ) # always add additional fields, even for failed jobs try: d["dir_name_full"] = d["dir_name"].split(":")[1] d["dir_name"] = get_block_part(d["dir_name_full"]) d["stored_data"] = {} except: print 'COULD NOT GET DIR NAME' pprint.pprint(d) print traceback.format_exc() raise ValueError('IMPROPER PARSING OF {}'.format(path)) if not self.simulate: # Perform actual insertion into db. Because db connections cannot # be pickled, every insertion needs to create a new connection # to the db. conn = MongoClient(self.host, self.port) db = conn[self.database] if self.user: db.authenticate(self.user, self.password) coll = db[self.collection] # Insert dos data into gridfs and then remove it from the dict. # DOS data tends to be above the 4Mb limit for mongo docs. A ref # to the dos file is in the dos_fs_id. result = coll.find_one({"dir_name": d["dir_name"]}) if result is None or self.update_duplicates: if self.parse_dos and "calculations" in d: for calc in d["calculations"]: if "dos" in calc: dos = json.dumps(calc["dos"], cls=MontyEncoder) fs = gridfs.GridFS(db, "dos_fs") dosid = fs.put(dos) calc["dos_fs_id"] = dosid del calc["dos"] d["last_updated"] = datetime.datetime.today() if result is None: if ("task_id" not in d) or (not d["task_id"]): d["task_id"] = "mp-{}".format( db.counter.find_one_and_update({"_id": "taskid"}, {"$inc": { "c": 1 }})["c"]) logger.info("Inserting {} with taskid = {}".format( d["dir_name"], d["task_id"])) elif self.update_duplicates: d["task_id"] = result["task_id"] logger.info("Updating {} with taskid = {}".format( d["dir_name"], d["task_id"])) #Fireworks processing self.process_fw(path, d) try: #Add oxide_type struct = Structure.from_dict(d["output"]["crystal"]) d["oxide_type"] = oxide_type(struct) except: logger.error("can't get oxide_type for {}".format( d["task_id"])) d["oxide_type"] = None #Override incorrect outcar subdocs for two step relaxations if "optimize structure" in d['task_type'] and \ os.path.exists(os.path.join(path, "relax2")): try: run_stats = {} for i in [1, 2]: o_path = os.path.join(path, "relax" + str(i), "OUTCAR") o_path = o_path if os.path.exists( o_path) else o_path + ".gz" outcar = Outcar(o_path) d["calculations"][ i - 1]["output"]["outcar"] = outcar.as_dict() run_stats["relax" + str(i)] = outcar.run_stats except: logger.error("Bad OUTCAR for {}.".format(path)) try: overall_run_stats = {} for key in [ "Total CPU time used (sec)", "User time (sec)", "System time (sec)", "Elapsed time (sec)" ]: overall_run_stats[key] = sum( [v[key] for v in run_stats.values()]) run_stats["overall"] = overall_run_stats except: logger.error("Bad run stats for {}.".format(path)) d["run_stats"] = run_stats # add is_compatible mpc = MaterialsProjectCompatibility("Advanced") try: func = d["pseudo_potential"]["functional"] labels = d["pseudo_potential"]["labels"] symbols = ["{} {}".format(func, label) for label in labels] parameters = { "run_type": d["run_type"], "is_hubbard": d["is_hubbard"], "hubbards": d["hubbards"], "potcar_symbols": symbols } entry = ComputedEntry(Composition(d["unit_cell_formula"]), 0.0, 0.0, parameters=parameters, entry_id=d["task_id"]) d['is_compatible'] = bool(mpc.process_entry(entry)) except: traceback.print_exc() print 'ERROR in getting compatibility' d['is_compatible'] = None #task_type dependent processing if 'static' in d['task_type']: launch_doc = launches_coll.find_one( { "fw_id": d['fw_id'], "launch_dir": { "$regex": d["dir_name"] } }, {"action.stored_data": 1}) for i in [ "conventional_standard_structure", "symmetry_operations", "symmetry_dataset", "refined_structure" ]: try: d['stored_data'][i] = launch_doc['action'][ 'stored_data'][i] except: pass #parse band structure if necessary if ('band structure' in d['task_type'] or "Uniform" in d['task_type'])\ and d['state'] == 'successful': launch_doc = launches_coll.find_one( { "fw_id": d['fw_id'], "launch_dir": { "$regex": d["dir_name"] } }, {"action.stored_data": 1}) vasp_run = Vasprun(zpath(os.path.join(path, "vasprun.xml")), parse_projected_eigen=True) if 'band structure' in d['task_type']: def string_to_numlist(stringlist): g = re.search( '([0-9\-\.eE]+)\s+([0-9\-\.eE]+)\s+([0-9\-\.eE]+)', stringlist) return [float(g.group(i)) for i in range(1, 4)] for i in ["kpath_name", "kpath"]: d['stored_data'][i] = launch_doc['action'][ 'stored_data'][i] kpoints_doc = d['stored_data']['kpath']['kpoints'] for i in kpoints_doc: if isinstance(kpoints_doc[i], six.string_types): kpoints_doc[i] = string_to_numlist( kpoints_doc[i]) bs = vasp_run.get_band_structure( efermi=d['calculations'][0]['output']['outcar'] ['efermi'], line_mode=True) else: bs = vasp_run.get_band_structure( efermi=d['calculations'][0]['output']['outcar'] ['efermi'], line_mode=False) bs_json = json.dumps(bs.as_dict(), cls=MontyEncoder) fs = gridfs.GridFS(db, "band_structure_fs") bs_id = fs.put(bs_json) d['calculations'][0]["band_structure_fs_id"] = bs_id # also override band gap in task doc gap = bs.get_band_gap() vbm = bs.get_vbm() cbm = bs.get_cbm() update_doc = { 'bandgap': gap['energy'], 'vbm': vbm['energy'], 'cbm': cbm['energy'], 'is_gap_direct': gap['direct'] } d['analysis'].update(update_doc) d['calculations'][0]['output'].update(update_doc) coll.update_one({"dir_name": d["dir_name"]}, {'$set': d}, upsert=True) return d["task_id"], d else: logger.info("Skipping duplicate {}".format(d["dir_name"])) return result["task_id"], result else: d["task_id"] = 0 logger.info( "Simulated insert into database for {} with task_id {}".format( d["dir_name"], d["task_id"])) return 0, d
entry for entry in all_entries if entry.composition.reduced_formula == Composition(formula).reduced_formula ] relevant_entries = sorted(relevant_entries, key=lambda e: e.energy_per_atom) return relevant_entries[0] def get_comp_entries(formula, all_entries): relevant_entries = [ entry for entry in all_entries if entry.composition.reduced_formula == Composition(formula).reduced_formula ] return relevant_entries def find_entry_index(formula, all_entries): entry_index = [ all_entries.index(entry) for entry in all_entries if entry.composition.reduced_formula == Composition( formula).reduced_formula ] return entry_index vasprun = Vasprun("vasprun.xml") entry = vasprun.get_computed_entry(inc_structure=True) compatibility = MaterialsProjectCompatibility() entry = compatibility.process_entry(entry) #entries = compatibility.process_entries([entry] + mp_entries)
def test_process_entry(self): compat = MaterialsProjectCompatibility() ggacompat = MaterialsProjectCompatibility("GGA") #Correct parameters self.assertIsNotNone(compat.process_entry(self.entry1)) self.assertIsNone(ggacompat.process_entry(self.entry1)) #Correct parameters entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': False, "hubbards": {}, 'run_type': 'GGA', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE O 08Apr2002']}) self.assertIsNone(compat.process_entry(entry)) self.assertIsNotNone(ggacompat.process_entry(entry)) entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE O 08Apr2002']}) self.assertIsNotNone(compat.process_entry(entry)) #Check actual correction self.assertAlmostEqual(compat.process_entry(entry).correction, - 2.733 * 2 - 0.70229 * 3) entry = ComputedEntry( 'FeF3', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'F': 0}, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE F 08Apr2002']}) self.assertIsNotNone(compat.process_entry(entry)) #Check actual correction self.assertAlmostEqual(compat.process_entry(entry).correction, -2.733) #Wrong U value entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.2, 'O': 0}, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE O 08Apr2002']}) self.assertIsNone(compat.process_entry(entry)) #GGA run of U entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE O 08Apr2002']}) self.assertIsNone(compat.process_entry(entry)) #GGA+U run of non-U entry = ComputedEntry( 'Al2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Al': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Al 06Sep2000', 'PAW_PBE O 08Apr2002']}) self.assertIsNone(compat.process_entry(entry)) #Materials project should not have a U for sulfides entry = ComputedEntry( 'FeS2', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'S': 0}, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE S 08Apr2002']}) self.assertIsNone(compat.process_entry(entry)) #Wrong psp entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe 06Sep2000', 'PAW_PBE O 08Apr2002']}) self.assertIsNone(compat.process_entry(entry)) #Testing processing of elements. entry = ComputedEntry( 'O', -1, 0.0, parameters={'is_hubbard': False, 'hubbards': {}, 'potcar_symbols': ['PAW_PBE O 08Apr2002'], 'run_type': 'GGA'}) entry = compat.process_entry(entry) # self.assertEqual(entry.entry_id, -8) self.assertAlmostEqual(entry.energy, -1) self.assertAlmostEqual(ggacompat.process_entry(entry).energy, -1)
class MaterialsProjectCompatibilityTest(unittest.TestCase): def setUp(self): self.entry1 = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.entry2 = ComputedEntry( 'Fe3O4', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.entry3 = ComputedEntry( 'FeO', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 4.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.compat = MaterialsProjectCompatibility(check_potcar_hash=False) self.ggacompat = MaterialsProjectCompatibility("GGA", check_potcar_hash=False) def test_process_entry(self): #Correct parameters self.assertIsNotNone(self.compat.process_entry(self.entry1)) self.assertIsNone(self.ggacompat.process_entry(self.entry1)) #Correct parameters entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': False, "hubbards": {}, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) self.assertIsNotNone(self.ggacompat.process_entry(entry)) entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNotNone(self.compat.process_entry(entry)) def test_correction_values(self): #test_corrections self.assertAlmostEqual(self.compat.process_entry(self.entry1).correction, - 2.733 * 2 - 0.70229 * 3) entry = ComputedEntry( 'FeF3', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'F': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE F 08Apr2002', 'hash': '180141c33d032bfbfff30b3bea9d23dd'}]}) self.assertIsNotNone(self.compat.process_entry(entry)) #Check actual correction self.assertAlmostEqual(self.compat.process_entry(entry).correction, -2.733) def test_U_values(self): #Wrong U value entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.2, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) #GGA run of U entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) #GGA+U run of non-U entry = ComputedEntry( 'Al2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Al': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel': 'PAW_PBE Al 06Sep2000', 'hash': '805c888bbd2793e462311f6a20d873d9'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) #Materials project should not have a U for sulfides entry = ComputedEntry( 'FeS2', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'S': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {"titel": 'PAW_PBE S 08Apr2002', 'hash': "f7f8e4a74a6cbb8d63e41f4373b54df2"}]}) self.assertIsNone(self.compat.process_entry(entry)) def test_wrong_psp(self): #Wrong psp entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe 06Sep2000', 'hash': '9530da8244e4dac17580869b4adab115'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) def test_element_processing(self): entry = ComputedEntry( 'O', -1, 0.0, parameters={'is_hubbard': False, 'hubbards': {}, 'potcar_spec': [{'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}], 'run_type': 'GGA'}) entry = self.compat.process_entry(entry) # self.assertEqual(entry.entry_id, -8) self.assertAlmostEqual(entry.energy, -1) self.assertAlmostEqual(self.ggacompat.process_entry(entry).energy, -1) def test_get_corrections_dict(self): compat = MaterialsProjectCompatibility(check_potcar_hash=False) ggacompat = MaterialsProjectCompatibility("GGA", check_potcar_hash=False) #Correct parameters entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': "7a25bc5b9a5393f46600a4939d357982"}]}) c = compat.get_corrections_dict(entry) self.assertAlmostEqual(c["MP Gas Correction"], -2.10687) self.assertAlmostEqual(c["MP Advanced Correction"], -5.466) entry.parameters["is_hubbard"] = False del entry.parameters["hubbards"] c = ggacompat.get_corrections_dict(entry) self.assertNotIn("MP Advanced Correction", c) def test_process_entries(self): entries = self.compat.process_entries([self.entry1, self.entry2, self.entry3]) self.assertEqual(len(entries), 2)
class AnalyseMaterialsProjectJsonDataWithComputedEntries(): """ Class which will wrap around boilerplate analysis of MaterialsProject-like json files, containing data extracted using borgs and queens. It will be assumed that we are providing ComputedEntries objects directly. """ def __init__(self): # some MP analysis power tools self.compat = MaterialsProjectCompatibility() return def extract_alkali_energy(self, computed_Alkali_entry ): processed_Alkali_entry = self.compat.process_entry(computed_Alkali_entry) self.E_Alkali = processed_Alkali_entry.energy return def extract_phase_diagram_info(self,MP_phase_diagram_json_data_filename): computed_entries = self._extract_MP_data(MP_phase_diagram_json_data_filename) processed_entries = self.compat.process_entries(computed_entries) pd = PhaseDiagram(processed_entries) self.phase_diagram_analyser = PDAnalyzer(pd) return def extract_processed_entries(self,computed_entries): processed_entries = self.compat.process_entries(computed_entries) return processed_entries def extract_energies_above_hull(self,computed_entries,alkali): processed_entries = self.extract_processed_entries(computed_entries) list_energy_above_hull = [] list_alkali_content = [] for entry in processed_entries: decomposition_dict, energy_above_hull = \ self.phase_diagram_analyser.get_decomp_and_e_above_hull(entry, allow_negative=True) list_energy_above_hull.append(energy_above_hull) list_alkali_content.append(entry.composition[alkali]) list_energy_above_hull = np.array(list_energy_above_hull) list_alkali_content = np.array(list_alkali_content ) return list_alkali_content, list_energy_above_hull def extract_energies(self,computed_entries,alkali): processed_entries = self.extract_processed_entries(computed_entries) list_energy = [] list_alkali_content = [] for entry in processed_entries: list_energy.append(entry.energy) list_alkali_content.append(entry.composition[alkali]) list_energy = np.array(list_energy) list_alkali_content = np.array(list_alkali_content ) I = np.argsort(list_alkali_content ) return list_alkali_content[I], list_energy[I] def _extract_MP_data(self,MP_data_filename): drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, "dummy", 1) queen.load_data(MP_data_filename) computed_entries = queen.get_data() del drone del queen return computed_entries
from pymatgen.io.vasp.outputs import Vasprun from pymatgen.entries.compatibility import MaterialsProjectCompatibility import os import glob from os import path entries=[] uncalculated=[] dirlist = glob.glob("*/") for subdir in dirlist: os.chdir(subdir) print(os.getcwd()) if path.exists('log'): with open('log') as myfile: if 'reached' in myfile.read(): compatibility = MaterialsProjectCompatibility() entry_temp=Vasprun('vasprun.xml').get_computed_entry() entry_temp = compatibility.process_entry(entry_temp) entries.append(entry_temp) else: uncalculated.append(os.getcwd()) else: uncalculated.append(os.getcwd()) os.chdir("../")
class MaterialsProjectCompatibilityTest(unittest.TestCase): def setUp(self): self.entry1 = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.entry_sulfide = ComputedEntry( 'FeS', -1, 0.0, parameters={'is_hubbard': False, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE S 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.entry2 = ComputedEntry( 'Fe3O4', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.entry3 = ComputedEntry( 'FeO', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 4.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.compat = MaterialsProjectCompatibility(check_potcar_hash=False) self.ggacompat = MaterialsProjectCompatibility("GGA", check_potcar_hash=False) def test_process_entry(self): #Correct parameters self.assertIsNotNone(self.compat.process_entry(self.entry1)) self.assertIsNone(self.ggacompat.process_entry(self.entry1)) #Correct parameters entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': False, "hubbards": {}, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) self.assertIsNotNone(self.ggacompat.process_entry(entry)) entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNotNone(self.compat.process_entry(entry)) def test_correction_values(self): #test_corrections self.assertAlmostEqual(self.compat.process_entry(self.entry1).correction, - 2.733 * 2 - 0.70229 * 3) entry = ComputedEntry( 'FeF3', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'F': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE F 08Apr2002', 'hash': '180141c33d032bfbfff30b3bea9d23dd'}]}) self.assertIsNotNone(self.compat.process_entry(entry)) #Check actual correction self.assertAlmostEqual(self.compat.process_entry(entry).correction, -2.733) self.assertAlmostEqual(self.compat.process_entry( self.entry_sulfide).correction, -0.66346) def test_U_values(self): #Wrong U value entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.2, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) #GGA run of U entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) #GGA+U run of non-U entry = ComputedEntry( 'Al2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Al': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel': 'PAW_PBE Al 06Sep2000', 'hash': '805c888bbd2793e462311f6a20d873d9'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) #Materials project should not have a U for sulfides entry = ComputedEntry( 'FeS2', -2, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'S': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {"titel": 'PAW_PBE S 08Apr2002', 'hash': "f7f8e4a74a6cbb8d63e41f4373b54df2"}]}) self.assertIsNone(self.compat.process_entry(entry)) def test_wrong_psp(self): #Wrong psp entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe 06Sep2000', 'hash': '9530da8244e4dac17580869b4adab115'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) self.assertIsNone(self.compat.process_entry(entry)) def test_element_processing(self): entry = ComputedEntry( 'O', -1, 0.0, parameters={'is_hubbard': False, 'hubbards': {}, 'potcar_spec': [{'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}], 'run_type': 'GGA'}) entry = self.compat.process_entry(entry) # self.assertEqual(entry.entry_id, -8) self.assertAlmostEqual(entry.energy, -1) self.assertAlmostEqual(self.ggacompat.process_entry(entry).energy, -1) def test_get_corrections_dict(self): compat = MaterialsProjectCompatibility(check_potcar_hash=False) ggacompat = MaterialsProjectCompatibility("GGA", check_potcar_hash=False) #Correct parameters entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={'is_hubbard': True, 'hubbards': {'Fe': 5.3, 'O': 0}, 'run_type': 'GGA+U', 'potcar_spec': [{'titel':'PAW_PBE Fe_pv 06Sep2000', 'hash': '994537de5c4122b7f1b77fb604476db4'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': "7a25bc5b9a5393f46600a4939d357982"}]}) c = compat.get_corrections_dict(entry) self.assertAlmostEqual(c["MP Anion Correction"], -2.10687) self.assertAlmostEqual(c["MP Advanced Correction"], -5.466) entry.parameters["is_hubbard"] = False del entry.parameters["hubbards"] c = ggacompat.get_corrections_dict(entry) self.assertNotIn("MP Advanced Correction", c) def test_process_entries(self): entries = self.compat.process_entries([self.entry1, self.entry2, self.entry3]) self.assertEqual(len(entries), 2)
def get_decomposed_entries(structure_type, species): """ Get decomposed entries for mix types Args: structure_type(str): "garnet" or "perovskite" species (dict): species in dictionary. structure_type(str): garnet or perovskite Returns: decompose entries(list): list of entries prepared from unmix garnets/perovskite decomposed from input mix garnet/perovskite """ def decomposed(specie_complex): """Decompose those have sub-dict to individual dict objects.""" for site, specie in specie_complex.items(): spe_copy = specie_complex.copy() if len(specie) > 1: for spe, amt in specie.items(): spe_copy[site] = {spe: 1} yield spe_copy decompose_entries = [] model, scaler = load_model_and_scaler(structure_type, "unmix") std_formula = STD_FORMULA[structure_type] for unmix_species in decomposed(species): charge = sum([ spe.oxi_state * amt * SITE_INFO[structure_type][site]["num_atoms"] for site in SITE_INFO[structure_type].keys() for spe, amt in unmix_species[site].items() ]) if not abs(charge - 2 * std_formula['O']) < 0.1: continue formula = spe2form(structure_type, unmix_species) composition = Composition(formula) elements = [el.name for el in composition] chemsy = '-'.join(sorted(elements)) calc_entries = [] if CALC_ENTRIES[structure_type].get(chemsy): calc_entries = [entry for entry in CALC_ENTRIES[structure_type][chemsy] if \ entry.name == Composition(formula).reduced_formula] else: pass if calc_entries: decompose_entries.extend(calc_entries) else: cn_specific = True if structure_type == 'garnet' else False descriptors = get_descriptor(structure_type, unmix_species, cn_specific=cn_specific) form_e = get_form_e(descriptors, model, scaler) # tot_e = get_tote(form_e * std_formula.num_atoms, unmix_species) tot_e = get_tote(structure_type, form_e * std_formula.num_atoms, unmix_species) entry = prepare_entry(structure_type, tot_e, unmix_species) compat = MaterialsProjectCompatibility() entry = compat.process_entry(entry) decompose_entries.append(entry) return decompose_entries
def test_process_entry(self): compat = MaterialsProjectCompatibility() ggacompat = MaterialsProjectCompatibility("GGA") #Correct parameters entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={ 'is_hubbard': True, 'hubbards': { 'Fe': 5.3, 'O': 0 }, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE O 08Apr2002'] }) self.assertIsNotNone(compat.process_entry(entry)) self.assertIsNone(ggacompat.process_entry(entry)) #Correct parameters entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={ 'is_hubbard': False, "hubbards": {}, 'run_type': 'GGA', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE O 08Apr2002'] }) self.assertIsNone(compat.process_entry(entry)) self.assertIsNotNone(ggacompat.process_entry(entry)) entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={ 'is_hubbard': True, 'hubbards': { 'Fe': 5.3, 'O': 0 }, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE O 08Apr2002'] }) self.assertIsNotNone(compat.process_entry(entry)) #Check actual correction self.assertAlmostEqual( compat.process_entry(entry).correction, -2.733 * 2 - 0.70229 * 3) entry = ComputedEntry( 'FeF3', -2, 0.0, parameters={ 'is_hubbard': True, 'hubbards': { 'Fe': 5.3, 'F': 0 }, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE F 08Apr2002'] }) self.assertIsNotNone(compat.process_entry(entry)) #Check actual correction self.assertAlmostEqual(compat.process_entry(entry).correction, -2.733) #Wrong U value entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={ 'is_hubbard': True, 'hubbards': { 'Fe': 5.2, 'O': 0 }, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE O 08Apr2002'] }) self.assertIsNone(compat.process_entry(entry)) #GGA run of U entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={ 'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE O 08Apr2002'] }) self.assertIsNone(compat.process_entry(entry)) #GGA+U run of non-U entry = ComputedEntry( 'Al2O3', -1, 0.0, parameters={ 'is_hubbard': True, 'hubbards': { 'Al': 5.3, 'O': 0 }, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Al 06Sep2000', 'PAW_PBE O 08Apr2002'] }) self.assertIsNone(compat.process_entry(entry)) #Materials project should not have a U for sulfides entry = ComputedEntry( 'FeS2', -2, 0.0, parameters={ 'is_hubbard': True, 'hubbards': { 'Fe': 5.3, 'S': 0 }, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe_pv 06Sep2000', 'PAW_PBE S 08Apr2002'] }) self.assertIsNone(compat.process_entry(entry)) #Wrong psp entry = ComputedEntry( 'Fe2O3', -1, 0.0, parameters={ 'is_hubbard': True, 'hubbards': { 'Fe': 5.3, 'O': 0 }, 'run_type': 'GGA+U', 'potcar_symbols': ['PAW_PBE Fe 06Sep2000', 'PAW_PBE O 08Apr2002'] }) self.assertIsNone(compat.process_entry(entry)) #Testing processing of elements. entry = ComputedEntry('O', -1, 0.0, parameters={ 'is_hubbard': False, 'hubbards': {}, 'potcar_symbols': ['PAW_PBE O 08Apr2002'], 'run_type': 'GGA' }) entry = compat.process_entry(entry) # self.assertEqual(entry.entry_id, -8) self.assertAlmostEqual(entry.energy, -1) self.assertAlmostEqual(ggacompat.process_entry(entry).energy, -1)
def update_mpworks_schema(mpworks_doc): """ Corrects an mpworks document for outdated schema, as enumerated below: 1. Formats input 2. Stores final energy according to e_wo_entrop 3. Tests compatibility, which was added to MPWorks in a later iteration Args: mpworks_doc: document to update schema for Returns: formatted doc """ # Input last_calc = mpworks_doc['calculations'][-1] xc = last_calc['input']['incar'].get("GGA") if xc: xc.upper() mpworks_doc["input"].update({ "is_lasph": last_calc["input"]["incar"].get("LASPH", False), "potcar_spec": last_calc["input"].get("potcar_spec"), "xc_override": xc, "is_hubbard": last_calc["input"]["incar"].get("LDAU", False) }) # Final energy - this is being changed because of a change in pymatgen # input parsing that uses e_wo_entrop instead of e_fr_energy for calc in mpworks_doc['calculations']: total_e = calc['output']['ionic_steps'][-1]['electronic_steps']\ [-1]['e_wo_entrp'] e_per_atom = total_e / mpworks_doc['nsites'] calc['output']['final_energy'] = total_e calc['output']['final_energy_per_atom'] = e_per_atom # Compatibility mpc = MaterialsProjectCompatibility("Advanced") func = mpworks_doc["pseudo_potential"]["functional"] labels = mpworks_doc["pseudo_potential"]["labels"] symbols = ["{} {}".format(func, label) for label in labels] parameters = { "run_type": mpworks_doc["run_type"], "is_hubbard": mpworks_doc["is_hubbard"], "hubbards": mpworks_doc["hubbards"], "potcar_symbols": symbols } entry = ComputedEntry(Composition(mpworks_doc["unit_cell_formula"]), 0.0, 0.0, parameters=parameters, entry_id=mpworks_doc["task_id"]) try: mpworks_doc['is_compatible'] = bool(mpc.process_entry(entry)) except: traceback.print_exc() logger.warning('ERROR in getting compatibility') mpworks_doc['is_compatible'] = None return mpworks_doc
def run_task(self, fw_spec): # import here to prevent import errors in bigger MPCollab # get the band structure and nelect from files """ prev_dir = get_loc(fw_spec['prev_vasp_dir']) vasprun_loc = zpath(os.path.join(prev_dir, 'vasprun.xml')) kpoints_loc = zpath(os.path.join(prev_dir, 'KPOINTS')) vr = Vasprun(vasprun_loc) bs = vr.get_band_structure(kpoints_filename=kpoints_loc) """ filename = get_slug( 'JOB--' + fw_spec['mpsnl'].structure.composition.reduced_formula + '--' + fw_spec['task_type']) with open(filename, 'w+') as f: f.write('') # get the band structure and nelect from DB block_part = get_block_part(fw_spec['prev_vasp_dir']) db_dir = os.environ['DB_LOC'] assert isinstance(db_dir, object) db_path = os.path.join(db_dir, 'tasks_db.json') with open(db_path) as f: creds = json.load(f) connection = MongoClient(creds['host'], creds['port']) tdb = connection[creds['database']] tdb.authenticate(creds['admin_user'], creds['admin_password']) props = {"calculations": 1, "task_id": 1, "state": 1, "pseudo_potential": 1, "run_type": 1, "is_hubbard": 1, "hubbards": 1, "unit_cell_formula": 1} m_task = tdb.tasks.find_one({"dir_name": block_part}, props) if not m_task: time.sleep(60) # only thing to think of is wait for DB insertion(?) m_task = tdb.tasks.find_one({"dir_name": block_part}, props) if not m_task: raise ValueError("Could not find task with dir_name: {}".format(block_part)) if m_task['state'] != 'successful': raise ValueError("Cannot run Boltztrap; parent job unsuccessful") nelect = m_task['calculations'][0]['input']['parameters']['NELECT'] bs_id = m_task['calculations'][0]['band_structure_fs_id'] print bs_id, type(bs_id) fs = gridfs.GridFS(tdb, 'band_structure_fs') bs_dict = json.loads(fs.get(bs_id).read()) bs_dict['structure'] = m_task['calculations'][0]['output']['crystal'] bs = BandStructure.from_dict(bs_dict) print 'Band Structure found:', bool(bs) print nelect # run Boltztrap runner = BoltztrapRunner(bs, nelect) dir = runner.run(path_dir=os.getcwd()) # put the data in the database bta = BoltztrapAnalyzer.from_files(dir) # 8/21/15 - Anubhav removed fs_id (also see line further below, ted['boltztrap_full_fs_id'] ...) # 8/21/15 - this is to save space in MongoDB, as well as non-use of full Boltztrap output (vs rerun) """ data = bta.as_dict() data.update(get_meta_from_structure(bs._structure)) data['snlgroup_id'] = fw_spec['snlgroup_id'] data['run_tags'] = fw_spec['run_tags'] data['snl'] = fw_spec['mpsnl'] data['dir_name_full'] = dir data['dir_name'] = get_block_part(dir) data['task_id'] = m_task['task_id'] del data['hall'] # remove because it is too large and not useful fs = gridfs.GridFS(tdb, "boltztrap_full_fs") btid = fs.put(json.dumps(jsanitize(data))) """ # now for the "sanitized" data ted = bta.as_dict() del ted['seebeck'] del ted['hall'] del ted['kappa'] del ted['cond'] # ted['boltztrap_full_fs_id'] = btid ted['snlgroup_id'] = fw_spec['snlgroup_id'] ted['run_tags'] = fw_spec['run_tags'] ted['snl'] = fw_spec['mpsnl'].as_dict() ted['dir_name_full'] = dir ted['dir_name'] = get_block_part(dir) ted['task_id'] = m_task['task_id'] ted['pf_doping'] = bta.get_power_factor(output='tensor', relaxation_time=self.TAU) ted['zt_doping'] = bta.get_zt(output='tensor', relaxation_time=self.TAU, kl=self.KAPPAL) ted['pf_eigs'] = self.get_eigs(ted, 'pf_doping') ted['pf_best'] = self.get_extreme(ted, 'pf_eigs') ted['pf_best_dope18'] = self.get_extreme(ted, 'pf_eigs', max_didx=3) ted['pf_best_dope19'] = self.get_extreme(ted, 'pf_eigs', max_didx=4) ted['zt_eigs'] = self.get_eigs(ted, 'zt_doping') ted['zt_best'] = self.get_extreme(ted, 'zt_eigs') ted['zt_best_dope18'] = self.get_extreme(ted, 'zt_eigs', max_didx=3) ted['zt_best_dope19'] = self.get_extreme(ted, 'zt_eigs', max_didx=4) ted['seebeck_eigs'] = self.get_eigs(ted, 'seebeck_doping') ted['seebeck_best'] = self.get_extreme(ted, 'seebeck_eigs') ted['seebeck_best_dope18'] = self.get_extreme(ted, 'seebeck_eigs', max_didx=3) ted['seebeck_best_dope19'] = self.get_extreme(ted, 'seebeck_eigs', max_didx=4) ted['cond_eigs'] = self.get_eigs(ted, 'cond_doping') ted['cond_best'] = self.get_extreme(ted, 'cond_eigs') ted['cond_best_dope18'] = self.get_extreme(ted, 'cond_eigs', max_didx=3) ted['cond_best_dope19'] = self.get_extreme(ted, 'cond_eigs', max_didx=4) ted['kappa_eigs'] = self.get_eigs(ted, 'kappa_doping') ted['kappa_best'] = self.get_extreme(ted, 'kappa_eigs', maximize=False) ted['kappa_best_dope18'] = self.get_extreme(ted, 'kappa_eigs', maximize=False, max_didx=3) ted['kappa_best_dope19'] = self.get_extreme(ted, 'kappa_eigs', maximize=False, max_didx=4) try: from mpcollab.thermoelectrics.boltztrap_TE import BoltzSPB bzspb = BoltzSPB(ted) maxpf_p = bzspb.get_maximum_power_factor('p', temperature=0, tau=1E-14, ZT=False, kappal=0.5,\ otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', \ 'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu')) maxpf_n = bzspb.get_maximum_power_factor('n', temperature=0, tau=1E-14, ZT=False, kappal=0.5,\ otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', \ 'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu')) maxzt_p = bzspb.get_maximum_power_factor('p', temperature=0, tau=1E-14, ZT=True, kappal=0.5, otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', \ 'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu')) maxzt_n = bzspb.get_maximum_power_factor('n', temperature=0, tau=1E-14, ZT=True, kappal=0.5, otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', \ 'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu')) ted['zt_best_finemesh'] = {'p': maxzt_p, 'n': maxzt_n} ted['pf_best_finemesh'] = {'p': maxpf_p, 'n': maxpf_n} except: import traceback traceback.print_exc() print 'COULD NOT GET FINE MESH DATA' # add is_compatible mpc = MaterialsProjectCompatibility("Advanced") try: func = m_task["pseudo_potential"]["functional"] labels = m_task["pseudo_potential"]["labels"] symbols = ["{} {}".format(func, label) for label in labels] parameters = {"run_type": m_task["run_type"], "is_hubbard": m_task["is_hubbard"], "hubbards": m_task["hubbards"], "potcar_symbols": symbols} entry = ComputedEntry(Composition(m_task["unit_cell_formula"]), 0.0, 0.0, parameters=parameters, entry_id=m_task["task_id"]) ted["is_compatible"] = bool(mpc.process_entry(entry)) except: traceback.print_exc() print 'ERROR in getting compatibility, task_id: {}'.format(m_task["task_id"]) ted["is_compatible"] = None tdb.boltztrap.insert(jsanitize(ted)) update_spec = {'prev_vasp_dir': fw_spec['prev_vasp_dir'], 'boltztrap_dir': os.getcwd(), 'prev_task_type': fw_spec['task_type'], 'mpsnl': fw_spec['mpsnl'].as_dict(), 'snlgroup_id': fw_spec['snlgroup_id'], 'run_tags': fw_spec['run_tags'], 'parameters': fw_spec.get('parameters')} return FWAction(update_spec=update_spec)
class AnalyseMaterialsProjectJsonDataWithComputedEntries(): """ Class which will wrap around boilerplate analysis of MaterialsProject-like json files, containing data extracted using borgs and queens. It will be assumed that we are providing ComputedEntries objects directly. """ def __init__(self): # some MP analysis power tools self.compat = MaterialsProjectCompatibility() return def extract_alkali_energy(self, computed_Alkali_entry): processed_Alkali_entry = self.compat.process_entry( computed_Alkali_entry) self.E_Alkali = processed_Alkali_entry.energy return def extract_phase_diagram_info(self, MP_phase_diagram_json_data_filename): computed_entries = self._extract_MP_data( MP_phase_diagram_json_data_filename) processed_entries = self.compat.process_entries(computed_entries) pd = PhaseDiagram(processed_entries) self.phase_diagram_analyser = PDAnalyzer(pd) return def extract_processed_entries(self, computed_entries): processed_entries = self.compat.process_entries(computed_entries) return processed_entries def extract_energies_above_hull(self, computed_entries, alkali): processed_entries = self.extract_processed_entries(computed_entries) list_energy_above_hull = [] list_alkali_content = [] for entry in processed_entries: decomposition_dict, energy_above_hull = \ self.phase_diagram_analyser.get_decomp_and_e_above_hull(entry, allow_negative=True) list_energy_above_hull.append(energy_above_hull) list_alkali_content.append(entry.composition[alkali]) list_energy_above_hull = np.array(list_energy_above_hull) list_alkali_content = np.array(list_alkali_content) return list_alkali_content, list_energy_above_hull def extract_energies(self, computed_entries, alkali): processed_entries = self.extract_processed_entries(computed_entries) list_energy = [] list_alkali_content = [] for entry in processed_entries: list_energy.append(entry.energy) list_alkali_content.append(entry.composition[alkali]) list_energy = np.array(list_energy) list_alkali_content = np.array(list_alkali_content) I = np.argsort(list_alkali_content) return list_alkali_content[I], list_energy[I] def _extract_MP_data(self, MP_data_filename): drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, "dummy", 1) queen.load_data(MP_data_filename) computed_entries = queen.get_data() del drone del queen return computed_entries