Exemplo n.º 1
0
    def test_calculate_energy(self):

        reactants = [Composition.from_formula("MgO"), Composition.from_formula("Al2O3")]
        products = [Composition.from_formula("MgAl2O4")]
        energies = {Composition.from_formula("MgO"):-0.1, Composition.from_formula("Al2O3"):-0.2, Composition.from_formula("MgAl2O4"):-0.5}
        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "1.000 MgO + 1.000 Al2O3 -> 1.000 MgAl2O4", "Wrong reaction obtained!")
        self.assertEquals(rxn.normalized_repr, "MgO + Al2O3 -> MgAl2O4", "Wrong normalized reaction obtained!")
        self.assertAlmostEquals(rxn.calculate_energy(energies), -0.2, 5)
Exemplo n.º 2
0
 def test_equals(self):
     random_z = random.randint(1, 92)
     fixed_el = Element.from_Z(random_z)
     other_z = random.randint(1, 92)
     while other_z == random_z:
         other_z = random.randint(1, 92)
     comp1 = Composition({fixed_el:1, Element.from_Z(other_z) :0})
     other_z = random.randint(1, 92)
     while other_z == random_z:
         other_z = random.randint(1, 92)
     comp2 = Composition({fixed_el:1, Element.from_Z(other_z) :0})
     self.assertEqual(comp1, comp2, "Composition equality test failed. %s should be equal to %s" % (comp1.formula, comp2.formula))
     self.assertEqual(comp1.__hash__(), comp2.__hash__(), "Hashcode equality test failed!")
Exemplo n.º 3
0
 def __init__(self, composition, energy, correction=0.0, parameters=None, data=None):
     """
     Args:
         composition:
             Composition of the entry. For flexibility, this can take the form
             of a {symbol: amt} dictionary as well the standard pymatgen
             Composition object.
         energy:
             Energy of the entry. Usually the final calculated energy from
             VASP or other electronic structure codes.
         correction:
             A correction to be applied to the energy. This is used to modify
             the energy for certain analyses. Defaults to 0.0.
         parameters:
             An optional dict of parameters associated with the entry. Defaults
             to None.
         data:
             An optional dict of any additional data associated with 
             the entry. Defaults to None
     """
     if not isinstance(composition, Composition):
         comp = Composition.from_dict(composition)
     else:
         comp = composition
     super(ComputedEntry, self).__init__(comp, energy)
     self.correction = correction
     self.parameters = parameters if parameters else {}
     self.data = data if data else {}
Exemplo n.º 4
0
 def test_get_atoms(self):
     if not aio.ase_loaded:
         raise SkipTest("ASE not present. Skipping...")
     p = Poscar.from_file(os.path.join(test_dir, 'POSCAR'))
     structure = p.struct
     atoms = aio.AseAtomsAdaptor.get_atoms(structure)
     ase_composition = Composition.from_formula(atoms.get_name())
     self.assertEqual(ase_composition, structure.composition)
Exemplo n.º 5
0
    def test_init(self):
        rct = {Composition.from_formula('K2SO4'):3, Composition.from_formula('Na2S'):1, Composition.from_formula('Li'):24}
        prod = {Composition.from_formula('KNaS'): 2, Composition.from_formula('K2S'):2, Composition.from_formula('Li2O'):12}
        rxn = BalancedReaction(rct, prod)
        self.assertEquals(str(rxn), "24.000 Li + 1.000 Na2S + 3.000 K2SO4 -> 12.000 Li2O + 2.000 K2S + 2.000 KNaS")

        #Test unbalanced exception
        rct = {Composition.from_formula('K2SO4'):1, Composition.from_formula('Na2S'):1, Composition.from_formula('Li'):24}
        prod = {Composition.from_formula('KNaS'): 2, Composition.from_formula('K2S'):2, Composition.from_formula('Li2O'):12}
        self.assertRaises(ReactionError, BalancedReaction, rct, prod)
Exemplo n.º 6
0
    def test_init(self):
        filepath = os.path.join(test_dir, 'POSCAR')
        poscar = Poscar.from_file(filepath)
        comp = poscar.struct.composition
        self.assertEqual(comp, Composition.from_formula("Fe4P4O16"))

        #Vasp 4 type with symbols at the end.
        poscar_string = """Test1
1.0
3.840198 0.000000 0.000000
1.920099 3.325710 0.000000
0.000000 -2.217138 3.135509
1 1
direct
0.000000 0.000000 0.000000 Si
0.750000 0.500000 0.750000 F"""
        poscar = Poscar.from_string(poscar_string)
        self.assertEqual(poscar.struct.composition, Composition.from_formula("SiF"))

        #Vasp 4 tyle file with default names, i.e. no element symbol found.
        poscar_string = """Test2
1.0
3.840198 0.000000 0.000000
1.920099 3.325710 0.000000
0.000000 -2.217138 3.135509
1 1
direct
0.000000 0.000000 0.000000
0.750000 0.500000 0.750000"""
        poscar = Poscar.from_string(poscar_string)
        self.assertEqual(poscar.struct.composition, Composition.from_formula("HHe"))

        #Vasp 4 tyle file with default names, i.e. no element symbol found.
        poscar_string = """Test3
1.0
3.840198 0.000000 0.000000
1.920099 3.325710 0.000000
0.000000 -2.217138 3.135509
1 1
Selective dynamics
direct
0.000000 0.000000 0.000000 T T T Si
0.750000 0.500000 0.750000 F F F O"""
        poscar = Poscar.from_string(poscar_string)
        self.assertEqual(poscar.selective_dynamics, [[True, True, True], [False, False, False]])
Exemplo n.º 7
0
 def test_to_dict(self):
     c = Composition.from_dict({'Fe': 4, 'O': 6})
     d = c.to_dict
     correct_dict = {'Fe': 4.0, 'O': 6.0}
     self.assertEqual(d['Fe'], correct_dict['Fe'])
     self.assertEqual(d['O'], correct_dict['O'])
     correct_dict = {'Fe': 2.0, 'O': 3.0}
     d = c.to_reduced_dict
     self.assertEqual(d['Fe'], correct_dict['Fe'])
     self.assertEqual(d['O'], correct_dict['O'])
Exemplo n.º 8
0
    def _get_int_removals_helper(self, spec_amts_oxi, oxid_el, oxid_els, numa):
        """
        This is a helper method for get_removals_int_oxid!

        Args:
            spec_amts_oxi - a dict of species to their amounts in the structure
            oxid_el - the element to oxidize
            oxid_els - the full list of elements that might be oxidized
            numa - a running set of numbers of A cation at integer oxidation steps
        Returns:
            a set of numbers A; steps for for oxidizing oxid_el first, then the other oxid_els in this list
        """

        # If Mn is the oxid_el, we have a mixture of Mn2+, Mn3+, determine the minimum oxidation state for Mn
        #this is the state we want to oxidize!
        oxid_old = min([spec.oxi_state for spec in spec_amts_oxi if spec.symbol == oxid_el.symbol])
        oxid_new = math.floor(oxid_old + 1)
        #if this is not a valid solution, break out of here and don't add anything to the list
        if oxid_new > oxid_el.max_oxidation_state:
            return numa

        #update the spec_amts_oxi map to reflect that the oxidation took place
        spec_old = Specie(oxid_el.symbol, oxid_old)
        spec_new = Specie(oxid_el.symbol, oxid_new)
        specamt = spec_amts_oxi[spec_old]
        spec_amts_oxi = {sp: amt for sp, amt in spec_amts_oxi.items() if sp != spec_old}
        spec_amts_oxi[spec_new] = specamt
        spec_amts_oxi = Composition(spec_amts_oxi)

        #determine the amount of cation A in the structure needed for charge balance and add it to the list
        oxi_noA = sum([spec.oxi_state * spec_amts_oxi[spec] for spec in spec_amts_oxi if
                       spec.symbol not in self.cation.symbol])
        a = max(0, -oxi_noA / self.cation_charge)
        numa = numa.union({a})

        #recursively try the other oxidation states
        if a == 0:
            return numa
        else:
            for oxid_el in oxid_els:
                numa = numa.union(
                    self._get_int_removals_helper(spec_amts_oxi.copy(), oxid_el, oxid_els, numa))
            return numa
Exemplo n.º 9
0
    def test_get_data(self):
        props = ["energy", "energy_per_atom", "formation_energy_per_atom",
                 "nsites", "unit_cell_formula", "pretty_formula", "is_hubbard",
                 "elements", "nelements", "e_above_hull", "hubbards",
                 "is_compatible", "task_ids",
                 "density", "icsd_ids", "total_magnetization"]
        # unicode literals have been reintroduced in py>3.2
        expected_vals = [-191.33812137, -6.833504334642858, -2.551358929370749,
                         28, {k: v for k, v in {'P': 4, 'Fe': 4, 'O': 16, 'Li': 4}.items()},
                         "LiFePO4", True, ['Li', 'O', 'P', 'Fe'], 4, 0.0,
                         {k: v for k, v in {'Fe': 5.3, 'Li': 0.0, 'O': 0.0, 'P': 0.0}.items()}, True,
                         [u'mp-601412', u'mp-19017', u'mp-796535', u'mp-797820',
                          u'mp-540081', u'mp-797269'],
                         3.4662026991351147,
                         [159107, 154117, 160776, 99860, 181272, 166815,
                          260571, 92198, 165000, 155580, 38209, 161479, 153699,
                          260569, 260570, 200155, 260572, 181341, 181342,
                          72545, 56291, 97764, 162282, 155635],
                         16.0002716]

        for (i, prop) in enumerate(props):
            if prop not in ['hubbards', 'unit_cell_formula', 'elements',
                            'icsd_ids', 'task_ids']:
                val = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertAlmostEqual(expected_vals[i], val)
            elif prop in ["elements", "icsd_ids", "task_ids"]:
                self.assertEqual(set(expected_vals[i]),
                                 set(self.rester.get_data("mp-19017",
                                                          prop=prop)[0][prop]))
            else:
                self.assertEqual(expected_vals[i],
                                 self.rester.get_data("mp-19017",
                                                      prop=prop)[0][prop])

        props = ['structure', 'initial_structure', 'final_structure', 'entry']
        for prop in props:
            obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
            if prop.endswith("structure"):
                self.assertIsInstance(obj, Structure)
            elif prop == "entry":
                obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertIsInstance(obj, ComputedEntry)

        #Test chemsys search
        data = self.rester.get_data('Fe-Li-O', prop='unit_cell_formula')
        self.assertTrue(len(data) > 1)
        elements = {Element("Li"), Element("Fe"), Element("O")}
        for d in data:
            self.assertTrue(
                set(Composition(d['unit_cell_formula']).elements).issubset(
                    elements))

        self.assertRaises(MPRestError, self.rester.get_data, "Fe2O3",
                          "badmethod")
Exemplo n.º 10
0
def ion_or_solid_comp_object(formula):
    """
    Returns either an ion object or composition object given
    a formula.

    Args:
        formula: String formula. Eg. of ion: NaOH(aq), Na[+];
            Eg. of solid: Fe2O3(s), Fe(s), Na2O

    Returns:
        Composition/Ion object
    """
    m = re.search(r"\[([^\[\]]+)\]|\(aq\)", formula)
    if m:
        comp_obj = Ion.from_formula(formula)
    elif re.search(r"\(s\)", formula):
        comp_obj = Composition(formula[:-3])
    else:
        comp_obj = Composition(formula)
    return comp_obj
Exemplo n.º 11
0
def ion_or_solid_comp_object(formula):
    """
    Returns either an ion object or composition object given
    a formula.

    Args:
        formula: String formula. Eg. of ion: NaOH(aq), Na[+];
            Eg. of solid: Fe2O3(s), Fe(s), Na2O

    Returns:
        Composition/Ion object
    """
    m = re.search(r"\[([^\[\]]+)\]|\(aq\)", formula)
    if m:
        comp_obj = Ion.from_formula(formula)
    elif re.search(r"\(s\)", formula):
        comp_obj = Composition.from_formula(formula[:-3])
    else:
        comp_obj = Composition.from_formula(formula)
    return comp_obj
Exemplo n.º 12
0
 def test_indeterminate_formula(self):
     correct_formulas = []
     correct_formulas.append(["Co1"])
     correct_formulas.append(["Co1", "C1 O1"])
     correct_formulas.append(["Co2 O3", "C1 O5"])
     correct_formulas.append(["N1 Ca1 Lu1", "U1 Al1 C1 N1"])
     correct_formulas.append(["N1 Ca1 Lu1", "U1 Al1 C1 N1"])
     correct_formulas.append(["Li1 Co1 P2 N1 O10", "Li1 P2 C1 N1 O11", "Li1 Co1 Po8 N1 O2", "Li1 Po8 C1 N1 O3"])
     correct_formulas.append(["Co2 P4 O4", "P4 C2 O6", "Co2 Po4", "Po4 C2 O2"])
     correct_formulas.append([])
     for i, c in enumerate(correct_formulas):
         self.assertEqual([Composition.from_formula(comp) for comp in c], self.indeterminate_comp[i])
Exemplo n.º 13
0
    def test_products_reactants(self):
        reactants = [Composition.from_formula("Li3Fe2(PO4)3"), Composition.from_formula("Fe2O3"), Composition.from_formula("O2")]
        products = [Composition.from_formula("LiFePO4")]
        energies = {Composition.from_formula("Li3Fe2(PO4)3"):-0.1, Composition.from_formula("Fe2O3"):-0.2, Composition.from_formula("O2"):-0.2, Composition.from_formula("LiFePO4"):-0.5}
        rxn = Reaction(reactants, products)

        self.assertIn(Composition.from_formula("O2"), rxn.products, "O not in products!")
        self.assertIn(Composition.from_formula("Li3Fe2(PO4)3"), rxn.reactants, "Li3Fe2(PO4)4 not in reactants!")
        self.assertEquals(str(rxn), "0.333 Li3Fe2(PO4)3 + 0.167 Fe2O3 -> 0.250 O2 + 1.000 LiFePO4", "Wrong reaction obtained!")
        self.assertEquals(rxn.normalized_repr, "4 Li3Fe2(PO4)3 + 2 Fe2O3 -> 3 O2 + 12 LiFePO4", "Wrong normalized reaction obtained!")
        self.assertAlmostEquals(rxn.calculate_energy(energies), -0.48333333, 5)
Exemplo n.º 14
0
    def __str__(self):
        reactant_str = []
        product_str = []
        for i in range(self._num_comp):
            comp = self._all_comp[i]
            coeff = self._coeffs[i]
            red_comp = Composition.from_formula(comp.reduced_formula)
            scale_factor = comp.num_atoms / red_comp.num_atoms
            scaled_coeff = coeff * scale_factor
            if scaled_coeff < 0:
                reactant_str.append("%.3f %s" % (-scaled_coeff, comp.reduced_formula))
            elif scaled_coeff > 0:
                product_str.append("%.3f %s" % (scaled_coeff, comp.reduced_formula))

        return " + ".join(reactant_str) + " -> " + " + ".join(product_str)
    def get_only_sites(self):
        """
        Get a copy of the structure with only the sites

        Args:

        Returns:
          Structure: Structure with all possible migrating ion sites

        """
        migrating_ion_sites = list(
            filter(
                lambda site: site.species == Composition(
                    {self.migrating_specie: 1}), self.structure.sites))
        return Structure.from_sites(migrating_ion_sites)
Exemplo n.º 16
0
    def get_element_profile(self, element, comp):
        """
        Provides the element evolution data for a composition.
        For example, can be used to analyze Li conversion voltages by varying uLi and looking at the phases formed.
        Also can be used to analyze O2 evolution by varying uO2.
        
        Args:
            element:
                An element. Must be in the phase diagram.
            comp:
                A Composition
        
        Returns:
            Evolution data as a list of dictionaries of the following format: [ {'chempot': -10.487582010000001, 'evolution': -2.0, 'reaction': Reaction Object], ...]
        """
        if element not in self._pd.elements:
            raise ValueError("get_transition_chempots can only be called with elements in the phase diagram.")
        chempots = self.get_transition_chempots(element)
        stable_entries = self._pd.stable_entries
        gccomp = Composition({el:amt for el, amt in comp.items() if el != element})
        elref = self._pd.el_refs[element]
        elcomp = Composition.from_formula(element.symbol)
        prev_decomp = [];
        evolution = []
        def are_same_decomp(decomp1, decomp2):
            for comp in decomp2:
                if comp not in decomp1:
                    return False
            return True

        for c in chempots:
            gcpd = GrandPotentialPhaseDiagram(stable_entries, {element:c - 0.01}, self._pd.elements)
            analyzer = PDAnalyzer(gcpd)
            decomp = [gcentry.original_entry.composition for gcentry, amt in analyzer.get_decomposition(gccomp).items() if amt > 1e-5]
            decomp_entries = [gcentry.original_entry for gcentry, amt in analyzer.get_decomposition(gccomp).items() if amt > 1e-5]

            if not are_same_decomp(prev_decomp, decomp):
                if elcomp not in decomp:
                    decomp.insert(0, elcomp)
                rxn = Reaction([comp], decomp)
                rxn.normalize_to(comp)
                prev_decomp = decomp
                evolution.append({'chempot':c, 'evolution' :-rxn.coeffs[rxn.all_comp.index(elcomp)], 'element_reference': elref, 'reaction':rxn, 'entries':decomp_entries})

        return evolution
Exemplo n.º 17
0
    def test_get_data(self):
        props = ["energy", "energy_per_atom", "formation_energy_per_atom",
                 "nsites", "unit_cell_formula", "pretty_formula", "is_hubbard",
                 "elements", "nelements", "e_above_hull", "hubbards",
                 "is_compatible", "task_ids",
                 "density", "icsd_id", "total_magnetization"]
        expected_vals = [-191.33812137, -6.833504334642858, -2.5532843405078913,
                         28, {u'P': 4, u'Fe': 4, u'O': 16, u'Li': 4},
                         "LiFePO4", True, [u'Li', u'O', u'P', u'Fe'], 4, 0.0,
                         {u'Fe': 5.3, u'Li': 0.0, u'O': 0.0, u'P': 0.0}, True,
                         [540081, 19017], 3.4662026991351147, 56291, 16.0001687]

        for (i, prop) in enumerate(props):
            if prop not in ['hubbards', 'unit_cell_formula', 'elements']:
                val = self.rester.get_data(540081, prop=prop)[0][prop]
                self.assertAlmostEqual(expected_vals[i], val)
            elif prop == "elements":
                self.assertEqual(set(expected_vals[i]),
                                 set(self.rester.get_data(540081,
                                                          prop=prop)[0][prop]))
            else:
                self.assertEqual(expected_vals[i],
                                 self.rester.get_data(540081,
                                                      prop=prop)[0][prop])

        props = ['structure', 'initial_structure', 'final_structure', 'entry']
        for prop in props:
            obj = self.rester.get_data(540081, prop=prop)[0][prop]
            if prop.endswith("structure"):
                self.assertIsInstance(obj, Structure)
            elif prop == "entry":
                obj = self.rester.get_data(540081, prop=prop)[0][prop]
                self.assertIsInstance(obj, ComputedEntry)

        #Test chemsys search
        data = self.rester.get_data('Fe-Li-O', prop='unit_cell_formula')
        self.assertTrue(len(data) > 1)
        elements = {Element("Li"), Element("Fe"), Element("O")}
        for d in data:
            self.assertTrue(
                set(Composition(d['unit_cell_formula']).elements).issubset(
                    elements))

        self.assertRaises(MPRestError, self.rester.get_data, "Fe2O3",
                          "badmethod")
Exemplo n.º 18
0
    def from_csv(filename):
        """
        Imports PourbaixEntries from a csv.

        Args:
            filename - Filename to import from.

        Returns:
            List of Entries
        """
        import csv
        reader = csv.reader(open(filename, "rb"),
                            delimiter=",",
                            quotechar="\"",
                            quoting=csv.QUOTE_MINIMAL)
        entries = list()
        header_read = False
        for row in reader:
            if not header_read:
                elements = row[1:(len(row) - 4)]
                header_read = True
            else:
                name = row[0]
                energy = float(row[-4])
                conc = float(row[-1])
                comp = dict()
                for ind in range(1, len(row) - 4):
                    if float(row[ind]) > 0:
                        comp[Element(elements[ind - 1])] = float(row[ind])
                phase_type = row[-3]
                if phase_type == "Ion":
                    PoE = PourbaixEntry(
                        IonEntry(Ion.from_formula(name), energy))
                    PoE.set_conc(conc)
                    PoE.set_name(name)
                    entries.append(PoE)
                else:
                    entries.append(
                        PourbaixEntry(PDEntry(Composition(comp), energy)))
        elements = [Element(el) for el in elements]
        return elements, entries
Exemplo n.º 19
0
    def test_get_data(self):
        props = [
            "energy", "energy_per_atom", "formation_energy_per_atom", "nsites",
            "unit_cell_formula", "pretty_formula", "is_hubbard", "elements",
            "nelements", "e_above_hull", "hubbards", "is_compatible",
            "task_ids", "density", "icsd_ids", "total_magnetization"
        ]

        expected_vals = [
            -191.3359011, -6.833425039285714, -2.5515769497278913, 28, {
                'P': 4,
                'Fe': 4,
                'O': 16,
                'Li': 4
            }, "LiFePO4", True, ['Li', 'O', 'P', 'Fe'], 4, 0.0, {
                'Fe': 5.3,
                'Li': 0.0,
                'O': 0.0,
                'P': 0.0
            }, True, {'mp-19017', 'mp-540081', 'mp-601412'}, 3.464840709092822,
            [
                159107, 154117, 160776, 99860, 181272, 166815, 260571, 92198,
                165000, 155580, 38209, 161479, 153699, 260569, 260570, 200155,
                260572, 181341, 181342, 72545, 56291, 97764, 162282, 155635
            ], 3.999999999
        ]

        for (i, prop) in enumerate(props):
            if prop not in [
                    'hubbards', 'unit_cell_formula', 'elements', 'icsd_ids',
                    'task_ids'
            ]:
                val = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertAlmostEqual(expected_vals[i], val, 2,
                                       "Failed with property %s" % prop)
            elif prop in ["elements", "icsd_ids", "task_ids"]:
                upstream_vals = set(
                    self.rester.get_data("mp-19017", prop=prop)[0][prop])
                self.assertLessEqual(set(expected_vals[i]), upstream_vals)
            else:
                self.assertEqual(
                    expected_vals[i],
                    self.rester.get_data("mp-19017", prop=prop)[0][prop])

        props = ['structure', 'initial_structure', 'final_structure', 'entry']
        for prop in props:
            obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
            if prop.endswith("structure"):
                self.assertIsInstance(obj, Structure)
            elif prop == "entry":
                obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertIsInstance(obj, ComputedEntry)

        # Test chemsys search
        data = self.rester.get_data('Fe-Li-O', prop='unit_cell_formula')
        self.assertTrue(len(data) > 1)
        elements = {Element("Li"), Element("Fe"), Element("O")}
        for d in data:
            self.assertTrue(
                set(Composition(
                    d['unit_cell_formula']).elements).issubset(elements))

        self.assertRaises(MPRestError, self.rester.get_data, "Fe2O3",
                          "badmethod")

        # Test getting supported properties
        self.assertNotEqual(self.rester.get_task_data("mp-30"), [])
        # Test aliasing
        data = self.rester.get_task_data("mp-30", "energy")
        self.assertAlmostEqual(data[0]["energy"], -4.09929227, places=2)
Exemplo n.º 20
0
    def test_get_data(self):
        props = {
            "energy",
            "energy_per_atom",
            "formation_energy_per_atom",
            "nsites",
            "unit_cell_formula",
            "pretty_formula",
            "is_hubbard",
            "elements",
            "nelements",
            "e_above_hull",
            "hubbards",
            "is_compatible",
            "task_ids",
            "density",
            "icsd_ids",
            "total_magnetization",
        }
        mpid = "mp-1143"
        vals = requests.get(
            f"http://legacy.materialsproject.org/materials/{mpid}/json/")
        expected_vals = vals.json()

        for prop in props:
            if prop not in [
                    "hubbards",
                    "unit_cell_formula",
                    "elements",
                    "icsd_ids",
                    "task_ids",
            ]:
                val = self.rester.get_data(mpid, prop=prop)[0][prop]
                if prop in ["energy", "energy_per_atom"]:
                    prop = "final_" + prop
                self.assertAlmostEqual(expected_vals[prop], val, 2,
                                       f"Failed with property {prop}")
            elif prop in ["elements", "icsd_ids", "task_ids"]:
                upstream_vals = set(
                    self.rester.get_data(mpid, prop=prop)[0][prop])
                self.assertLessEqual(set(expected_vals[prop]), upstream_vals)
            else:
                self.assertEqual(
                    expected_vals[prop],
                    self.rester.get_data(mpid, prop=prop)[0][prop],
                )

        props = ["structure", "initial_structure", "final_structure", "entry"]
        for prop in props:
            obj = self.rester.get_data(mpid, prop=prop)[0][prop]
            if prop.endswith("structure"):
                self.assertIsInstance(obj, Structure)
            elif prop == "entry":
                obj = self.rester.get_data(mpid, prop=prop)[0][prop]
                self.assertIsInstance(obj, ComputedEntry)

        # Test chemsys search
        data = self.rester.get_data("Fe-Li-O", prop="unit_cell_formula")
        self.assertTrue(len(data) > 1)
        elements = {Element("Li"), Element("Fe"), Element("O")}
        for d in data:
            self.assertTrue(
                set(Composition(
                    d["unit_cell_formula"]).elements).issubset(elements))

        self.assertRaises(MPRestError, self.rester.get_data, "Fe2O3",
                          "badmethod")
Exemplo n.º 21
0
    def test_get_data(self):
        props = [
            "energy",
            "energy_per_atom",
            "formation_energy_per_atom",
            "nsites",
            "unit_cell_formula",
            "pretty_formula",
            "is_hubbard",
            "elements",
            "nelements",
            "e_above_hull",
            "hubbards",
            "is_compatible",
            "task_ids",
            "density",
            "icsd_ids",
            "total_magnetization",
        ]

        expected_vals = [
            -191.7661349,
            -6.848790532142857,
            -2.5571951564625857,
            28,
            {
                "P": 4,
                "Fe": 4,
                "O": 16,
                "Li": 4
            },
            "LiFePO4",
            True,
            ["Li", "O", "P", "Fe"],
            4,
            0.0,
            {
                "Fe": 5.3,
                "Li": 0.0,
                "O": 0.0,
                "P": 0.0
            },
            True,
            {"mp-19017", "mp-540081", "mp-601412"},
            3.4708958823634912,
            [
                159107,
                154117,
                160776,
                99860,
                181272,
                166815,
                260571,
                92198,
                165000,
                155580,
                38209,
                161479,
                153699,
                260569,
                260570,
                200155,
                260572,
                181341,
                181342,
                72545,
                56291,
                97764,
                162282,
                155635,
            ],
            0,
        ]

        for (i, prop) in enumerate(props):
            if prop not in [
                    "hubbards",
                    "unit_cell_formula",
                    "elements",
                    "icsd_ids",
                    "task_ids",
            ]:
                val = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertAlmostEqual(expected_vals[i], val, 2,
                                       "Failed with property %s" % prop)
            elif prop in ["elements", "icsd_ids", "task_ids"]:
                upstream_vals = set(
                    self.rester.get_data("mp-19017", prop=prop)[0][prop])
                self.assertLessEqual(set(expected_vals[i]), upstream_vals)
            else:
                self.assertEqual(
                    expected_vals[i],
                    self.rester.get_data("mp-19017", prop=prop)[0][prop],
                )

        props = ["structure", "initial_structure", "final_structure", "entry"]
        for prop in props:
            obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
            if prop.endswith("structure"):
                self.assertIsInstance(obj, Structure)
            elif prop == "entry":
                obj = self.rester.get_data("mp-19017", prop=prop)[0][prop]
                self.assertIsInstance(obj, ComputedEntry)

        # Test chemsys search
        data = self.rester.get_data("Fe-Li-O", prop="unit_cell_formula")
        self.assertTrue(len(data) > 1)
        elements = {Element("Li"), Element("Fe"), Element("O")}
        for d in data:
            self.assertTrue(
                set(Composition(
                    d["unit_cell_formula"]).elements).issubset(elements))

        self.assertRaises(MPRestError, self.rester.get_data, "Fe2O3",
                          "badmethod")

        # Test getting supported properties
        self.assertNotEqual(self.rester.get_task_data("mp-30"), [])
        # Test aliasing
        data = self.rester.get_task_data("mp-30", "energy")
        self.assertAlmostEqual(data[0]["energy"], -4.09929227, places=2)
Exemplo n.º 22
0
def curate_cifstring(cifstring):
    """
    :return
    integrity_class
        3 can run all calculations
        2 can only run geometric analyses
        1 do not run any calculations (exception)
    outputs
        files written by this function
    structural_schemas
        structural_schemas['configuration']: the major config
        structural_schemas['molgraphs']: a list of unique molgraphs from the major config, rsorted by # of atoms
        structural_schemas['molsmiles']: a list of unique molecular smiles from the major config, rsorted by # of atoms
    identifier
        hashconfig(major_config)
    """
    integrity_class = 3
    outputs = []
    structural_schemas = OrderedDict()
    dp = DisParser(cifstring)
    try:
        print('--- begin DisParser.to_configs ---')
        dis_pstructure, dis_unwrap_str, dis_mols, config_infos = dp.to_configs(
            write_files=True, vanilla=True
        )  # if True writes conf_x.cif, configs is a list of pmg Structure
    except:
        emsg = 'ERROR: dp.to_configs failed!'
        print(emsg)
        raise CuratorError(emsg)
    if len(config_infos) not in [1, 2]:
        emsg = 'ERROR: vanilla to_configs found too many configs'
        print(emsg)
        raise CuratorError(emsg)
    disorder_class = dp.classification
    print('disorder class: {}'.format(disorder_class))
    print('--- end DisParser.to_configs ---\n')

    print('--- begin composition check ---')
    try:
        cif_comp = Composition(dp.cifdata['_chemical_formula_sum'])
        print('_chemical_formula_sum: {}'.format(cif_comp))
    except (KeyError, CompositionError) as e:
        cif_comp = None
        print(
            WEAK_WMSG.format(
                '_chemical_formula_sum does not exist or cannot be parsed'))
    try:
        comp_str = dp.cifdata['_chemical_formula_moiety']
        moiety_comps = [Composition(s) for s in comp_str.split(',')]
        moiety_comps = sorted(moiety_comps, key=lambda x: len(x), reverse=True)
        print('_chemical_formula_moiety:')
        for moiety_comp in moiety_comps:
            print('-- {}'.format(moiety_comp))
    except (KeyError, CompositionError) as e:
        print(
            WEAK_WMSG.format(
                '_chemical_formula_moiety does not exist or cannot be parsed'))
    major_config_structure, major_occu = config_infos[0]
    print('major config comps: {}'.format(major_config_structure.composition))
    print('major config occu: {}'.format(major_occu))
    if isinstance(cif_comp, Composition):
        if not major_config_structure.composition == cif_comp:
            print(
                WEAK_WMSG.format(
                    'major comps does not match _chemical_formula_sum'))
    try:
        minor_config_structure, minor_occu = config_infos[1]
        print('minor config comps: {}'.format(
            minor_config_structure.composition))
        print('minor config occu: {}'.format(minor_occu))
        major_minor_comps_match = minor_config_structure.composition == major_config_structure
        if major_minor_comps_match:
            print(WEAK_WMSG.format('minor and major comps do not match'))
    except IndexError:
        pass
    print('--- end composition check ---\n')

    print('--- begin major config check ---')
    try:
        major_config = Config.from_labeled_clean_pstructure(
            major_config_structure, major_occu)
    except:
        emsg = 'ERROR: cannot parse major config structure into a config!'
        print(emsg)
        raise CuratorError(emsg)
    structural_schemas['configuration'] = major_config.as_dict()
    major_config_cif = 'curated_major_config.cif'
    major_config.pstructure.to('cif', major_config_cif)
    outputs.append('{}/{}'.format(os.getcwd(), major_config_cif))
    if not major_config.molconformers_all_legit():
        emsg = 'ERROR: cannot convert all molconformers to rdkit mol'
        print(emsg)
        raise CuratorError(emsg)

    print('major config moiety comps:')
    mc: MolConformer
    max_nradicals = 0

    imc = 0
    for mc in major_config.molconformers:
        print('  -- imc {}: {}'.format(imc, mc.composition))
        try:
            rdmol, smiles, _, _ = mc.to_rdmol(charged_fragments=False)
            Chem.SanitizeMol(rdmol)
        except:
            print(
                WMSG.format(
                    'rdmol sanitize failed, integrity_class is set to 2'))
            if integrity_class > 2:
                integrity_class = 2
        nradicals = mc.is_missing_hydrogen()
        print('     missing hydrogen: {}'.format(nradicals))
        mc_xyzfils = 'curated_molconformer_{}_{}.xyz'.format(imc, nradicals)
        mc.to('xyz', mc_xyzfils)
        outputs.append(mc_xyzfils)
        if nradicals > max_nradicals:
            max_nradicals = nradicals
        imc += 1

    molsmiles = []
    for mc in sorted(major_config.molconformers,
                     key=lambda x: len(x),
                     reverse=True):
        # imol == imc, imol is not assigned based on len(mc), so use another for loop to do this
        molsmiles.append(mc.smiles)
    structural_schemas['molsmiles'] = list(set(molsmiles))

    if max_nradicals:
        print(
            WMSG.format(
                'major config missing hydrogen, integrity_class is set to 2'))
        if integrity_class > 2:
            integrity_class = 2

    unique_molgraphs = major_config.molgraph_set()
    structural_schemas['molgraphs'] = [
        umg.as_dict()
        for umg in sorted(list(unique_molgraphs), key=lambda x: len(x))
    ]
    if len(unique_molgraphs) > 1:
        emsg = 'ERROR: more than one unique molecule in the major config!'
        print(emsg)
        raise CuratorError(emsg)
    print('--- end major config check ---\n')

    print('integrity_class: {}'.format(integrity_class))
    return integrity_class, outputs, structural_schemas, major_config.hashconfig(
    )
Exemplo n.º 23
0
    def read(self):
        dis_pstructure, dis_unwrap_str, dis_mols, config_infos = self.dp.to_configs(write_files=False, vanilla=True)  # if True writes conf_x.cif, configs is a list of pmg Structure
        self.disorder_class = self.dp.classification
        self.results['disordered_pstructure'] = dis_unwrap_str
        self.results['disordered_pmgmols'] = dis_mols

        config_structures = []
        config_occupancies = []
        for item in config_infos:
            config_structures.append(item[0])
            config_occupancies.append(item[1])

        self.results['config_sturcutures'] = config_structures
        self.results['config_occupancies'] = config_occupancies


        configs = []
        missh = []
        for i in range(len(config_structures)):
            structure = config_structures[i]
            conf = Config.from_labeled_clean_pstructure(structure, occu=config_occupancies[i])
            config_missingh = False
            for conformer in conf.molconformers:
                if conformer.is_missing_hydrogen():
                    config_missingh = True
                    break
            if config_missingh:
                conf.pstructure.to('cif', '{}_mhconf_{}.cif'.format(self.identifier, i))
                warnings.warn('missing hydrogens in {}_mhconf_{}.cif'.format(self.identifier, i))
            configs.append(conf)
            missh.append(config_missingh)
        self.results['configurations'] = configs
        self.results['missingh'] = missh

        # these are checked against to configs[0]
        check_config = configs[0]
        try:
            self.results['n_unique_molecule'] = len(check_config.molgraph_set())
            self.results['n_molconformers'] = len(check_config.molconformers)
            self.results['all_molconformers_legit'] = check_config.molconformers_all_legit()
            self.results['disorder_location'] = self.where_is_disorder(check_config)
        except:
            warnings.warn('there are problems in readcif.results, some fileds will be missing!')
        
        try:
            comp = Composition(self.dp.cifdata['_chemical_formula_sum'])
            self.results['cif_sum_composition'] = comp
            if not all(self.results['cif_sum_composition'] == mc.composition for mc in check_config.molconformers):
                self.results['sum_composition_match'] = False
                print('cif_sum_composition: {}'.format(self.results['cif_sum_composition']))
                for mc in check_config.molconformers:
                    print('mc composition: {}'.format(mc.composition))
                warnings.warn('moiety sum composition does not match that specified in cif file!')
            else:
                self.results['sum_composition_match'] = True
        except (KeyError, CompositionError) as e:
            self.results['cif_sum_composition'] = None
            self.results['sum_composition_match'] = None

        try:
            comp_str = self.dp.cifdata['_chemical_formula_moiety']
            comps = [Composition(s) for s in comp_str.split(',')]
            comps = sorted(comps, key=lambda x:len(x), reverse=True)
            if len(comps) > 1:
                warnings.warn('more than 1 moiety from cif file! only the largest one is checked!')
            self.results['cif_moiety_composition'] = comps[0]
            if not all(self.results['cif_moiety_composition'] == mc.composition for mc in check_config.molconformers):
                self.results['moiety_composition_match'] = False
                print('cif_moiety_composition: {}'.format(self.results['cif_moiety_composition']))
                for mc in check_config.molconformers:
                    print('mc composition: {}'.format(mc.composition))
                warnings.warn('moiety composition does not match that specified in cif file!')
            else:
                self.results['moiety_composition_match'] = True
        except (KeyError, CompositionError) as e:
            self.results['cif_moiety_composition'] = None
            self.results['moiety_composition_match'] = None
Exemplo n.º 24
0
    def __init__(self, struct):
        """
        Args:
            struct:
                A pymatgen.core.structure.Structure object.
        """
        block = CifFile.CifBlock()
        latt = struct.lattice
        comp = struct.composition
        no_oxi_comp = Composition.from_formula(comp.formula)
        block['_symmetry_space_group_name_H-M'] = 'P 1'
        block['_cell_length_a'] = str(latt.a)
        block['_cell_length_b'] = str(latt.b)
        block['_cell_length_c'] = str(latt.c)
        block['_cell_angle_alpha'] = str(latt.alpha)
        block['_cell_angle_beta'] = str(latt.beta)
        block['_cell_angle_gamma'] = str(latt.gamma)
        block['_chemical_name_systematic'] = "Generated by pymatgen"
        block['_symmetry_Int_Tables_number'] = 1
        block['_chemical_formula_structural'] = str(no_oxi_comp.reduced_formula)
        block['_chemical_formula_sum'] = str(no_oxi_comp.formula)
        block['_cell_volume'] = str(latt.volume)

        reduced_comp = Composition.from_formula(no_oxi_comp.reduced_formula)
        el = no_oxi_comp.elements[0]
        amt = comp[el]
        fu = int(amt / reduced_comp[Element(el.symbol)])

        block['_cell_formula_units_Z'] = str(fu)
        block.AddCifItem(([['_symmetry_equiv_pos_site_id', '_symmetry_equiv_pos_as_xyz']], [[['1'], ['x, y, z']]]))

        contains_oxidation = True
        symbol_to_oxinum = dict()
        try:
            symbol_to_oxinum = {str(el):el.oxi_state for el in comp.elements}
        except:
            symbol_to_oxinum = {el.symbol:0 for el in comp.elements}
            contains_oxidation = False
        if contains_oxidation:
            block.AddCifItem(([['_atom_type_symbol', '_atom_type_oxidation_number']], [[symbol_to_oxinum.keys(), symbol_to_oxinum.values()]]))

        atom_site_type_symbol = []
        atom_site_symmetry_multiplicity = []
        atom_site_fract_x = []
        atom_site_fract_y = []
        atom_site_fract_z = []
        atom_site_attached_hydrogens = []
        atom_site_B_iso_or_equiv = []
        atom_site_label = []
        atom_site_occupancy = []
        count = 1
        for site in struct:
            for sp, occu in site.species_and_occu.items():
                atom_site_type_symbol.append(str(sp))
                atom_site_symmetry_multiplicity.append('1')
                atom_site_fract_x.append(str('{0:f}'.format(site.a)))
                atom_site_fract_y.append(str('{0:f}'.format(site.b)))
                atom_site_fract_z.append(str('{0:f}'.format(site.c)))
                atom_site_attached_hydrogens.append('0')
                atom_site_B_iso_or_equiv.append('.')
                atom_site_label.append(str(sp.symbol) + str(count))
                atom_site_occupancy.append(str(occu))
                count += 1


        block['_atom_site_type_symbol'] = atom_site_type_symbol
        block.AddToLoop('_atom_site_type_symbol', {'_atom_site_label':atom_site_label})
        block.AddToLoop('_atom_site_type_symbol', {'_atom_site_symmetry_multiplicity':atom_site_symmetry_multiplicity})
        block.AddToLoop('_atom_site_type_symbol', {'_atom_site_fract_x':atom_site_fract_x})
        block.AddToLoop('_atom_site_type_symbol', {'_atom_site_fract_y':atom_site_fract_y})
        block.AddToLoop('_atom_site_type_symbol', {'_atom_site_fract_z':atom_site_fract_z})
        block.AddToLoop('_atom_site_type_symbol', {'_atom_site_attached_hydrogens':atom_site_attached_hydrogens})
        block.AddToLoop('_atom_site_type_symbol', {'_atom_site_B_iso_or_equiv':atom_site_B_iso_or_equiv})
        block.AddToLoop('_atom_site_type_symbol', {'_atom_site_occupancy':atom_site_occupancy})

        self._cf = CifFile.CifFile()
        self._cf[comp.reduced_formula] = block
Exemplo n.º 25
0
    def apply_transformation(self, structure, return_ranked_list=False):
        # Make a mutable structure first
        mods = Structure.from_sites(structure)
        for sp, spin in self.mag_species_spin.items():
            sp = get_el_sp(sp)
            oxi_state = getattr(sp, "oxi_state", 0)
            if spin:
                up = Specie(sp.symbol, oxi_state, {"spin": abs(spin)})
                down = Specie(sp.symbol, oxi_state, {"spin": -abs(spin)})
                mods.replace_species({
                    sp:
                    Composition({
                        up: self.order_parameter,
                        down: 1 - self.order_parameter
                    })
                })
            else:
                mods.replace_species(
                    {sp: Specie(sp.symbol, oxi_state, {"spin": spin})})

        if mods.is_ordered:
            return [mods] if return_ranked_list > 1 else mods

        enum_args = self.kwargs

        enum_args["min_cell_size"] = max(
            int(
                MagOrderingTransformation.determine_min_cell(
                    structure, self.mag_species_spin, self.order_parameter)),
            enum_args.get("min_cell_size", 1))

        max_cell = enum_args.get('max_cell_size')
        if max_cell:
            if enum_args["min_cell_size"] > max_cell:
                raise ValueError('Specified max cell size is smaller'
                                 ' than the minimum enumerable cell size')
        else:
            enum_args["max_cell_size"] = enum_args["min_cell_size"]

        t = EnumerateStructureTransformation(**enum_args)

        alls = t.apply_transformation(mods,
                                      return_ranked_list=return_ranked_list)

        try:
            num_to_return = int(return_ranked_list)
        except ValueError:
            num_to_return = 1

        if num_to_return == 1 or not return_ranked_list:
            return alls[0]["structure"] if num_to_return else alls

        m = StructureMatcher(comparator=SpinComparator())
        key = lambda x: SpacegroupAnalyzer(x, 0.1).get_space_group_number()
        out = []
        for _, g in groupby(sorted([d["structure"] for d in alls], key=key),
                            key):
            g = list(g)
            grouped = m.group_structures(g)
            out.extend([{
                "structure": g[0],
                "energy": self.energy_model.get_energy(g[0])
            } for g in grouped])

        self._all_structures = sorted(out, key=lambda d: d["energy"])

        return self._all_structures[0:num_to_return]
Exemplo n.º 26
0
Created on Wed Feb 28 15:40:02 2018

@author: jherfson
"""
from pymatgen.analysis.pourbaix.entry import PourbaixEntry, IonEntry  #, MultiEntry
from pymatgen.analysis.pourbaix.entry import PourbaixEntryIO
from pymatgen.analysis.phase_diagram import PDEntry
from pymatgen.core.ion import Ion
from pymatgen.core.structure import Composition

Zn_solids = ["Zn", "ZnO", "ZnO2"]
sol_g = [0.0, -3.338, -1.315]
Zn_ions = ["Zn[2+]", "ZnOH[+]", "HZnO2[-]", "ZnO2[2-]", "ZnO"]
liq_g = [-1.527, -3.415, -4.812, -4.036, -2.921]
liq_conc = [1e-6, 1e-6, 1e-6, 1e-6, 1e-6]
solid_entry = list()
for sol in Zn_solids:
    comp = Composition(sol)
    delg = sol_g[Zn_solids.index(sol)]
    solid_entry.append(PourbaixEntry(PDEntry(comp, delg)))
ion_entry = list()
for ion in Zn_ions:
    comp_ion = Ion.from_formula(ion)
    delg = liq_g[Zn_ions.index(ion)]
    conc = liq_conc[Zn_ions.index(ion)]
    PoE = PourbaixEntry(IonEntry(comp_ion, delg))
    PoE.conc = conc
    ion_entry.append(PoE)
entries = solid_entry + ion_entry
PourbaixEntryIO.to_csv("pourbaix_test_entries.csv", entries)
Exemplo n.º 27
0
 def test_get_decomposition(self):
     for entry in self.pd.stable_entries:
         self.assertEquals(len(self.analyzer.get_decomposition(entry.composition)), 1, "Stable composition should have only 1 decomposition!")
     dim = len(self.pd.elements)
     for entry in self.pd.all_entries:
         ndecomp = len(self.analyzer.get_decomposition(entry.composition))
         self.assertTrue(ndecomp > 0 and ndecomp <= dim, "The number of decomposition phases can at most be equal to the number of components.")
     
     #Just to test decomp for a ficitious composition
     ansdict = {entry.composition.formula: amt for entry, amt in self.analyzer.get_decomposition(Composition.from_formula("Li3Fe7O11")).items()}
     expected_ans = {"Fe2 O2" : 0.0952380952380949, "Li1 Fe1 O2": 0.5714285714285714, "Fe6 O8": 0.33333333333333393}
     for k, v in expected_ans.items():
         self.assertAlmostEqual(ansdict[k], v)
Exemplo n.º 28
0
 def test_sub(self):
     self.assertEqual((self.comp[0] - Composition.from_formula("Li2O")).formula, "Li1 Fe2 P3 O11", "Incorrect composition after addition!")
     self.assertEqual((self.comp[0] - {"Fe":2, "O":3}).formula, "Li3 P3 O9")
Exemplo n.º 29
0
    def setUp(self):
        self.comp = list()
        self.comp.append(Composition.from_formula("Li3Fe2(PO4)3"))
        self.comp.append(Composition.from_formula("Li3Fe(PO4)O"))
        self.comp.append(Composition.from_formula("LiMn2O4"))
        self.comp.append(Composition.from_formula("Li4O4"))
        self.comp.append(Composition.from_formula("Li3Fe2Mo3O12"))
        self.comp.append(Composition.from_formula("Li3Fe2((PO4)3(CO3)5)2"))
        self.comp.append(Composition.from_formula("Li1.5Si0.5"))

        self.indeterminate_comp = list()
        self.indeterminate_comp.append(Composition.ranked_compositions_from_indeterminate_formula("Co1", True))
        self.indeterminate_comp.append(Composition.ranked_compositions_from_indeterminate_formula("Co1", False))
        self.indeterminate_comp.append(Composition.ranked_compositions_from_indeterminate_formula("co2o3"))
        self.indeterminate_comp.append(Composition.ranked_compositions_from_indeterminate_formula("ncalu"))
        self.indeterminate_comp.append(Composition.ranked_compositions_from_indeterminate_formula("calun"))
        self.indeterminate_comp.append(Composition.ranked_compositions_from_indeterminate_formula("liCoo2n (pO4)2"))
        self.indeterminate_comp.append(Composition.ranked_compositions_from_indeterminate_formula("(co)2 (PO)4"))
        self.indeterminate_comp.append(Composition.ranked_compositions_from_indeterminate_formula("Fee3"))
Exemplo n.º 30
0
 def test_reduced_composition(self):
     correct_reduced_formulas = ['Li3Fe2(PO4)3', 'Li3FePO5', 'LiMn2O4', 'Li2O2', 'Li3Fe2(MoO4)3', 'Li3Fe2P6(C5O27)2', 'Li1.5Si0.5']
     for i in xrange(len(self.comp)):
         self.assertEqual(self.comp[i].get_reduced_composition_and_factor()[0], Composition.from_formula(correct_reduced_formulas[i]))
Exemplo n.º 31
0
 def test_normalize_to(self):
     products = [Composition.from_formula("Fe"), Composition.from_formula("O2")]
     reactants = [Composition.from_formula("Fe2O3")]
     rxn = Reaction(reactants, products)
     rxn.normalize_to(Composition.from_formula("Fe"), 3)
     self.assertEquals(str(rxn), "1.500 Fe2O3 -> 3.000 Fe + 2.250 O2", "Wrong reaction obtained!")
Exemplo n.º 32
0
    def test_init(self):

        reactants = [Composition.from_formula("Fe"), Composition.from_formula("O2")]
        products = [Composition.from_formula("Fe2O3")]
        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "2.000 Fe + 1.500 O2 -> 1.000 Fe2O3", "Wrong reaction obtained!")
        self.assertEquals(rxn.normalized_repr, "4 Fe + 3 O2 -> 2 Fe2O3", "Wrong normalized reaction obtained!")

        reactants = [Composition.from_formula("Fe"), Composition.from_formula("O"), Composition.from_formula("Mn"), Composition.from_formula("P")]
        products = [Composition.from_formula("FeP"), Composition.from_formula("MnO")]
        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "1.000 Fe + 0.500 O2 + 1.000 Mn + 1.000 P -> 1.000 FeP + 1.000 MnO", "Wrong reaction obtained!")
        self.assertEquals(rxn.normalized_repr, "2 Fe + O2 + 2 Mn + 2 P -> 2 FeP + 2 MnO", "Wrong normalized reaction obtained!")
        reactants = [Composition.from_formula("FePO4")]
        products = [Composition.from_formula("FePO4")]

        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "1.000 FePO4 -> 1.000 FePO4", "Wrong reaction obtained!")

        products = [Composition.from_formula("Ti2 O4"), Composition.from_formula("O1")]
        reactants = [Composition.from_formula("Ti1 O2")]
        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "2.000 TiO2 -> 2.000 TiO2", "Wrong reaction obtained!")

        reactants = [Composition.from_formula("FePO4"), Composition.from_formula("Li")]
        products = [Composition.from_formula("LiFePO4")]
        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "1.000 FePO4 + 1.000 Li -> 1.000 LiFePO4", "Wrong reaction obtained!")

        reactants = [Composition.from_formula("MgO")]
        products = [Composition.from_formula("MgO")]

        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "1.000 MgO -> 1.000 MgO", "Wrong reaction obtained!")

        reactants = [Composition.from_formula("Mg")]
        products = [Composition.from_formula("Mg")]

        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "1.000 Mg -> 1.000 Mg", "Wrong reaction obtained!")

        reactants = [Composition.from_formula("FePO4"), Composition.from_formula("LiPO3")]
        products = [Composition.from_formula("LiFeP2O7")]

        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "1.000 FePO4 + 1.000 LiPO3 -> 1.000 LiFeP2O7", "Wrong reaction obtained!")

        reactants = [Composition.from_formula("Na"), Composition.from_formula("K2O")]
        products = [Composition.from_formula("Na2O"), Composition.from_formula("K")]
        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "1.000 Na + 0.500 K2O -> 0.500 Na2O + 1.000 K", "Wrong reaction obtained!")

        # Test for an old bug which has a problem when excess product is defined.
        products = [Composition.from_formula("FePO4"), Composition.from_formula("O")]
        reactants = [Composition.from_formula("FePO4")]
        rxn = Reaction(reactants, products)

        self.assertEquals(str(rxn), "1.000 FePO4 -> 1.000 FePO4", "Wrong reaction obtained!")

        products = map(Composition.from_formula, ['La8Ti8O12', 'O2', 'LiCrO2'])
        reactants = [Composition.from_formula('LiLa3Ti3CrO12')]
        rxn = Reaction(reactants, products)
        self.assertEquals(str(rxn), "1.000 LiLa3Ti3CrO12 -> 1.500 La2Ti2O3 + 2.750 O2 + 1.000 LiCrO2", "Wrong reaction obtained!")
Exemplo n.º 33
0
 def test_from_dict(self):
     sym_dict = {"Fe":6, "O" :8}
     self.assertEqual(Composition.from_dict(sym_dict).reduced_formula, "Fe3O4", "Creation form sym_amount dictionary failed!")