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 _get_framework(formula, ignored_species) -> str: """ Return the reduced formula of the entry without any of the ignored species Return 'ignored' if the all the atoms are ignored """ dd_ = Composition(formula).as_dict() if dd_.keys() == set(ignored_species): return "ignored" for ignored_sp in ignored_species: if ignored_sp in dd_: dd_.pop(ignored_sp) return Composition.from_dict(dd_).reduced_formula
def test_StructureGroupDoc_from_ungrouped_entries(entries_lfeo): entry_dict = {ient.entry_id: ient for ient in entries_lfeo} sgroup_docs = StructureGroupDoc.from_ungrouped_structure_entries( entries_lfeo, ignored_species=["Li"]) # Make sure that all the structure in each group has the same framework for sgroup_doc in sgroup_docs: framework_ref = sgroup_doc.framework_formula ignored = sgroup_doc.ignored_species for entry_id in sgroup_doc.material_ids: dd_ = entry_dict[entry_id].composition.as_dict() for k in ignored: if k in dd_: dd_.pop(k) framework = Composition.from_dict(dd_).reduced_formula assert framework == framework_ref
def __swap(self, sites): idx = self.ctx.rs.choice(self.ctx.idxes) species = self.ctx.select[idx] if isinstance(species, dict): species = Composition.from_dict(species) new_sites = deepcopy(sites) i = self.ctx.rs.randint(len(new_sites[species])) ielement = sites[species][i] J = [j for j, site in enumerate(new_sites[species]) if site.value != ielement.value] j = self.ctx.rs.randint(len(J)) jelement = sites[species][J[j]] new_sites[species][i] = jelement new_sites[species][J[j]] = ielement return new_sites
def from_grouped_entries( cls, entries: List[Union[ComputedEntry, ComputedStructureEntry]], ignored_species: List[str], ) -> "StructureGroupDoc": """ " Assuming a list of entries are already grouped together, create a StructureGroupDoc Args: entries: A list of entries that is already grouped together. ignored_species: The species that are ignored during structure matching """ all_atoms = set() all_comps = set() for ient in entries: all_atoms |= set(ient.composition.as_dict().keys()) all_comps.add(ient.composition.reduced_formula) common_atoms = all_atoms - set(ignored_species) if len(common_atoms) == 0: framework_str = "ignored" else: comp_d = { k: entries[0].composition.as_dict()[k] for k in common_atoms } framework_comp = Composition.from_dict(comp_d) framework_str = framework_comp.reduced_formula ids = [ient.entry_id for ient in entries] lowest_id = min(ids, key=_get_id_num) sub_script = "_".join(ignored_species) fields = { "group_id": f"{lowest_id}_{sub_script}", "material_ids": ids, "framework_formula": framework_str, "ignored_species": sorted(ignored_species), "chemsys": "-".join(sorted(all_atoms | set(ignored_species))), "has_distinct_compositions": len(all_comps) > 1, } return cls(**fields)