Esempio n. 1
0
    def setUp(self):
        self.entry_Li = ComputedEntry("Li", -1.90753119)

        with open(os.path.join(test_dir, "LiTiO2_batt.json"), "r") as f:
            self.entries_LTO = json.load(f, cls=PMGJSONDecoder)

        self.ie_LTO = InsertionElectrode(self.entries_LTO, self.entry_Li)
Esempio n. 2
0
    def setUp(self):
        self.entry_Li = ComputedEntry("Li", -1.90753119)

        with open(os.path.join(test_dir, "LiTiO2_batt.json"), "r") as f:
            self.entries_LTO = json.load(f, cls=MontyDecoder)

        with open(os.path.join(test_dir, "MgVO_batt.json"), "r") as file:
            self.entries_MVO = json.load(file, cls=MontyDecoder)

        with open(os.path.join(test_dir, "Mg_batt.json"), "r") as file:
            self.entry_Mg = json.load(file, cls=MontyDecoder)

        self.ie_LTO = InsertionElectrode(self.entries_LTO, self.entry_Li)
        self.ie_MVO = InsertionElectrode(self.entries_MVO, self.entry_Mg)
    def setUp(self):
        self.entry_Li = ComputedEntry("Li", -1.90753119)

        with open(os.path.join(test_dir, "LiTiO2_batt.json"), "r") as f:
            self.entries_LTO = json.load(f, cls=MontyDecoder)

        with open(os.path.join(test_dir, "MgVO_batt.json"), "r") as file:
            self.entries_MVO = json.load(file, cls=MontyDecoder)

        with open(os.path.join(test_dir, "Mg_batt.json"), "r") as file:
            self.entry_Mg = json.load(file, cls=MontyDecoder)


        self.ie_LTO = InsertionElectrode(self.entries_LTO, self.entry_Li)
        self.ie_MVO = InsertionElectrode(self.entries_MVO, self.entry_Mg)
Esempio n. 4
0
    def setUp(self):
        self.entry_Li = ComputedEntry("Li", -1.90753119)

        with open(os.path.join(test_dir, "LiTiO2_batt.json"), "r") as f:
            self.entries_LTO = json.load(f, cls=PMGJSONDecoder)

        self.ie_LTO = InsertionElectrode(self.entries_LTO, self.entry_Li)
Esempio n. 5
0
 def from_entries(
     cls,
     grouped_entries: List[ComputedEntry],
     working_ion_entry: ComputedEntry,
     battery_id: str,
     host_structure: Structure,
 ) -> Union["InsertionElectrodeDoc", None]:
     try:
         ie = InsertionElectrode.from_entries(
             entries=grouped_entries,
             working_ion_entry=working_ion_entry,
             strip_structures=True,
         )
     except IndexError:
         return None
     d = ie.get_summary_dict()
     d["material_ids"] = d["stable_material_ids"] + d[
         "unstable_material_ids"]
     d["num_steps"] = d.pop("nsteps", None)
     d["last_updated"] = datetime.utcnow()
     elements = sorted(host_structure.composition.elements)
     chemsys = "-".join(sorted(map(str, elements)))
     framework = Composition(d["framework_formula"])
     return cls(battery_id=battery_id,
                host_structure=host_structure.as_dict(),
                framework=framework,
                electrode_object=ie.as_dict(),
                elements=elements,
                nelements=len(elements),
                chemsys=chemsys,
                formula_anonymous=framework.anonymized_formula,
                **d)
Esempio n. 6
0
def build_battery(e_l, wi):
    """build_battery
    Builds an InsertionElectrode from ComputedStructureEntries.
    :param s_l: List of entries for various states of charge.
    :param wi: Charge-carrier ion for the battery. (String)
    :return: An InsertionElectrode object.
    """
    with MPRester(mp_api) as m:
        wi_entry = m.get_entry_by_material_id(wi_ids[wi], inc_structure=True)
    return InsertionElectrode(e_l, wi_entry)
Esempio n. 7
0
    def setUp(self):
        entry_Li = ComputedEntry("Li", -1.90753119)

        with open(os.path.join(test_dir, "LiTiO2_batt.json"), "r") as f:
            entries_LTO = json.load(f, cls=MontyDecoder)
            self.ie_LTO = InsertionElectrode.from_entries(
                entries_LTO, entry_Li)

        with open(os.path.join(test_dir, "FeF3_batt.json"), "r") as fid:
            entries = json.load(fid, cls=MontyDecoder)
            self.ce_FF = ConversionElectrode.from_composition_and_entries(
                Composition("FeF3"), entries)
    def test_to_from_dict(self):
        d = self.ie_LTO.as_dict()
        ie = InsertionElectrode.from_dict(d)
        self.assertAlmostEqual(ie.max_voltage, 2.78583901, 3)
        self.assertAlmostEqual(ie.min_voltage, 0.89702381, 3)
        self.assertAlmostEqual(ie.get_average_voltage(), 1.84143141, 3)

        #Just to make sure json string works.
        json_str = json.dumps(self.ie_LTO, cls=MontyEncoder)
        ie = json.loads(json_str, cls=MontyDecoder)
        self.assertAlmostEqual(ie.max_voltage, 2.78583901, 3)
        self.assertAlmostEqual(ie.min_voltage, 0.89702381, 3)
        self.assertAlmostEqual(ie.get_average_voltage(), 1.84143141, 3)
Esempio n. 9
0
def insertion_elec(test_dir):
    """
    Recycle the test cases from pymatgen
    """
    entry_Li = ComputedEntry("Li", -1.90753119)
    # more cases can be added later if problems are found
    entries_LTO = loadfn(test_dir / "LiTiO2_batt.json")
    ie_LTO = InsertionElectrode.from_entries(entries_LTO, entry_Li)

    d = {
        "LTO": (ie_LTO, entries_LTO[0].structure, entry_Li),
    }
    return d
Esempio n. 10
0
class InsertionElectrodeTest(unittest.TestCase):
    def setUp(self):
        self.entry_Li = ComputedEntry("Li", -1.90753119)
        self.entry_Ca = ComputedEntry("Ca", -1.99689568)

        with open(os.path.join(test_dir, "LiTiO2_batt.json"), "r") as f:
            self.entries_LTO = json.load(f, cls=MontyDecoder)

        with open(os.path.join(test_dir, "MgVO_batt.json"), "r") as file:
            self.entries_MVO = json.load(file, cls=MontyDecoder)

        with open(os.path.join(test_dir, "Mg_batt.json"), "r") as file:
            self.entry_Mg = json.load(file, cls=MontyDecoder)

        with open(os.path.join(test_dir, "CaMoO2_batt.json"), "r") as f:
            self.entries_CMO = json.load(f, cls=MontyDecoder)

        self.ie_LTO = InsertionElectrode(self.entries_LTO, self.entry_Li)
        self.ie_MVO = InsertionElectrode(self.entries_MVO, self.entry_Mg)
        self.ie_CMO = InsertionElectrode(self.entries_CMO, self.entry_Ca)

    def test_voltage(self):
        #test basic voltage
        self.assertAlmostEqual(self.ie_LTO.max_voltage, 2.78583901, 3)
        self.assertAlmostEqual(self.ie_LTO.min_voltage, 0.89702381, 3)
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(), 1.84143141,
                               3)
        #test voltage range selectors
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(0, 1),
                               0.89702381, 3)
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(2, 3),
                               2.78583901, 3)
        #test non-existing voltage range
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(0, 0.1), 0, 3)
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(4, 5), 0, 3)

        self.assertAlmostEqual(self.ie_MVO.get_average_voltage(), 2.513767, 3)

    def test_capacities(self):
        #test basic capacity
        self.assertAlmostEqual(self.ie_LTO.get_capacity_grav(), 308.74865045,
                               3)
        self.assertAlmostEqual(self.ie_LTO.get_capacity_vol(), 1205.99391136,
                               3)

        #test capacity selector
        self.assertAlmostEqual(self.ie_LTO.get_capacity_grav(1, 3),
                               154.374325225, 3)

        #test alternate normalization option
        self.assertAlmostEqual(self.ie_LTO.get_capacity_grav(1, 3, False),
                               160.803169506, 3)
        self.assertIsNotNone(self.ie_LTO.as_dict_summary(True))

        self.assertAlmostEqual(self.ie_MVO.get_capacity_grav(), 281.845548242,
                               3)
        self.assertAlmostEqual(self.ie_MVO.get_capacity_vol(), 1145.80087994,
                               3)

    def test_get_instability(self):
        self.assertIsNone(self.ie_LTO.get_max_instability())
        self.assertAlmostEqual(self.ie_MVO.get_max_instability(),
                               0.7233711650000014)
        self.assertAlmostEqual(self.ie_MVO.get_min_instability(),
                               0.4913575099999994)

    def test_get_muO2(self):
        self.assertIsNone(self.ie_LTO.get_max_muO2())
        self.assertAlmostEqual(self.ie_MVO.get_max_muO2(), -4.93552791875)
        self.assertAlmostEqual(self.ie_MVO.get_min_muO2(), -11.06599657)

    def test_entries(self):
        #test that the proper number of sub-electrodes are returned
        self.assertEqual(len(self.ie_LTO.get_sub_electrodes(False, True)), 3)
        self.assertEqual(len(self.ie_LTO.get_sub_electrodes(True, True)), 2)

    def test_get_all_entries(self):
        self.ie_LTO.get_all_entries()

    def test_to_from_dict(self):
        d = self.ie_LTO.as_dict()
        ie = InsertionElectrode.from_dict(d)
        self.assertAlmostEqual(ie.max_voltage, 2.78583901, 3)
        self.assertAlmostEqual(ie.min_voltage, 0.89702381, 3)
        self.assertAlmostEqual(ie.get_average_voltage(), 1.84143141, 3)

        #Just to make sure json string works.
        json_str = json.dumps(self.ie_LTO, cls=MontyEncoder)
        ie = json.loads(json_str, cls=MontyDecoder)
        self.assertAlmostEqual(ie.max_voltage, 2.78583901, 3)
        self.assertAlmostEqual(ie.min_voltage, 0.89702381, 3)
        self.assertAlmostEqual(ie.get_average_voltage(), 1.84143141, 3)

    def test_voltage_pair(self):
        vpair = self.ie_LTO[0]
        self.assertAlmostEqual(vpair.voltage, 2.78583901)
        self.assertAlmostEqual(vpair.mAh, 13400.7411749, 2)
        self.assertAlmostEqual(vpair.mass_charge, 79.8658)
        self.assertAlmostEqual(vpair.mass_discharge, 83.3363)
        self.assertAlmostEqual(vpair.vol_charge, 37.553684467)
        self.assertAlmostEqual(vpair.vol_discharge, 37.917719932)
        self.assertAlmostEqual(vpair.frac_charge, 0.0)
        self.assertAlmostEqual(vpair.frac_discharge, 0.14285714285714285)

    def test_as_dict_summary(self):
        d = self.ie_CMO.as_dict_summary()
        self.assertAlmostEqual(d['stability_charge'], 0.2346574583333325)
        self.assertAlmostEqual(d['stability_discharge'], 0.33379544031249786)
        self.assertAlmostEqual(d['muO2_data']['mp-714969'][0]['chempot'],
                               -4.93552791875)
class InsertionElectrodeTest(unittest.TestCase):

    def setUp(self):
        self.entry_Li = ComputedEntry("Li", -1.90753119)

        with open(os.path.join(test_dir, "LiTiO2_batt.json"), "r") as f:
            self.entries_LTO = json.load(f, cls=MontyDecoder)

        with open(os.path.join(test_dir, "MgVO_batt.json"), "r") as file:
            self.entries_MVO = json.load(file, cls=MontyDecoder)

        with open(os.path.join(test_dir, "Mg_batt.json"), "r") as file:
            self.entry_Mg = json.load(file, cls=MontyDecoder)


        self.ie_LTO = InsertionElectrode(self.entries_LTO, self.entry_Li)
        self.ie_MVO = InsertionElectrode(self.entries_MVO, self.entry_Mg)

    def test_voltage(self):
        #test basic voltage
        self.assertAlmostEqual(self.ie_LTO.max_voltage, 2.78583901, 3)
        self.assertAlmostEqual(self.ie_LTO.min_voltage, 0.89702381, 3)
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(), 1.84143141,
                               3)
        #test voltage range selectors
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(0, 1),
                               0.89702381, 3)
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(2, 3),
                               2.78583901, 3)
        #test non-existing voltage range
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(0, 0.1), 0, 3)
        self.assertAlmostEqual(self.ie_LTO.get_average_voltage(4, 5), 0, 3)

        self.assertAlmostEqual(self.ie_MVO.get_average_voltage(), 2.513767,3)



    def test_capacities(self):
        #test basic capacity
        self.assertAlmostEqual(self.ie_LTO.get_capacity_grav(), 308.74865045,
                               3)
        self.assertAlmostEqual(self.ie_LTO.get_capacity_vol(), 1205.99391136,
                               3)

        #test capacity selector
        self.assertAlmostEqual(self.ie_LTO.get_capacity_grav(1, 3),
                               154.374325225, 3)

        #test alternate normalization option
        self.assertAlmostEqual(self.ie_LTO.get_capacity_grav(1, 3, False),
                               160.803169506, 3)
        self.assertIsNotNone(self.ie_LTO.as_dict_summary(True))

        self.assertAlmostEqual(self.ie_MVO.get_capacity_grav(), 281.845548242, 3)
        self.assertAlmostEqual(self.ie_MVO.get_capacity_vol(), 1145.80087994, 3)



    def test_get_muO2(self):
        self.assertIsNone(self.ie_LTO.get_max_muO2())

    def test_entries(self):
        #test that the proper number of sub-electrodes are returned
        self.assertEqual(len(self.ie_LTO.get_sub_electrodes(False, True)), 3)
        self.assertEqual(len(self.ie_LTO.get_sub_electrodes(True, True)), 2)

    def test_get_all_entries(self):
        self.ie_LTO.get_all_entries()

    def test_to_from_dict(self):
        d = self.ie_LTO.as_dict()
        ie = InsertionElectrode.from_dict(d)
        self.assertAlmostEqual(ie.max_voltage, 2.78583901, 3)
        self.assertAlmostEqual(ie.min_voltage, 0.89702381, 3)
        self.assertAlmostEqual(ie.get_average_voltage(), 1.84143141, 3)

        #Just to make sure json string works.
        json_str = json.dumps(self.ie_LTO, cls=MontyEncoder)
        ie = json.loads(json_str, cls=MontyDecoder)
        self.assertAlmostEqual(ie.max_voltage, 2.78583901, 3)
        self.assertAlmostEqual(ie.min_voltage, 0.89702381, 3)
        self.assertAlmostEqual(ie.get_average_voltage(), 1.84143141, 3)

    def test_voltage_pair(self):
        vpair = self.ie_LTO[0]
        self.assertAlmostEqual(vpair.voltage, 2.78583901)
        self.assertAlmostEqual(vpair.mAh, 13400.7411749, 2)
        self.assertAlmostEqual(vpair.mass_charge, 79.8658)
        self.assertAlmostEqual(vpair.mass_discharge, 83.3363)
        self.assertAlmostEqual(vpair.vol_charge, 37.553684467)
        self.assertAlmostEqual(vpair.vol_discharge, 37.917719932)
        self.assertAlmostEqual(vpair.frac_charge, 0.0)
        self.assertAlmostEqual(vpair.frac_discharge, 0.14285714285714285)
Esempio n. 12
0
    def process_item(self, item):
        """
        Read the entries from the thermo database and group them based on the reduced composition
        of the framework material (without working ion).
        Args:
            chemsys(string): the chemical system string to be queried
        returns:
            (chemsys, [group]): entry contains a list of entries the materials together by composition
        """
        # sort the entries intro subgroups
        # then perform PD analysis
        all_entries = item["all_entries"]
        pd_ents = item["pd_ents"]
        phdi = PhaseDiagram(pd_ents)

        # The working ion entries
        ents_wion = list(
            filter(
                lambda x: x.composition.get_integer_formula_and_factor()[0]
                == self.working_ion,
                pd_ents,
            )
        )
        self.working_ion_entry = min(ents_wion, key=lambda e: e.energy_per_atom)
        assert self.working_ion_entry != None

        grouped_entries = list(self.get_sorted_subgroups(all_entries))

        docs = []  # results

        for group in grouped_entries:
            self.logger.debug(
                f"Grouped entries in all sandboxes {', '.join([en.name for en in group])}"
            )
            for en in group:
                # skip this d_muO2 stuff if you do note have oxygen
                if Element("O") in en.composition.elements:
                    d_muO2 = [
                        {
                            "reaction": str(itr["reaction"]),
                            "chempot": itr["chempot"],
                            "evolution": itr["evolution"],
                        }
                        for itr in phdi.get_element_profile("O", en.composition)
                    ]
                else:
                    d_muO2 = None
                en.data["muO2"] = d_muO2
                en.data["decomposition_energy"] = phdi.get_e_above_hull(en)

            # sort out the sandboxes
            # for each sandbox core+sandbox will both contribute entries
            all_sbx = [ent.data["_sbxn"] for ent in group]
            all_sbx = set(chain.from_iterable(all_sbx))
            self.logger.debug(f"All sandboxes {', '.join(list(all_sbx))}")

            for isbx in all_sbx:
                group_sbx = list(
                    filter(
                        lambda ent: (isbx in ent.data["_sbxn"])
                        or (ent.data["_sbxn"] == ["core"]),
                        group,
                    )
                )
                self.logger.debug(
                    f"Grouped entries in sandbox {', '.join([en.name for en in group_sbx])}"
                )

                result = InsertionElectrode(group_sbx, self.working_ion_entry)

                spacegroup = SpacegroupAnalyzer(
                    result.get_stable_entries(charge_to_discharge=True)[0].structure
                )

                d = result.as_dict_summary()

                # d['stable_material_ids'] = [entry.entry_id
                #                        for entry in result.get_stable_entries()]
                # d['unstable_material_ids'] = [entry.entry_id
                #                             for entry in result.get_unstable_entries()]
                # d['stability_data'] = {entry.entry_id : entry.data['decomposition_energy']
                #                               for entry in result.get_all_entries()}
                # d['muO2_data'] = {entry.entry_id : entry.data['muO2']
                #                        for entry in result.get_all_entries()}

                # sort the ids based on value
                ids = [entry.entry_id for entry in result.get_all_entries()]
                lowest_id = sorted(ids, key=lambda x: x.split("-")[-1])[0]
                d["spacegroup"] = {
                    k: spacegroup._space_group_data[k] for k in sg_fields
                }

                if isbx == "core":
                    d["battid"] = lowest_id + "_" + self.working_ion
                else:
                    d["battid"] = lowest_id + "_" + self.working_ion + "_" + isbx
                # Only allow one sandbox value for each electrode
                d["_sbxn"] = [isbx]

                docs.append(d)

        return docs
Esempio n. 13
0
        discharge_struc = Structure.from_dict(dict_discharge["structure"])
        discharge_energy = dict_discharge["final_energy"]
        entry_discharge = ComputedStructureEntry(discharge_struc,
                                                 discharge_energy)
        discharge_ehull = dict_discharge["e_above_hull"]

        mpr = MPRester(api_key=API_KEY, host="www.materialsproject.org")
        entries = mpr.get_entries(result[0][1], inc_structure="final")

        counter = 0
        energies = []
        for entry in entries:
            energies.append(entry.energy_per_atom)
        working_ion_entry = entries[(energies.index(min(energies)))]

        cathode = InsertionElectrode([entry_charge, entry_discharge],
                                     working_ion_entry)

        batt_list.append(
            [result[0], result[1], result[2], charge_struc.formula,
             charge_ehull, discharge_struc.formula, discharge_ehull,
             cathode.max_voltage_step, cathode.get_average_voltage(),
             cathode.get_capacity_vol(), cathode.get_capacity_grav(),
             cathode.max_delta_volume])

voltage = []
capacity_grav = []
discharge_ehull = []
charge_ehull = []

for working_ion in working_ion_pool:
    ion_row = []
Esempio n. 14
0
<<<<<<< HEAD
                group_sbx = list(
                    filter(
                        lambda ent: (isbx in ent.data["_sbxn"])
                        or (ent.data["_sbxn"] == ["core"]),
                        group,
                    )
                )
                self.logger.debug(
                    f"Grouped entries in sandbox {', '.join([en.name for en in group_sbx])}"
                )
=======
                group_sbx = list(filter(lambda ent : (isbx in ent.data['_sbxn']) or (ent.data['_sbxn']==['core']), group))
                self.logger.debug(f"Grouped entries in sandbox {isbx} -- {', '.join([en.name for en in group_sbx])}")
>>>>>>> master
                result = InsertionElectrode(group_sbx, self.working_ion_entry)

                spacegroup = SpacegroupAnalyzer(
                    result.get_stable_entries(charge_to_discharge=True)[0].structure
                )

                d = result.as_dict_summary()

                # d['stable_material_ids'] = [entry.entry_id
                #                        for entry in result.get_stable_entries()]
                # d['unstable_material_ids'] = [entry.entry_id
                #                             for entry in result.get_unstable_entries()]
                # d['stability_data'] = {entry.entry_id : entry.data['decomposition_energy']
                #                               for entry in result.get_all_entries()}
                # d['muO2_data'] = {entry.entry_id : entry.data['muO2']
                #                        for entry in result.get_all_entries()}