def setUp(self): d = loadfn(f"{dir_path}/parse_entry_test_vars.json") struct_uc = d["struct_uc"] self.li_ent = d["li_ent"] e_uc = 100 self.base = ComputedStructureEntry(structure=struct_uc, energy=e_uc) sc = struct_uc * [2, 2, 2] sc.insert(0, "Li", [0.125, 0.125, 0.25]) self.inserted_1Li1 = ComputedStructureEntry(structure=sc, energy=e_uc * 8 + 3) sc = struct_uc * [2, 2, 2] sc.insert(0, "Li", [0.375, 0.375, 0.25]) self.inserted_1Li2 = ComputedStructureEntry(structure=sc, energy=e_uc * 8 + 5) sc = struct_uc * [2, 2, 2] sc.insert(0, "Li", [0.125, 0.125, 0.25]) sc.insert(0, "Li", [0.375, 0.375, 0.25]) self.inserted_2Li = ComputedStructureEntry(structure=sc, energy=e_uc * 8 + 4) self.sm = StructureMatcher(ignored_species=["Li"], primitive_cell=False) self.struct_inserted_1Li1 = get_inserted_on_base( self.base, self.inserted_1Li1, self.li_ent, self.sm) self.struct_inserted_1Li2 = get_inserted_on_base( self.base, self.inserted_1Li2, self.li_ent, self.sm) self.struct_inserted_2Li = get_inserted_on_base( self.base, self.inserted_2Li, self.li_ent, self.sm)
def __init__(self, c_e, status, job_folder): self.status = status self.status_string = self.status_dict[status] self.job_folder = job_folder self.stacking = job_folder.split('/')[-2] self.str_id = job_folder.split('/')[-1].split("__")[-1] if c_e is not None: energy = 1000000 if status <= 1 else c_e.energy ComputedStructureEntry.__init__(self, c_e.structure, energy, correction=c_e.correction, parameters=c_e.parameters, data=c_e.data, entry_id=None) # define all attributes self.nb_cell = 1 self.x_na = 0 self.volume = None self.formula = None # self.name_tag = None self.spacegroup = None self.equivSiteList = None self.dOO_min = None self.dOO_min_indices = None # self.mag = None self.OO_pairs = None self.MMOO_quadruplets = None self.bader_done = False # self.structure_data = self.structure self._mag = None self.generate_tags()
def setUp(self): entry_dict = get_entry_dict( os.path.join(get_path(""), "Cu_entries.txt")) self.Cu_entry_dict = entry_dict with open(os.path.join(get_path(""), 'ucell_entries.txt')) as ucell_entries: ucell_entries = json.loads(ucell_entries.read()) self.Cu_ucell_entry = ComputedStructureEntry.from_dict( ucell_entries["Cu"]) self.Cu_analyzer = SurfaceEnergyPlotter(entry_dict, self.Cu_ucell_entry) self.metals_O_entry_dict = load_O_adsorption() ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["Pt"]) self.Pt_analyzer = SurfaceEnergyPlotter(self.metals_O_entry_dict["Pt"], ucell_entry) ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["Ni"]) self.Ni_analyzer = SurfaceEnergyPlotter(self.metals_O_entry_dict["Ni"], ucell_entry) ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["Rh"]) self.Rh_analyzer = SurfaceEnergyPlotter(self.metals_O_entry_dict["Rh"], ucell_entry) self.Oads_analyzer_dict = { "Pt": self.Pt_analyzer, "Ni": self.Ni_analyzer, "Rh": self.Rh_analyzer }
def test_properties(self): # Test cases for getting adsorption related quantities for a 1/4 # monolalyer adsorption of O on the low MMI surfaces of Pt, Ni and Rh for el in self.metals_O_entry_dict.keys(): el_ucell = ComputedStructureEntry.from_dict(self.ucell_entries[el]) for hkl in self.metals_O_entry_dict[el].keys(): for clean in self.metals_O_entry_dict[el][hkl].keys(): for ads in self.metals_O_entry_dict[el][hkl][clean]: ml = ads.get_unit_primitive_area self.assertAlmostEqual(ml, 4, 2) self.assertAlmostEqual(ads.get_monolayer, 1 / 4, 2) Nads = ads.Nads_in_slab self.assertEqual(Nads, 1) self.assertEqual(ads.Nsurfs_ads_in_slab, 1) # Determine the correct binding energy with open(os.path.join(get_path(""), 'isolated_O_entry.txt')) as isolated_O_entry: isolated_O_entry = json.loads(isolated_O_entry.read()) O = ComputedStructureEntry.from_dict(isolated_O_entry) gbind = (ads.energy - ml * clean.energy) / Nads - O.energy_per_atom self.assertEqual(gbind, ads.gibbs_binding_energy()) # Determine the correction Gibbs adsorption energy eads = Nads * gbind self.assertEqual(eads, ads.gibbs_binding_energy(eads=True)) se = ads.surface_energy(el_ucell) self.assertAlmostEqual(se.as_coefficients_dict()[Symbol("delu_O")], (-1 / 2) * ads.surface_area ** (-1))
def setUp(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") with open(os.path.join(get_path(""), 'ucell_entries.txt')) as ucell_entries: ucell_entries = json.loads(ucell_entries.read()) self.ucell_entries = ucell_entries # Load objects for O adsorption tests self.metals_O_entry_dict = load_O_adsorption() # Load objects for Cu test self.Cu_entry_dict = get_entry_dict( os.path.join(get_path(""), "Cu_entries.txt")) self.assertEqual(len(self.Cu_entry_dict.keys()), 13) self.Cu_ucell_entry = ComputedStructureEntry.from_dict( self.ucell_entries["Cu"]) # Load dummy MgO slab entries self.MgO_ucell_entry = ComputedStructureEntry.from_dict( self.ucell_entries["MgO"]) self.Mg_ucell_entry = ComputedStructureEntry.from_dict( self.ucell_entries["Mg"]) self.MgO_slab_entry_dict = get_entry_dict( os.path.join(get_path(""), "MgO_slab_entries.txt"))
def test_properties(self): # Test cases for getting adsorption related quantities for a 1/4 # monolalyer adsorption of O on the low MMI surfaces of Pt, Ni and Rh for el in self.metals_O_entry_dict.keys(): el_ucell = ComputedStructureEntry.from_dict(self.ucell_entries[el]) for hkl in self.metals_O_entry_dict[el].keys(): for clean in self.metals_O_entry_dict[el][hkl].keys(): for ads in self.metals_O_entry_dict[el][hkl][clean]: ml = ads.get_unit_primitive_area self.assertAlmostEqual(ml, 4, 2) self.assertAlmostEqual(ads.get_monolayer, 1/4, 2) Nads = ads.Nads_in_slab self.assertEqual(Nads, 1) self.assertEqual(ads.Nsurfs_ads_in_slab, 1) # Determine the correct binding energy with open(os.path.join(get_path(""), 'isolated_O_entry.txt')) as isolated_O_entry: isolated_O_entry = json.loads(isolated_O_entry.read()) O = ComputedStructureEntry.from_dict(isolated_O_entry) gbind = (ads.energy - ml*clean.energy)/Nads - O.energy_per_atom self.assertEqual(gbind, ads.gibbs_binding_energy()) # Determine the correction Gibbs adsorption energy eads = Nads * gbind self.assertEqual(eads, ads.gibbs_binding_energy(eads=True)) se = ads.surface_energy(el_ucell) self.assertAlmostEqual(se.as_coefficients_dict()[Symbol("delu_O")], (-1/2)*ads.surface_area**(-1))
def setUp(self): blk_entry_file = os.path.join(file_loc, 'Cr2O3_defects.json') blk_entry = loadfn(blk_entry_file, cls=MontyDecoder) bulk_struct = blk_entry['bulk']['supercell']['structure'] bulk_energy = -100 bulk_entry = ComputedStructureEntry(bulk_struct, bulk_energy) e_vbm = 0.5 mu_elts = {Element('Cr'): -10, Element('O'): -5} bandgap = 3.0 self.da = DefectsAnalyzer(bulk_entry, e_vbm, mu_elts, bandgap) d1_entry_file = os.path.join(file_loc, 'Cr2O3_defects.json') d1_entry = loadfn(d1_entry_file, cls=MontyDecoder) structure = d1_entry['vacancies'][0]['supercell']['structure'] site_in_bulk = d1_entry['vacancies'][0]['bulk_supercell_site'] mult = d1_entry['vacancies'][0]['site_multiplicity'] sc_size = d1_entry['vacancies'][0]['supercell']['size'] entry_defect = ComputedStructureEntry(structure, -99) self.cd = ComputedDefect(entry_defect, site_in_bulk, multiplicity=mult, supercell_size=sc_size, charge=2, name='vac_1_Cr') entry_defect2 = ComputedStructureEntry(structure, -99) self.cd2 = ComputedDefect(entry_defect2, site_in_bulk, multiplicity=mult, supercell_size=sc_size, charge=1, name='vac_1_Cr')
def load_O_adsorption(): # Loads the dictionary for clean and O adsorbed Rh, Pt, and Ni entries # Load the adsorbate as an entry with open(os.path.join(get_path(""), 'isolated_O_entry.txt')) as isolated_O_entry: isolated_O_entry = json.loads(isolated_O_entry.read()) O = ComputedStructureEntry.from_dict(isolated_O_entry) # entry_dict for the adsorption case, O adsorption on Ni, Rh and Pt metals_O_entry_dict = {"Ni": {(1, 1, 1): {}, (1, 0, 0): {}}, "Pt": {(1, 1, 1): {}}, "Rh": {(1, 0, 0): {}} } with open(os.path.join(get_path(""), "csentries_slabs.json")) as entries: entries = json.loads(entries.read()) for k in entries.keys(): entry = ComputedStructureEntry.from_dict(entries[k]) for el in metals_O_entry_dict.keys(): if el in k: if "111" in k: clean = SlabEntry(entry.structure, entry.energy, (1,1,1), label=k+"_clean") metals_O_entry_dict[el][(1, 1, 1)][clean] = [] if "110" in k: clean = SlabEntry(entry.structure, entry.energy, (1, 1, 0), label=k + "_clean") metals_O_entry_dict[el][(1, 1, 0)][clean] = [] if "100" in k: clean = SlabEntry(entry.structure, entry.energy, (1,0,0), label=k+"_clean") metals_O_entry_dict[el][(1, 0, 0)][clean] = [] with open(os.path.join(get_path(""), "csentries_o_ads.json")) as entries: entries = json.loads(entries.read()) for k in entries.keys(): entry = ComputedStructureEntry.from_dict(entries[k]) for el in metals_O_entry_dict.keys(): if el in k: if "111" in k: clean = list(metals_O_entry_dict[el][(1, 1, 1)].keys())[0] ads = SlabEntry(entry.structure, entry.energy, (1,1,1), label=k+"_O", adsorbates=[O], clean_entry=clean) metals_O_entry_dict[el][(1, 1, 1)][clean] = [ads] if "110" in k: clean = list(metals_O_entry_dict[el][(1, 1, 0)].keys())[0] ads = SlabEntry(entry.structure, entry.energy, (1,1,0), label=k+"_O", adsorbates=[O], clean_entry=clean) metals_O_entry_dict[el][(1, 1, 0)][clean] = [ads] if "100" in k: clean = list(metals_O_entry_dict[el][(1, 0, 0)].keys())[0] ads = SlabEntry(entry.structure, entry.energy, (1,0,0), label=k+"_O", adsorbates=[O], clean_entry=clean) metals_O_entry_dict[el][(1, 0, 0)][clean] = [ads] return metals_O_entry_dict
def process_item(self, task): """ Process the tasks into a list of materials Args: task [dict] : a task doc Returns: list of C """ t_type = task_type(get(task, 'orig_inputs')) entries = [] if not any([t in t_type for t in self.task_types]): return [] is_hubbard = get(task, "input.is_hubbard", False) hubbards = get(task, "input.hubbards", []) i = 0 for calc in task.get("calcs_reversed", []): parameters = { "is_hubbard": is_hubbard, "hubbards": hubbards, "potcar_spec": get(calc, "input.potcar_spec", []), "run_type": calc.get("run_type", "GGA") } for step_num, step in enumerate(get(calc, "output.ionic_steps")): struc = Structure.from_dict(step.get("structure")) forces = calc.get("forces", []) if forces: struc.add_site_property("forces", forces) stress = calc.get("stress", None) data = {"stress": stress} if stress else {} data["step"] = step_num c = ComputedStructureEntry(structure=struc, correction=0, energy=step.get("e_wo_entrp"), parameters=parameters, entry_id="{}-{}".format( task[self.tasks.key], i), data=data) i += 1 d = c.as_dict() d["chemsys"] = '-'.join( sorted(set([e.symbol for e in struc.composition.elements]))) d["task_type"] = task_type(get(calc, 'input')) d["calc_name"] = get(calc, "task.name") d["task_id"] = task[self.tasks.key] entries.append(d) return entries
def get_entries(self, chemsys_formula_id, compatible_only=True, inc_structure=None): """ Get a list of ComputedEntries or ComputedStructureEntries corresponding to a chemical system, formula, or materials_id. Args: chemsys_formula_id (str): A chemical system (e.g., Li-Fe-O), or formula (e.g., Fe2O3) or materials_id (e.g., mp-1234). compatible_only (bool): Whether to return only "compatible" entries. Compatible entries are entries that have been processed using the MaterialsProjectCompatibility class, which performs adjustments to allow mixing of GGA and GGA+U calculations for more accurate phase diagrams and reaction energies. inc_structure (str): If None, entries returned are ComputedEntries. If inc_structure="final", ComputedStructureEntries with final structures are returned. Otherwise, ComputedStructureEntries with initial structures are returned. Returns: List of ComputedEntry or ComputedStructureEntry objects. """ # TODO: This is a very hackish way of doing this. It should be fixed # on the REST end. if compatible_only: data = self.get_data(chemsys_formula_id, prop="entry") entries = [d["entry"] for d in data] if inc_structure: for i, e in enumerate(entries): s = self.get_structure_by_material_id( e.entry_id, inc_structure == "final") entries[i] = ComputedStructureEntry( s, e.energy, e.correction, e.parameters, e.data, e.entry_id) entries = MaterialsProjectCompatibility().process_entries(entries) else: entries = [] for d in self.get_data(chemsys_formula_id, prop="task_ids"): for i in d["task_ids"]: e = self.get_task_data(i, prop="entry") e = e[0]["entry"] if inc_structure: s = self.get_task_data( i, prop="structure")[0]["structure"] e = ComputedStructureEntry(s, e.energy, e.correction, e.parameters, e.data, e.entry_id) entries.append(e) return entries
def setUp(self): # Load all entries La_hcp_entry_dict = get_entry_dict(os.path.join(get_path(""), "La_hcp_entries.txt")) La_fcc_entry_dict = get_entry_dict(os.path.join(get_path(""), "La_fcc_entries.txt")) with open(os.path.join(get_path(""), "ucell_entries.txt")) as ucell_entries: ucell_entries = json.loads(ucell_entries.read()) La_hcp_ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["La_hcp"]) La_fcc_ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["La_fcc"]) # Set up the NanoscaleStabilityClass self.La_hcp_analyzer = SurfaceEnergyPlotter(La_hcp_entry_dict, La_hcp_ucell_entry) self.La_fcc_analyzer = SurfaceEnergyPlotter(La_fcc_entry_dict, La_fcc_ucell_entry) self.nanoscale_stability = NanoscaleStability([self.La_fcc_analyzer, self.La_hcp_analyzer])
def test_aqueous_compat(self): el_li = Element("Li") el_o = Element("O") el_h = Element("H") latt = Lattice.from_parameters(3.565276, 3.565276, 4.384277, 90.000000, 90.000000, 90.000000) elts = [el_h, el_h, el_li, el_li, el_o, el_o] coords = [[0.000000, 0.500000, 0.413969], [0.500000, 0.000000, 0.586031], [0.000000, 0.000000, 0.000000], [0.500000, 0.500000, 0.000000], [0.000000, 0.500000, 0.192672], [0.500000, 0.000000, 0.807328]] struct = Structure(latt, elts, coords) lioh_entry = ComputedStructureEntry(struct, -3, parameters={ 'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_symbols': [ 'PAW_PBE Fe 17Jan2003', 'PAW_PBE O 08Apr2002', 'PAW_PBE H 15Jun2001' ] }) lioh_entry_compat = self.compat.process_entry(lioh_entry) lioh_entry_compat_aqcorr = self.aqcorr.correct_entry(lioh_entry_compat) lioh_entry_aqcompat = self.aqcompat.process_entry(lioh_entry) self.assertAlmostEqual(lioh_entry_compat_aqcorr.energy, lioh_entry_aqcompat.energy, 4)
def test_peroxide_energy_corr(self): latt = Lattice.from_parameters(3.159597, 3.159572, 7.685205, 89.999884, 89.999674, 60.000510) el_li = Element("Li") el_o = Element("O") elts = [el_li, el_li, el_li, el_li, el_o, el_o, el_o, el_o] coords = [[0.666656, 0.666705, 0.750001], [0.333342, 0.333378, 0.250001], [0.000001, 0.000041, 0.500001], [0.000001, 0.000021, 0.000001], [0.333347, 0.333332, 0.649191], [0.333322, 0.333353, 0.850803], [0.666666, 0.666686, 0.350813], [0.666665, 0.666684, 0.149189]] struct = Structure(latt, elts, coords) li2o2_entry = ComputedStructureEntry( struct, -3, parameters={ 'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_symbols': ['PAW_PBE Fe 06Sep2000', 'PAW_PBE O 08Apr2002'] }) li2o2_entry_corrected = self.compat.process_entry(li2o2_entry) self.assertRaises(AssertionError, self.assertAlmostEqual, *(li2o2_entry_corrected.energy, -3 - 0.44317 * 4, 4)) self.assertAlmostEqual(li2o2_entry_corrected.energy, -3 - 0.66975 * 4, 4)
def test_process_entry_superoxide(self): el_li = Element("Li") el_o = Element("O") latt = Lattice([[3.985034, 0.0, 0.0], [0.0, 4.881506, 0.0], [0.0, 0.0, 2.959824]]) elts = [el_li, el_li, el_o, el_o, el_o, el_o] coords = list() coords.append([0.500000, 0.500000, 0.500000]) coords.append([0.0, 0.0, 0.0]) coords.append([0.632568, 0.085090, 0.500000]) coords.append([0.367432, 0.914910, 0.500000]) coords.append([0.132568, 0.414910, 0.000000]) coords.append([0.867432, 0.585090, 0.000000]) struct = Structure(latt, elts, coords) lio2_entry = ComputedStructureEntry( struct, -3, parameters={ 'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_symbols': ['PAW_PBE Fe 06Sep2000', 'PAW_PBE O 08Apr2002'] }) lio2_entry_corrected = self.compat.process_entry(lio2_entry) self.assertAlmostEqual(lio2_entry_corrected.energy, -3 - 0.13893 * 4, 4)
def test_process_entry_superoxide(self): el_li = Element("Li") el_o = Element("O") latt = Lattice([[3.985034, 0.0, 0.0], [0.0, 4.881506, 0.0], [0.0, 0.0, 2.959824]]) elts = [el_li, el_li, el_o, el_o, el_o, el_o] coords = list() coords.append([0.500000, 0.500000, 0.500000]) coords.append([0.0, 0.0, 0.0]) coords.append([0.632568, 0.085090, 0.500000]) coords.append([0.367432, 0.914910, 0.500000]) coords.append([0.132568, 0.414910, 0.000000]) coords.append([0.867432, 0.585090, 0.000000]) struct = Structure(latt, elts, coords) lio2_entry = ComputedStructureEntry(struct, -3, parameters={'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Li 17Jan2003', 'hash': '65e83282d1707ec078c1012afbd05be8'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) lio2_entry_corrected = self.compat.process_entry(lio2_entry) self.assertAlmostEqual(lio2_entry_corrected.energy, -3 -0.13893*4, 4)
def test_peroxide_energy_corr(self): latt = Lattice.from_parameters(3.159597, 3.159572, 7.685205, 89.999884, 89.999674, 60.000510) el_li = Element("Li") el_o = Element("O") elts = [el_li, el_li, el_li, el_li, el_o, el_o, el_o, el_o] coords = [[0.666656, 0.666705, 0.750001], [0.333342, 0.333378, 0.250001], [0.000001, 0.000041, 0.500001], [0.000001, 0.000021, 0.000001], [0.333347, 0.333332, 0.649191], [0.333322, 0.333353, 0.850803], [0.666666, 0.666686, 0.350813], [0.666665, 0.666684, 0.149189]] struct = Structure(latt, elts, coords) li2o2_entry = ComputedStructureEntry(struct, -3, parameters={'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Li 17Jan2003', 'hash': '65e83282d1707ec078c1012afbd05be8'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) li2o2_entry_corrected = self.compat.process_entry(li2o2_entry) self.assertRaises(AssertionError, self.assertAlmostEqual, *(li2o2_entry_corrected.energy, -3 - 0.44317 * 4, 4)) self.assertAlmostEqual(li2o2_entry_corrected.energy, -3 - 0.66975 * 4, 4)
def test_aqueous_compat(self): el_li = Element("Li") el_o = Element("O") el_h = Element("H") latt = Lattice.from_parameters(3.565276, 3.565276, 4.384277, 90.000000, 90.000000, 90.000000) elts = [el_h, el_h, el_li, el_li, el_o, el_o] coords = [[0.000000, 0.500000, 0.413969], [0.500000, 0.000000, 0.586031], [0.000000, 0.000000, 0.000000], [0.500000, 0.500000, 0.000000], [0.000000, 0.500000, 0.192672], [0.500000, 0.000000, 0.807328]] struct = Structure(latt, elts, coords) lioh_entry = ComputedStructureEntry(struct, -3, parameters={'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Li 17Jan2003', 'hash': '65e83282d1707ec078c1012afbd05be8'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}, {"titel": 'PAW_PBE H 15Jun2001', 'hash': "bb43c666e3d36577264afe07669e9582"}]}) lioh_entry_compat = self.compat.process_entry(lioh_entry) lioh_entry_compat_aqcorr = self.aqcorr.correct_entry(lioh_entry_compat) lioh_entry_aqcompat = self.aqcompat.process_entry(lioh_entry) self.assertAlmostEqual(lioh_entry_compat_aqcorr.energy, lioh_entry_aqcompat.energy, 4)
def get_computed_entry(self, inc_structure=False, parameters=None, data=None): """ Returns a pymatgen :class:`ComputedStructureEntry` from the GSR file. Same API as the one used in vasp_output.get_computed_entry. Args: inc_structure (bool): Set to True if you want ComputedStructureEntries to be returned instead of ComputedEntries. parameters (list): Input parameters to include. It has to be one of the properties supported by the GSR object. If parameters == None, a default set of parameters that are necessary for typical post-processing will be set. data (list): Output data to include. Has to be one of the properties supported by the GSR object. Returns: ComputedStructureEntry/ComputedEntry """ #raise NotImplementedError("") # TODO #param_names = {"is_hubbard", "hubbards", "potcar_symbols", "run_type"} #if parameters: # param_names.update(parameters) #params = {p: getattr(self, p) for p in param_names} #data = {p: getattr(self, p) for p in data} if data is not None else {} params, data = {}, {} if inc_structure: return ComputedStructureEntry(self.structure, self.energy, parameters=params, data=data) else: return ComputedEntry(self.structure.composition, self.energy, parameters=params, data=data)
def from_dict(d): """ Construct VaspJob object from python dictionary. Returns ------- VaspJob object """ path = d['path'] inputs = VaspInput.from_dict(d['inputs']) job_settings = d['job_settings'] job_script_filename = d['job_script_filename'] name = d['name'] outputs = {} if d['outputs']: outputs[ 'ComputedStructureEntry'] = ComputedStructureEntry.from_dict( d['outputs']['ComputedStructureEntry']) vaspjob = VaspJob(path, inputs, job_settings, outputs, job_script_filename, name) vaspjob._band_structure = BandStructure.from_dict( d['band_structure']) if d['band_structure'] else None vaspjob._is_converged = d['is_converged'] if outputs: for k, v in vaspjob.computed_entry.data.items(): if k not in vaspjob._default_data_computed_entry: setattr(vaspjob, k, v) return vaspjob
def get_entries(self, criteria, inc_structure=False, optional_data=None): """ Get ComputedEntries satisfying a particular criteria. .. note:: The get_entries_in_system and get_entries methods should be used with care. In essence, all entries, GGA, GGA+U or otherwise, are returned. The dataset is very heterogeneous and not directly comparable. It is highly recommended that you perform post-processing using pymatgen.entries.compatibility. Args: criteria: Criteria obeying the same syntax as query. inc_structure: Optional parameter as to whether to include a structure with the ComputedEntry. Defaults to False. Use with care - including structures with a large number of entries can potentially slow down your code to a crawl. optional_data: Optional data to include with the entry. This allows the data to be access via entry.data[key]. Returns: List of pymatgen.entries.ComputedEntries satisfying criteria. """ all_entries = list() optional_data = [] if not optional_data else list(optional_data) fields = [k for k in optional_data] fields.extend(["task_id", "unit_cell_formula", "energy", "is_hubbard", "hubbards", "pseudo_potential.labels", "pseudo_potential.functional", "run_type", "input.is_lasph", "input.xc_override", "input.potcar_spec"]) for c in self.query(fields, criteria): func = c["pseudo_potential.functional"] labels = c["pseudo_potential.labels"] symbols = ["{} {}".format(func, label) for label in labels] parameters = {"run_type": c["run_type"], "is_hubbard": c["is_hubbard"], "hubbards": c["hubbards"], "potcar_symbols": symbols, "is_lasph": c.get("input.is_lasph") or False, "potcar_spec": c.get("input.potcar_spec"), "xc_override": c.get("input.xc_override")} optional_data = {k: c[k] for k in optional_data} if inc_structure: struct = self.get_structure_from_id(c["task_id"]) entry = ComputedStructureEntry(struct, c["energy"], 0.0, parameters=parameters, data=optional_data, entry_id=c["task_id"]) else: entry = ComputedEntry(Composition(c["unit_cell_formula"]), c["energy"], 0.0, parameters=parameters, data=optional_data, entry_id=c["task_id"]) all_entries.append(entry) return all_entries
def get_computed_entry(self, inc_structure=True, parameters=None, data=None): """ Returns a pymatgen :class:`ComputedStructureEntry` from the GSR file. Same API as the one used in vasp_output.get_computed_entry. Args: inc_structure (bool): Set to True if you want ComputedStructureEntries to be returned instead of ComputedEntries. parameters (list): Input parameters to include. It has to be one of the properties supported by the GSR object. If parameters is None, a default set of parameters that are necessary for typical post-processing will be set. data (list): Output data to include. Has to be one of the properties supported by the GSR object. Returns: ComputedStructureEntry/ComputedEntry """ # TODO #param_names = {"is_hubbard", "hubbards", "potcar_symbols", "run_type"} if inc_structure: return ComputedStructureEntry(self.structure, self.energy, correction=0.0, parameters=parameters, data=data) else: return ComputedEntry(self.structure.composition, self.energy, parameters=parameters, data=data)
def get_entry_dict(filename): # helper to generate an entry_dict entry_dict = {} with open(filename) as entries: entries = json.loads(entries.read()) for k in entries.keys(): n = k[25:] miller_index = [] for i, s in enumerate(n): if s == "_": break if s == "-": continue t = int(s) if n[i - 1] == "-": t *= -1 miller_index.append(t) hkl = tuple(miller_index) if hkl not in entry_dict.keys(): entry_dict[hkl] = {} entry = ComputedStructureEntry.from_dict(entries[k]) entry_dict[hkl][SlabEntry(entry.structure, entry.energy, hkl, label=k)] = [] return entry_dict
def from_structure(cls, structure, entry_id=None): status = 1 # pre-run status job_folder = "" c_e = ComputedStructureEntry(structure=structure, energy=100000000, entry_id=entry_id) return cls(c_e, status, job_folder)
def assimilate(self, path): """ Assimilate data in a directory path into a ComputedEntry object. Args: path: directory path Returns: ComputedEntry """ try: gaurun = GaussianOutput(path) except Exception as ex: logger.debug("error in {}: {}".format(path, ex)) return None param = {} for p in self._parameters: param[p] = getattr(gaurun, p) data = {} for d in self._data: data[d] = getattr(gaurun, d) if self._inc_structure: entry = ComputedStructureEntry(gaurun.final_structure, gaurun.final_energy, parameters=param, data=data) else: entry = ComputedEntry(gaurun.final_structure.composition, gaurun.final_energy, parameters=param, data=data) return entry
def get_mp_chempots_from_dpd(dpd): """ Grab Materials Project chemical potentials from a pymatgen DefectPhaseDiagram object """ print("Retrieiving chemical potentials from MP database using dpd object...") bulk_energy = 0. if ('bulk_energy' in dpd.entries[0].parameters.keys()) and \ ('bulk_sc_structure' in dpd.entries[0].parameters.keys()): try: bulk_struct = dpd.entries[0].parameters['bulk_sc_structure'].copy() if type(bulk_struct) != Structure: bulk_struct = Structure.from_dict(bulk_struct) bulk_energy = dpd.entries[0].parameters['bulk_energy'] except: print("Failure in grabbing bulk energy and structure for chemical potential parsing.") if not bulk_energy: print("Grabbing chemical potentials without analyzing stability of bulk structure. " "Ignore any flags raised about stability of structure") bulk_energy = 0. bulk_struct = dpd.entries[0].defect.bulk_structure.copy() bulk_ce = ComputedStructureEntry( bulk_struct, bulk_energy) bulk_elt_set = list(bulk_struct.symbol_set) sub_species = [] for entry in dpd.entries: def_site = entry.defect.site.specie.symbol if def_site not in bulk_elt_set: sub_species.append( def_site) sub_species = set(sub_species) print('Bulk symbols = {}, Sub symbols = {}'.format( bulk_elt_set, sub_species)) mp_cpa = MPChemPotAnalyzer( bulk_ce = bulk_ce, sub_species = sub_species) return mp_cpa.analyze_GGA_chempots()
def from_dict(cls, d): entry_bulk = ComputedStructureEntry.from_dict(d['entry_bulk']) analyzer = DefectsAnalyzer(entry_bulk, d['e_vbm'], d.get( 'band_gap', 0), {el: d['mu_elts'][el] for el in d['mu_elts']}) for ddict in d['defects']: analyzer.add_computed_defect(ComputedDefect.from_dict(ddict)) return analyzer
def test_convert_cd_to_de(self): #create a ComputedDefect object similar to legacy format # Vacancy type first struc = PymatgenTest.get_structure("VO2") struc.make_supercell(3) vac = Vacancy(struc, struc.sites[0], charge=-3) ids = vac.generate_defect_structure(1) defect_data = { "locpot_path": "defect/path/to/files/LOCPOT", "encut": 520 } bulk_data = {"locpot_path": "bulk/path/to/files/LOCPOT"} cse_defect = ComputedStructureEntry(ids, 100., data=defect_data) cd = ComputedDefect(cse_defect, struc.sites[0], charge=-3, name="Vac_1_O") b_cse = ComputedStructureEntry(struc, 10., data=bulk_data) de = convert_cd_to_de(cd, b_cse) self.assertIsInstance(de.defect, Vacancy) self.assertIsInstance(de, DefectEntry) self.assertEqual(de.parameters["defect_path"], "defect/path/to/files") self.assertEqual(de.parameters["bulk_path"], "bulk/path/to/files") self.assertEqual(de.parameters["encut"], 520) self.assertEqual(de.site.specie.symbol, "O") # try again for substitution type # (site object had bulk specie for ComputedDefects, # while it should have substituional site specie for DefectEntrys...) de_site_type = PeriodicSite("Sb", vac.site.frac_coords, struc.lattice) sub = Substitution(struc, de_site_type, charge=1) ids = sub.generate_defect_structure(1) cse_defect = ComputedStructureEntry(ids, 100., data=defect_data) cd = ComputedDefect(cse_defect, struc.sites[0], charge=1, name="Sub_1_Sb_on_O") de = convert_cd_to_de(cd, b_cse) self.assertIsInstance(de.defect, Substitution) self.assertIsInstance(de, DefectEntry) self.assertEqual(de.site.specie.symbol, "Sb")
def from_dict(cls, d): return cls(ComputedStructureEntry.from_dict(d['entry']), PeriodicSite.from_dict(d['site']), multiplicity=d.get('multiplicity', None), supercell_size=d.get('supercell_size', [1, 1, 1]), charge=d.get('charge', 0.0), charge_correction=d.get('charge_correction', 0.0), other_correction=d.get('other_correction', 0.0), name=d.get('name', None))
def cache_common_calculations(target_entry: ComputedStructureEntry, elements: Tuple[str], precursor_library: List[ComputedStructureEntry], v_elements_key: str): target_entry.data[v_elements_key] = get_v( target_entry.composition.fractional_composition.as_dict(), elements) target_entry.data['composition_keys'] = set( target_entry.composition.as_dict().keys()) target_entry.data['reduced_composition_sum'] = sum( target_entry.composition.reduced_composition.as_dict().values()) for p in precursor_library: p.data[v_elements_key] = get_v( p.composition.fractional_composition.as_dict(), elements) p.data['reduced_formula'] = p.composition.reduced_formula p.data['composition_keys'] = set(p.composition.as_dict().keys()) p.data['reduced_composition_sum'] = sum( p.composition.reduced_composition.as_dict().values())
def setUp(self): # Load all entries La_hcp_entry_dict = get_entry_dict(os.path.join(get_path(""), "La_hcp_entries.txt")) La_fcc_entry_dict = get_entry_dict(os.path.join(get_path(""), "La_fcc_entries.txt")) with open(os.path.join(get_path(""), 'ucell_entries.txt')) as ucell_entries: ucell_entries = json.loads(ucell_entries.read()) La_hcp_ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["La_hcp"]) La_fcc_ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["La_fcc"]) # Set up the NanoscaleStabilityClass self.La_hcp_analyzer = SurfaceEnergyPlotter(La_hcp_entry_dict, La_hcp_ucell_entry) self.La_fcc_analyzer = SurfaceEnergyPlotter(La_fcc_entry_dict, La_fcc_ucell_entry) self.nanoscale_stability = NanoscaleStability([self.La_fcc_analyzer, self.La_hcp_analyzer])
def _entry_from_mat_doc(self, mdoc): # Note since we are just structure grouping we don't need to be careful with energy or correction # All of the energy analysis is left to other builders d_ = { "entry_id": mdoc["material_id"], "structure": mdoc["structure"], "energy": -math.inf, "correction": -math.inf, } return ComputedStructureEntry.from_dict(d_)
def assimilate(self, path): files = os.listdir(path) if "relax1" in files and "relax2" in files: filepath = glob.glob(os.path.join(path, "relax2", "vasprun.xml*"))[0] else: vasprun_files = glob.glob(os.path.join(path, "vasprun.xml*")) filepath = None if len(vasprun_files) == 1: filepath = vasprun_files[0] elif len(vasprun_files) > 1: """ This is a bit confusing, since there maybe be multi-steps. By default, assimilate will try to find a file simply named vasprun.xml, vasprun.xml.bz2, or vasprun.xml.gz. Failing which it will try to get a relax2 from an aflow style run if possible. Or else, a randomly chosen file containing vasprun.xml is chosen. """ for fname in vasprun_files: if os.path.basename(fname) in [ "vasprun.xml", "vasprun.xml.gz", "vasprun.xml.bz2" ]: filepath = fname break if re.search("relax2", fname): filepath = fname break filepath = fname try: vasprun = Vasprun(filepath) except Exception as ex: logger.debug("error in {}: {}".format(filepath, ex)) return None param = {} for p in self._parameters: param[p] = getattr(vasprun, p) param["history"] = _get_transformation_history(path) data = {} for d in self._data: data[d] = getattr(vasprun, d) if self._inc_structure: entry = ComputedStructureEntry(vasprun.final_structure, vasprun.final_energy, parameters=param, data=data) else: entry = ComputedEntry(vasprun.final_structure.composition, vasprun.final_energy, parameters=param, data=data) return entry
def setUp(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") with open(os.path.join(get_path(""), 'ucell_entries.txt')) as ucell_entries: ucell_entries = json.loads(ucell_entries.read()) self.ucell_entries = ucell_entries # Load objects for O adsorption tests self.metals_O_entry_dict = load_O_adsorption() # Load objects for Cu test self.Cu_entry_dict = get_entry_dict(os.path.join(get_path(""), "Cu_entries.txt")) self.assertEqual(len(self.Cu_entry_dict.keys()), 13) self.Cu_ucell_entry = ComputedStructureEntry.from_dict(self.ucell_entries["Cu"]) # Load dummy MgO slab entries self.MgO_ucell_entry = ComputedStructureEntry.from_dict(self.ucell_entries["MgO"]) self.Mg_ucell_entry = ComputedStructureEntry.from_dict(self.ucell_entries["Mg"]) self.MgO_slab_entry_dict = get_entry_dict(os.path.join(get_path(""), "MgO_slab_entries.txt"))
def setUp(self): entry_dict = get_entry_dict(os.path.join(get_path(""), "Cu_entries.txt")) self.Cu_entry_dict = entry_dict with open(os.path.join(get_path(""), 'ucell_entries.txt')) as ucell_entries: ucell_entries = json.loads(ucell_entries.read()) self.Cu_ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["Cu"]) self.Cu_analyzer = SurfaceEnergyPlotter(entry_dict, self.Cu_ucell_entry) self.metals_O_entry_dict = load_O_adsorption() ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["Pt"]) self.Pt_analyzer = SurfaceEnergyPlotter(self.metals_O_entry_dict["Pt"], ucell_entry) ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["Ni"]) self.Ni_analyzer = SurfaceEnergyPlotter(self.metals_O_entry_dict["Ni"], ucell_entry) ucell_entry = ComputedStructureEntry.from_dict(ucell_entries["Rh"]) self.Rh_analyzer = SurfaceEnergyPlotter(self.metals_O_entry_dict["Rh"], ucell_entry) self.Oads_analyzer_dict = {"Pt": self.Pt_analyzer, "Ni": self.Ni_analyzer, "Rh": self.Rh_analyzer}
class ComputedStructureEntryTest(unittest.TestCase): def setUp(self): self.entry = ComputedStructureEntry(vasprun.final_structure, vasprun.final_energy, parameters=vasprun.incar) def test_energy(self): self.assertAlmostEqual(self.entry.energy, -269.38319884) self.entry.correction = 1.0 self.assertAlmostEqual(self.entry.energy, -268.38319884) def test_composition(self): self.assertEqual(self.entry.composition.reduced_formula, "LiFe4(PO4)4") def test_to_from_dict(self): d = self.entry.as_dict() e = ComputedStructureEntry.from_dict(d) self.assertAlmostEqual(e.energy, -269.38319884) def test_str(self): self.assertIsNotNone(str(self.entry))
def setUp(self): self.entry = ComputedStructureEntry(vasprun.final_structure, vasprun.final_energy, parameters=vasprun.incar)
def convert(self, d): if 'structure' in d: return ComputedStructureEntry.from_dict(d) else: return ComputedEntry.from_dict(d)
def test_to_from_dict(self): d = self.entry.to_dict e = ComputedStructureEntry.from_dict(d) self.assertAlmostEqual(e.energy, -269.38319884)