def std_rel_energies(self) -> Tuple["StandardEnergies", "RelativeEnergies"]: std, rel = StandardEnergies(), RelativeEnergies() abs_energies_per_atom = {k.reduced_formula: v.energy / k.num_atoms for k, v in self.items()} std_energies_list = [] for vertex_element in self.elements: # This target is needed as some reduced formulas shows molecule # ones such as H2 and O2. reduced_formula = Composition({vertex_element: 1.0}).reduced_formula candidates = filter(lambda x: x[0] == reduced_formula, abs_energies_per_atom.items()) try: min_abs_energy = min([abs_energy_per_atom[1] for abs_energy_per_atom in candidates]) except ValueError: print(f"Element {vertex_element} does not exist in " f"CompositionEnergies.") raise NoElementEnergyError std[vertex_element] = min_abs_energy std_energies_list.append(min_abs_energy) for formula, abs_energy_per_atom in abs_energies_per_atom.items(): if Composition(formula).is_element: continue frac = atomic_fractions(formula, self.elements) offset = sum([a * b for a, b in zip(frac, std_energies_list)]) rel[formula] = abs_energy_per_atom - offset return std, rel
def test_fit(self): """ Take two known matched structures 1) Ensure match 2) Ensure match after translation and rotations 3) Ensure no-match after large site translation 4) Ensure match after site shuffling """ sm = StructureMatcher() self.assertTrue(sm.fit(self.struct_list[0], self.struct_list[1])) # Test rotational/translational invariance op = SymmOp.from_axis_angle_and_translation([0, 0, 1], 30, False, np.array([0.4, 0.7, 0.9])) self.struct_list[1].apply_operation(op) self.assertTrue(sm.fit(self.struct_list[0], self.struct_list[1])) #Test failure under large atomic translation self.struct_list[1].translate_sites([0], [.4, .4, .2], frac_coords=True) self.assertFalse(sm.fit(self.struct_list[0], self.struct_list[1])) self.struct_list[1].translate_sites([0], [-.4, -.4, -.2], frac_coords=True) # random.shuffle(editor._sites) self.assertTrue(sm.fit(self.struct_list[0], self.struct_list[1])) #Test FrameworkComporator sm2 = StructureMatcher(comparator=FrameworkComparator()) lfp = read_structure(os.path.join(test_dir, "LiFePO4.cif")) nfp = read_structure(os.path.join(test_dir, "NaFePO4.cif")) self.assertTrue(sm2.fit(lfp, nfp)) self.assertFalse(sm.fit(lfp, nfp)) #Test anonymous fit. self.assertEqual(sm.fit_anonymous(lfp, nfp), {Composition("Li"): Composition("Na")}) self.assertAlmostEqual(sm.get_minimax_rms_anonymous(lfp, nfp)[0], 0.096084154118549828) #Test partial occupancies. s1 = Structure([[3, 0, 0], [0, 3, 0], [0, 0, 3]], [{"Fe": 0.5}, {"Fe": 0.5}, {"Fe": 0.5}, {"Fe": 0.5}], [[0, 0, 0], [0.25, 0.25, 0.25], [0.5, 0.5, 0.5], [0.75, 0.75, 0.75]]) s2 = Structure([[3, 0, 0], [0, 3, 0], [0, 0, 3]], [{"Fe": 0.25}, {"Fe": 0.5}, {"Fe": 0.5}, {"Fe": 0.75}], [[0, 0, 0], [0.25, 0.25, 0.25], [0.5, 0.5, 0.5], [0.75, 0.75, 0.75]]) self.assertFalse(sm.fit(s1, s2)) self.assertFalse(sm.fit(s2, s1)) s2 = Structure([[3, 0, 0], [0, 3, 0], [0, 0, 3]], [{"Fe": 0.25}, {"Fe": 0.25}, {"Fe": 0.25}, {"Fe": 0.25}], [[0, 0, 0], [0.25, 0.25, 0.25], [0.5, 0.5, 0.5], [0.75, 0.75, 0.75]]) self.assertEqual(sm.fit_anonymous(s1, s2), {Composition("Fe0.5"): Composition("Fe0.25")}) self.assertAlmostEqual(sm.get_minimax_rms_anonymous(s1, s2)[0], 0)
def test_electronegativity(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5) s1 = read_structure(os.path.join(test_dir, "Na2Fe2PAsO4S4.cif")) s2 = read_structure(os.path.join(test_dir, "Na2Fe2PNO4Se4.cif")) self.assertAlmostEqual(sm.fit_with_electronegativity(s1, s2), {Composition('S'): Composition('Se'), Composition('As'): Composition('N')})
def test_composition_to_oxidcomposition(self): df = DataFrame(data={"composition": [Composition("Fe2O3")]}) cto = CompositionToOxidComposition() df = cto.featurize_dataframe(df, 'composition') self.assertEqual(df["composition_oxid"].tolist()[0], Composition({ "Fe3+": 2, "O2-": 3 })) # test error handling df = DataFrame(data={"composition": [Composition("Fe2O3")]}) cto = CompositionToOxidComposition(return_original_on_error=False, max_sites=2) self.assertRaises(ValueError, cto.featurize_dataframe, df, 'composition') # check non oxi state structure returned correctly cto = CompositionToOxidComposition(return_original_on_error=True, max_sites=2) df = cto.featurize_dataframe(df, 'composition') self.assertEqual(df["composition_oxid"].tolist()[0], Composition({ "Fe": 2, "O": 3 }))
def make_composition_energies_from_mp( elements: List[str], atom_energy_yaml: Optional[str] = None, ) -> CompositionEnergies: """Obtain the energies from Materials Project. When the atom_energy_yaml is provided, the total energies are aligned via atom energies. """ properties = ["task_id", "full_formula", "final_energy"] query = MpQuery(elements, properties=properties) comp_es = {} if atom_energy_yaml: energies = loadfn(atom_energy_yaml) diff = {e: energies[e] - mp_energies[e] for e in elements} else: diff = {e: 0.0 for e in elements} for m in query.materials: key = Composition(m["full_formula"]) energy = m["final_energy"] for k, v in key.as_dict().items(): energy += diff[k] * v comp_es[key] = CompositionEnergy(energy, m["task_id"]) print(comp_es) comp_es = remove_higher_energy_comp(comp_es) print(comp_es) return CompositionEnergies(comp_es)
def __getitem__(self, idx: int): """Get an entry out of the Dataset Args: idx (int): index of entry in Dataset Returns: tuple: containing - tuple[Tensor, Tensor, LongTensor, LongTensor]: Roost model inputs - list[Tensor | LongTensor]: regression or classification targets - list[str | int]: identifiers like material_id, composition """ df_idx = self.df.iloc[idx] composition = df_idx[self.inputs] cry_ids = df_idx[self.identifiers].to_list() comp_dict = Composition(composition).get_el_amt_dict() elements = list(comp_dict.keys()) weights = list(comp_dict.values()) weights = np.atleast_2d(weights).T / np.sum(weights) try: elem_fea = np.vstack( [self.elem_features[element] for element in elements]) except AssertionError: raise AssertionError( f"cry-id {cry_ids[0]} [{composition}] contains element types not in embedding" ) except ValueError: raise ValueError( f"cry-id {cry_ids[0]} [{composition}] composition cannot be parsed into elements" ) nele = len(elements) self_idx = [] nbr_idx = [] for i, _ in enumerate(elements): self_idx += [i] * nele nbr_idx += list(range(nele)) # convert all data to tensors elem_weights = Tensor(weights) elem_fea = Tensor(elem_fea) self_idx = LongTensor(self_idx) nbr_idx = LongTensor(nbr_idx) targets = [] for target in self.task_dict: if self.task_dict[target] == "regression": targets.append(Tensor([df_idx[target]])) elif self.task_dict[target] == "classification": targets.append(LongTensor([df_idx[target]])) return ( (elem_weights, elem_fea, self_idx, nbr_idx), targets, *cry_ids, )
def mp_query_mock(mocker): mock = mocker.patch( "pydefect.cli.vasp.make_composition_energies_from_mp.MpEntries") mock.return_value.materials = \ [ComputedEntry(Composition("O8"), -39.58364375, entry_id="mp-1"), ComputedEntry(Composition("Mg3"), -4.79068775, entry_id="mp-2"), ComputedEntry(Composition("Mg1O1"), -11.96742144, entry_id="mp-3")] return mock
def comp_energies_corr(): return CompositionEnergies({ Composition('O8'): CompositionEnergy(-39.58364375 + diff["O"] * 8, "mp-1"), Composition('Mg3'): CompositionEnergy(-4.79068775 + diff["Mg"] * 3, "mp-2"), Composition('Mg1O1'): CompositionEnergy(-11.96742144 + diff["Mg"] + diff["O"], "mp-3") })
def side_effect_structure(key): mock_structure = mocker.Mock() if key == Path("Mg") / defaults.contcar: mock_structure.composition = Composition("Mg2") elif key == Path("O") / defaults.contcar: mock_structure.composition = Composition("O2") else: raise ValueError return mock_structure
def comp_energies(): return CompositionEnergies({ Composition('O8'): CompositionEnergy(-39.58364375, "mp-1"), Composition('Mg3'): CompositionEnergy(-4.79068775, "mp-2"), Composition('Mg1O1'): CompositionEnergy(-11.96742144, "mp-3") })
def formula_to_criteria(formula: str) -> Dict: """ Santizes formula into a dictionary to search with wild cards Arguments: formula: a chemical formula with wildcards in it for unknown elements Returns: Mongo style search criteria for this formula """ dummies = "ADEGJLMQRXZ" if "*" in formula: # Wild card in formula nstars = formula.count("*") formula_dummies = formula.replace("*", "{}").format(*dummies[:nstars]) integer_formula = Composition( formula_dummies).get_integer_formula_and_factor()[0] comp = Composition(integer_formula).reduced_composition crit = dict() crit["formula_anonymous"] = comp.anonymized_formula real_elts = [ str(e) for e in comp.elements if not e.as_dict().get("element", "A") in dummies ] for el, n in comp.to_reduced_dict.items(): if el in real_elts: crit[f"composition_reduced.{el}"] = n return crit elif "-" in formula: crit = {} eles = formula.split("-") chemsys = "-".join(sorted(eles)) crit["chemsys"] = chemsys return crit elif any(isinstance(el, DummySpecies) for el in Composition(formula)): # Assume fully anonymized formula return {"formula_anonymous": Composition(formula).anonymized_formula} else: comp = Composition(formula) # Paranoia below about floating-point "equality" crit = {} crit["nelements"] = len(comp) for el, n in comp.to_reduced_dict.items(): crit[f"composition_reduced.{el}"] = n return crit
def test_composition_to_structurefromMP(self): df = DataFrame(data={"composition": [Composition("Fe2O3"), Composition("N9Al34Fe234")]}) cto = CompositionToStructureFromMP() df = cto.featurize_dataframe(df, 'composition') structures = df["structure"].tolist() self.assertTrue(isinstance(structures[0], Structure)) self.assertGreaterEqual(len(structures[0]), 5) # has at least 5 sites self.assertTrue(math.isnan(structures[1]))
def setUp(self): self.df = pd.DataFrame({ "composition": [ Composition("Fe2O3"), Composition({ Specie("Fe", 2): 1, Specie("O", -2): 1 }) ] })
def test_get_sc_structures(self): dist_ref = self.m_hop.length start, end, b_sc = self.m_hop.get_sc_structures(vac_mode=False) start_site = next( filter(lambda x: x.species_string == "Li", start.sites)) end_site = next(filter(lambda x: x.species_string == "Li", end.sites)) assert start.composition == end.composition == Composition( "Li1 Fe24 P24 O96") assert b_sc.composition == Composition("Fe24 P24 O96") self.assertAlmostEqual(start_site.distance(end_site), dist_ref, 3)
def remove_higher_energy_comp(comp_energies: Dict[Composition, CompositionEnergy]): _l = [[k, v] for k, v in comp_energies.items()] result = {} for _, grouped_k_v in groupby( _l, key=lambda x: Composition(x[0]).reduced_formula): formula, comp_e = min(list(grouped_k_v), key=lambda y: (y[1].energy / Composition(y[0]).num_atoms)) result[formula] = comp_e return result
def test_remove_higher_energy_comp(): comp_es = CompositionEnergies( {Composition('Mg1'): CompositionEnergy(-1.9, "mp-2"), Composition('Mg2'): CompositionEnergy(-4.0, "mp-3"), Composition('O2'): CompositionEnergy(-4.0, "mp-4")}) actual = remove_higher_energy_comp(comp_es) expected = CompositionEnergies( {Composition('Mg2'): CompositionEnergy(-4.0, "mp-3"), Composition('O2'): CompositionEnergy(-4.0, "mp-4"),}) assert actual == expected
def test_str_to_composition(self): d = {'comp_str': ["Fe2", "MnO2"]} df = DataFrame(data=d) df["composition"] = str_to_composition(df["comp_str"]) self.assertEqual(df["composition"].tolist(), [Composition("Fe2"), Composition("MnO2")]) df["composition_red"] = str_to_composition(df["comp_str"], reduce=True) self.assertEqual(df["composition_red"].tolist(), [Composition("Fe"), Composition("MnO2")])
def side_effect(key): mock_vasprun = mocker.Mock() if key == Path("Mg") / defaults.vasprun: mock_vasprun.final_structure.composition = Composition("Mg2") mock_vasprun.final_energy = -10 elif key == Path("O") / defaults.vasprun: mock_vasprun.final_structure.composition = Composition("O2") mock_vasprun.final_energy = -20 else: raise ValueError return mock_vasprun
def test_is_ionic(self): """Test checking whether a compound is ionic""" self.assertTrue( is_ionic(Composition({ Specie("Fe", 2): 1, Specie("O", -2): 1 }))) self.assertFalse( is_ionic(Composition({ Specie("Fe", 0): 1, Specie("Al", 0): 1 })))
def test_stoich(self): featurizer = Stoichiometry(num_atoms=True) df_stoich = Stoichiometry(num_atoms=True).featurize_dataframe( self.df, col_id="composition") self.assertAlmostEqual(df_stoich["num atoms"][0], 5) self.assertAlmostEqual(df_stoich["0-norm"][0], 2) self.assertAlmostEqual(df_stoich["7-norm"][0], 0.604895199) # Test whether the number of formula units affects result original_value = featurizer.featurize(Composition("FeO")) self.assertArrayAlmostEqual( featurizer.featurize(Composition("Fe0.5O0.5")), original_value) self.assertArrayAlmostEqual(featurizer.featurize(Composition("Fe2O2")), original_value)
def test_structure_to_composition(self): coords = [[0, 0, 0], [0.75, 0.5, 0.75]] lattice = Lattice([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]]) struct = Structure(lattice, ["Si"] * 2, coords) df = DataFrame(data={'structure': [struct]}) df["composition"] = structure_to_composition(df["structure"]) self.assertEqual(df["composition"].tolist()[0], Composition("Si2")) df["composition_red"] = structure_to_composition(df["structure"], reduce=True) self.assertEqual(df["composition_red"].tolist()[0], Composition("Si"))
def test_str_to_composition(self): d = {'comp_str': ["Fe2", "MnO2"]} df = DataFrame(data=d) df = StrToComposition().featurize_dataframe(df, 'comp_str') self.assertEqual(df["composition"].tolist(), [Composition("Fe2"), Composition("MnO2")]) stc = StrToComposition(reduce=True, target_col_id='composition_red') df = stc.featurize_dataframe(df, 'comp_str') self.assertEqual(df["composition_red"].tolist(), [Composition("Fe"), Composition("MnO2")])
def test_miedema_all(self): df = pd.DataFrame({ "composition": [ Composition("TiZr"), Composition("Mg10Cu50Ca40"), Composition("Fe2O3") ] }) miedema = Miedema(struct_types='all') self.assertTrue(miedema.precheck(df["composition"].iloc[0])) self.assertFalse(miedema.precheck(df["composition"].iloc[-1])) self.assertAlmostEqual(miedema.precheck_dataframe(df, "composition"), 2 / 3) # test precheck for oxidation-state decorated compositions df = CompositionToOxidComposition(return_original_on_error=True).\ featurize_dataframe(df, 'composition') self.assertTrue(miedema.precheck(df["composition_oxid"].iloc[0])) self.assertFalse(miedema.precheck(df["composition_oxid"].iloc[-1])) self.assertAlmostEqual( miedema.precheck_dataframe(df, "composition_oxid"), 2 / 3) mfps = miedema.featurize_dataframe(df, col_id="composition") self.assertAlmostEqual(mfps['Miedema_deltaH_inter'][0], -0.003445022152) self.assertAlmostEqual(mfps['Miedema_deltaH_amor'][0], 0.0707658836300) self.assertAlmostEqual(mfps['Miedema_deltaH_ss_min'][0], 0.03663599755) self.assertAlmostEqual(mfps['Miedema_deltaH_inter'][1], -0.235125978427) self.assertAlmostEqual(mfps['Miedema_deltaH_amor'][1], -0.164541848271) self.assertAlmostEqual(mfps['Miedema_deltaH_ss_min'][1], -0.05280843311) self.assertAlmostEqual(math.isnan(mfps['Miedema_deltaH_inter'][2]), True) self.assertAlmostEqual(math.isnan(mfps['Miedema_deltaH_amor'][2]), True) self.assertAlmostEqual(math.isnan(mfps['Miedema_deltaH_ss_min'][2]), True) # make sure featurization works equally for compositions with or without # oxidation states mfps = miedema.featurize_dataframe(df, col_id="composition_oxid") self.assertAlmostEqual(mfps['Miedema_deltaH_inter'][0], -0.003445022152) self.assertAlmostEqual(mfps['Miedema_deltaH_amor'][0], 0.0707658836300) self.assertAlmostEqual(mfps['Miedema_deltaH_ss_min'][0], 0.03663599755)
def update_sites(self, directory, ignore_magmom=False): """ Based on the CONTCAR and OUTCAR of a geometry optimization, update the site coordinates and magnetic moments that were optimized. Note that this method relies on the cation configuration of the cathode not having changed. Args: directory (str): Directory in which the geometry optimization output files (i.e. CONTCAR and OUTCAR) are stored. ignore_magmom (bool): Flag that indicates that the final magnetic moments of the optimized structure should be ignored. This means that the magnetic moments of the Cathode structure will remain the same. Returns: None """ new_cathode = Cathode.from_file(os.path.join(directory, "CONTCAR")) out = Outcar(os.path.join(directory, "OUTCAR")) if ignore_magmom: magmom = [site.properties["magmom"] for site in self.sites if site.species != Composition()] else: magmom = [site["tot"] for site in out.magnetization] if len(out.magnetization) != 0: new_cathode.add_site_property("magmom", magmom) # Update the lattice self.lattice = new_cathode.lattice # Update the coordinates of the occupied sites. new_index = 0 for i, site in enumerate(self): # If the site is not empty if site.species != Composition(): new_site = new_cathode.sites[new_index] # Update the site coordinates self.replace(i, species=new_site.species, coords=new_site.frac_coords, properties=new_site.properties) new_index += 1
def get_insertion_energy( base_entry: ComputedStructureEntry, inserted_entry: ComputedStructureEntry, migrating_ion_entry: ComputedEntry, ) -> float: """ Calculate the insertion energy for a given inserted entry Args: base_entry: The entry for the host structure inserted_entry: The entry for the inserted structure migrating_ion_entry: The entry for the metallic phase of the working ion Returns: The insertion energy defined as (E[inserted] - (E[Base] + n * E[working_ion]))/(n) Where n is the number of working ions and E[inserted]. Additionally, and E[base] and E[inserted] are for structures of the same size (sans working ion) """ wi_ = str(migrating_ion_entry.composition.elements[0]) comp_inserted_no_wi = inserted_entry.composition.as_dict() comp_inserted_no_wi.pop(wi_) comp_inserted_no_wi = Composition.from_dict(comp_inserted_no_wi) _, factor_inserted = comp_inserted_no_wi.get_reduced_composition_and_factor( ) _, factor_base = base_entry.composition.get_reduced_composition_and_factor( ) e_base = base_entry.energy * factor_inserted / factor_base e_insert = inserted_entry.energy e_wi = migrating_ion_entry.energy_per_atom n_wi = inserted_entry.composition[wi_] return (e_insert - (e_base + n_wi * e_wi)) / n_wi
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 run(self): logger.info("Starting FileMaterials Builder.") with open(self._data_file, 'rt') as f: line_no = 0 lines = [line for line in f] # only good for smaller files pbar = tqdm(lines) for line in pbar: line = line.strip() if line and not line.startswith("#"): line_no += 1 if line_no > self.header_lines: line = line.split(self._delimiter) if "-" in line[0]: search_val = line[0] search_key = "material_id" else: search_key = "formula_reduced_abc" search_val = Composition(line[0]).\ reduced_composition.alphabetical_formula key = line[1] val = line[2] try: val = float(val) except: pass self._materials.update({search_key: search_val}, {"$set": {key: val}}) logger.info("FileMaterials Builder finished processing")
def FullChemicalPotentialWindow(target_phase, key_element): chemsys = key_element + '-' + Composition(target_phase).chemical_system with MPRester(api_key='') as mpr: entries = mpr.get_entries_in_chemsys(chemsys) pd_closed = PhaseDiagram(entries) transition_chempots = pd_closed.get_transition_chempots( Element(key_element)) # The exact mu value used to construct the plot for each range is # the average of the endpoints of the range, with the exception of the last range, # which is plotted at the value of the last endpoint minus 0.1. # https://matsci.org/t/question-on-phase-diagram-app-chemical-potential/511 average_chempots = [] if len(transition_chempots) > 1: for i in range(len(transition_chempots) - 1): ave = (transition_chempots[i] + transition_chempots[i + 1]) / 2 average_chempots.append(ave) average_chempots.append(transition_chempots[-1] - 0.1) elif len(transition_chempots) == 1: # prepare for binary systems, of which two endnodes tielined directly, like Li-Zr average_chempots.append(transition_chempots[0]) average_chempots = np.round(average_chempots, 3) boolean_list = [] for chempot in average_chempots: # GrandPotentialPhaseDiagram works good even for binary systems to find stable phases pd_open = GrandPotentialPhaseDiagram(entries, {Element(key_element): chempot}) stable_phases = [entry.name for entry in pd_open.stable_entries] boolean_list.append(target_phase in stable_phases) return (False not in boolean_list)
def test_structure_to_composition(self): coords = [[0, 0, 0], [0.75, 0.5, 0.75]] lattice = Lattice([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]]) struct = Structure(lattice, ["Si"] * 2, coords) df = DataFrame(data={'structure': [struct]}) stc = StructureToComposition() df = stc.featurize_dataframe(df, 'structure') self.assertEqual(df["composition"].tolist()[0], Composition("Si2")) stc = StructureToComposition(reduce=True, target_col_id='composition_red') df = stc.featurize_dataframe(df, 'structure') self.assertEqual(df["composition_red"].tolist()[0], Composition("Si"))
def test_band_center(self): df_band_center = BandCenter().featurize_dataframe(self.df, col_id="composition") self.assertAlmostEqual(df_band_center["band center"][0], -2.672486385) self.assertAlmostEqual( BandCenter().featurize(Composition('Ag33O500V200'))[0], -2.7337150991)
def get_comp_data(un_data): element_universe = [str(e) for e in Element] dict_element = {} for i, j in enumerate(element_universe): dict_element[str(j)] = i stoich_array = np.zeros((len(un_data), 3), dtype=float) at_num_array = np.zeros((len(un_data), 3), dtype=int) electroneg_array = np.zeros((len(un_data), 3), dtype=float) comp_array=[] for index, entry in enumerate(un_data): comp = Composition(entry[2]) comp_array.append(comp.formula) temp_dict = dict(comp.get_el_amt_dict()) for count, key in enumerate(temp_dict.keys()): stoich_array[index][count] = temp_dict[key] if key not in ['D', 'T']: at_num_array[index][count] = Element(key).Z electroneg_array[index][count] = Element(key).X else: at_num_array[index][count] = Element('H').Z electroneg_array[index][count] = Element('H').X return (comp_array,stoich_array,at_num_array,electroneg_array)
def __init__(self, entries, comp_dict=None): """ Args: entries: Entries list containing both Solids and Ions comp_dict: Dictionary of compositions """ self._solid_entries = list() self._ion_entries = list() for entry in entries: if entry.phase_type == "Solid": self._solid_entries.append(entry) elif entry.phase_type == "Ion": self._ion_entries.append(entry) else: raise StandardError("Incorrect Phase type - needs to be \ Pourbaix entry of phase type Ion/Solid") self._unprocessed_entries = self._solid_entries + self._ion_entries self._elt_comp = comp_dict if comp_dict: self._multielement = True self.pourbaix_elements = [key for key in comp_dict] w = [comp_dict[key] for key in comp_dict] A = [] for comp in comp_dict: m = re.search(r"\[([^\[\]]+)\]|\(aq\)", comp) if m: comp_obj = Ion.from_formula(comp) else: comp_obj = Composition.from_formula(comp) Ai = [] for elt in self.pourbaix_elements: Ai.append(comp_obj[Element(elt)]) A.append(Ai) A = np.array(A).T.astype(float) w = np.array(w) A /= np.dot([A[i].sum() for i in xrange(len(A))], w) x = np.linalg.solve(A, w) self._elt_comp = dict(zip(self.pourbaix_elements, x)) else: self._multielement = False self.pourbaix_elements = [el.symbol for el in entries[0].composition.elements if el.symbol not in ["H", "O"]] self._make_pourbaixdiagram()
factors = {'Co': 1.7/3.2/0.6, 'Fe': 2.1/3.9/0.6} for fldidx,fields_str in enumerate(fields_strings): fields = fields_str.split(' -> ') for elidx,elem in enumerate(chemsys[:-1]): print fields_str, elem plt = plotter.get_plot() title = elem+': '+fields_str if fldidx == 3 and elidx == 1: title = fields_str plt.suptitle(title, fontsize=24) plt.triplot(grid_triang, 'k:') # heatmap x, y, z = [], [], [] for idx,(comp,cid) in enumerate(comps_cids): comp_str = comp if args.dev else doc[cid]['_id'] composition = Composition(comp_str) x0, x1, x2 = [composition.get_atomic_fraction(el) for el in chemsys] x.append(x0+x2/2.) # NOTE x0 might need to be replace with x1 y.append(x2*math.sqrt(3.)/2.) if fldidx < 3: zval = mpfile.document[comp_str]['{} XMCD'.format(elem)][fields[0]][fields[1]] if fldidx == 0: norms[elem] = zval elif fldidx == 1: xmcd_diffs[elem] = zval else: xmcd_diffs[elem] -= zval z.append(zval) else: mag += xmcd_diffs[elem] * factors[elem] * norms[elem] if elidx == 1: z.append(mag) if fldidx == 3 and elidx == 0: continue #x0, x1, x2 = 1/2., 1/3., 1/6.