def from_steps(cls, step1, step2, normalization_els, framework_formula=None): """ Creates a ConversionVoltagePair from two steps in the element profile from a PD analysis. Args: step1: Starting step step2: Ending step normalization_els: Elements to normalize the reaction by. To ensure correct capacities. """ working_ion_entry = step1["element_reference"] working_ion = working_ion_entry.composition.elements[0].symbol working_ion_valence = max(Element(working_ion).oxidation_states) voltage = (-step1["chempot"] + working_ion_entry.energy_per_atom) / working_ion_valence mAh = ((step2["evolution"] - step1["evolution"]) * Charge(1, "e").to("C") * Time(1, "s").to("h") * N_A * 1000 * working_ion_valence) licomp = Composition(working_ion) prev_rxn = step1["reaction"] reactants = { comp: abs(prev_rxn.get_coeff(comp)) for comp in prev_rxn.products if comp != licomp } curr_rxn = step2["reaction"] products = { comp: abs(curr_rxn.get_coeff(comp)) for comp in curr_rxn.products if comp != licomp } reactants[licomp] = step2["evolution"] - step1["evolution"] rxn = BalancedReaction(reactants, products) for el, amt in normalization_els.items(): if rxn.get_el_amount(el) > 1e-6: rxn.normalize_to_element(el, amt) break prev_mass_dischg = (sum([ prev_rxn.all_comp[i].weight * abs(prev_rxn.coeffs[i]) for i in range(len(prev_rxn.all_comp)) ]) / 2) vol_charge = sum([ abs(prev_rxn.get_coeff(e.composition)) * e.structure.volume for e in step1["entries"] if e.composition.reduced_formula != working_ion ]) mass_discharge = (sum([ curr_rxn.all_comp[i].weight * abs(curr_rxn.coeffs[i]) for i in range(len(curr_rxn.all_comp)) ]) / 2) mass_charge = prev_mass_dischg mass_discharge = mass_discharge vol_discharge = sum([ abs(curr_rxn.get_coeff(e.composition)) * e.structure.volume for e in step2["entries"] if e.composition.reduced_formula != working_ion ]) totalcomp = Composition({}) for comp in prev_rxn.products: if comp.reduced_formula != working_ion: totalcomp += comp * abs(prev_rxn.get_coeff(comp)) frac_charge = totalcomp.get_atomic_fraction(Element(working_ion)) totalcomp = Composition({}) for comp in curr_rxn.products: if comp.reduced_formula != working_ion: totalcomp += comp * abs(curr_rxn.get_coeff(comp)) frac_discharge = totalcomp.get_atomic_fraction(Element(working_ion)) rxn = rxn entries_charge = step2["entries"] entries_discharge = step1["entries"] return cls( rxn=rxn, voltage=voltage, mAh=mAh, vol_charge=vol_charge, vol_discharge=vol_discharge, mass_charge=mass_charge, mass_discharge=mass_discharge, frac_charge=frac_charge, frac_discharge=frac_discharge, entries_charge=entries_charge, entries_discharge=entries_discharge, working_ion_entry=working_ion_entry, _framework_formula=framework_formula, )
def from_steps(step1, step2, normalization_els): """ Creates a ConversionVoltagePair from two steps in the element profile from a PD analysis. Args: step1: Starting step step2: Ending step normalization_els: Elements to normalize the reaction by. To ensure correct capacities. """ working_ion_entry = step1["element_reference"] working_ion = working_ion_entry.composition.elements[0].symbol voltage = -step1["chempot"] + working_ion_entry.energy_per_atom mAh = (step2["evolution"] - step1["evolution"]) \ * Charge(1, "e").to("C") * Time(1, "s").to("h") * N_A * 1000 licomp = Composition(working_ion) prev_rxn = step1["reaction"] reactants = {comp: abs(prev_rxn.get_coeff(comp)) for comp in prev_rxn.products if comp != licomp} curr_rxn = step2["reaction"] products = {comp: abs(curr_rxn.get_coeff(comp)) for comp in curr_rxn.products if comp != licomp} reactants[licomp] = (step2["evolution"] - step1["evolution"]) rxn = BalancedReaction(reactants, products) for el, amt in normalization_els.items(): if rxn.get_el_amount(el) > 1e-6: rxn.normalize_to_element(el, amt) break prev_mass_dischg = sum([prev_rxn.all_comp[i].weight * abs(prev_rxn.coeffs[i]) for i in range(len(prev_rxn.all_comp))]) / 2 vol_charge = sum([abs(prev_rxn.get_coeff(e.composition)) * e.structure.volume for e in step1["entries"] if e.composition.reduced_formula != working_ion]) mass_discharge = sum([curr_rxn.all_comp[i].weight * abs(curr_rxn.coeffs[i]) for i in range(len(curr_rxn.all_comp))]) / 2 mass_charge = prev_mass_dischg mass_discharge = mass_discharge vol_discharge = sum([abs(curr_rxn.get_coeff(e.composition)) * e.structure.volume for e in step2["entries"] if e.composition.reduced_formula != working_ion]) totalcomp = Composition({}) for comp in prev_rxn.products: if comp.reduced_formula != working_ion: totalcomp += comp * abs(prev_rxn.get_coeff(comp)) frac_charge = totalcomp.get_atomic_fraction(Element(working_ion)) totalcomp = Composition({}) for comp in curr_rxn.products: if comp.reduced_formula != working_ion: totalcomp += comp * abs(curr_rxn.get_coeff(comp)) frac_discharge = totalcomp.get_atomic_fraction(Element(working_ion)) rxn = rxn entries_charge = step2["entries"] entries_discharge = step1["entries"] return ConversionVoltagePair(rxn, voltage, mAh, vol_charge, vol_discharge, mass_charge, mass_discharge, frac_charge, frac_discharge, entries_charge, entries_discharge, working_ion_entry)
def from_steps(step1, step2, normalization_els): """ Creates a ConversionVoltagePair from two steps in the element profile from a PD analysis. Args: step1: Starting step step2: Ending step normalization_els: Elements to normalize the reaction by. To ensure correct capacities. """ working_ion_entry = step1["element_reference"] working_ion = working_ion_entry.composition.elements[0].symbol voltage = -step1["chempot"] + working_ion_entry.energy_per_atom mAh = (step2["evolution"] - step1["evolution"]) \ * ELECTRON_TO_AMPERE_HOURS * 1000 licomp = Composition.from_formula(working_ion) prev_rxn = step1["reaction"] reactants = { comp: abs(prev_rxn.get_coeff(comp)) for comp in prev_rxn.products if comp != licomp } curr_rxn = step2["reaction"] products = { comp: abs(curr_rxn.get_coeff(comp)) for comp in curr_rxn.products if comp != licomp } reactants[licomp] = (step2["evolution"] - step1["evolution"]) rxn = BalancedReaction(reactants, products) for el, amt in normalization_els.items(): if rxn.get_el_amount(el) != 0: rxn.normalize_to_element(el, amt) break prev_mass_dischg = sum([ prev_rxn.all_comp[i].weight * abs(prev_rxn.coeffs[i]) for i in xrange(len(prev_rxn.all_comp)) ]) / 2 vol_charge = sum([ abs(prev_rxn.get_coeff(e.composition)) * e.structure.volume for e in step1["entries"] if e.composition.reduced_formula != working_ion ]) mass_discharge = sum([ curr_rxn.all_comp[i].weight * abs(curr_rxn.coeffs[i]) for i in xrange(len(curr_rxn.all_comp)) ]) / 2 mass_charge = prev_mass_dischg mass_discharge = mass_discharge vol_discharge = sum([ abs(curr_rxn.get_coeff(e.composition)) * e.structure.volume for e in step2["entries"] if e.composition.reduced_formula != working_ion ]) totalcomp = Composition({}) for comp in prev_rxn.products: if comp.reduced_formula != working_ion: totalcomp += comp * abs(prev_rxn.get_coeff(comp)) frac_charge = totalcomp.get_atomic_fraction(Element(working_ion)) totalcomp = Composition({}) for comp in curr_rxn.products: if comp.reduced_formula != working_ion: totalcomp += comp * abs(curr_rxn.get_coeff(comp)) frac_discharge = totalcomp.get_atomic_fraction(Element(working_ion)) rxn = rxn entries_charge = step2["entries"] entries_discharge = step1["entries"] return ConversionVoltagePair(rxn, voltage, mAh, vol_charge, vol_discharge, mass_charge, mass_discharge, frac_charge, frac_discharge, entries_charge, entries_discharge, working_ion_entry)