Example #1
0
    def test_get_concentration(self):
        doc = [["Na", 3], ["P", 1]]
        conc = get_concentration(doc, ["Na", "P"])
        self.assertEqual(conc, [0.75])
        conc = get_concentration(doc, ["Na", "P"], include_end=True)
        self.assertEqual(conc, [0.75, 0.25])
        conc = get_concentration(doc, ["K", "P"], include_end=True)
        self.assertEqual(conc, [0.0, 0.25])

        doc = {"stoichiometry": [["Na", 3], ["P", 1]]}
        conc = get_concentration(doc, ["Na", "P"])
        self.assertEqual(conc, [0.75])
        conc = get_concentration(doc, ["Na", "P"], include_end=True)
        self.assertEqual(conc, [0.75, 0.25])
Example #2
0
 def concentration(self):
     """ Return concentration of each species in stoichiometry. """
     if 'concentration' not in self._data:
         self._data['concentration'] = get_concentration(
             self.stoichiometry, [elem[0] for elem in self.stoichiometry],
             include_end=True)
     return self._data['concentration']
Example #3
0
    def test_gravimetric_capacity(self):
        test_docs = []
        test_elements = []
        Q = []

        # Li3P and symmetry test
        doc = dict()
        doc["stoichiometry"] = [["Li", 3], ["P", 1]]
        test_docs.append(doc)
        test_elements.append(["Li", "P"])
        doc = dict()
        doc["stoichiometry"] = [["P", 1], ["Li", 3]]
        test_docs.append(doc)
        test_elements.append(["Li", "P"])
        # ternary test
        doc = dict()
        doc["stoichiometry"] = [["Li", 1], ["Mo", 1], ["S", 2]]
        test_docs.append(doc)
        test_elements.append(["Li", "Mo", "S"])
        doc = dict()
        doc["stoichiometry"] = [["Li", 8], ["Mo", 1], ["S", 2]]
        test_docs.append(doc)
        test_elements.append(["Li", "Mo", "S"])
        doc = dict()
        doc["stoichiometry"] = [["Li", 1], ["Mo", 2], ["S", 4]]
        test_docs.append(doc)
        test_elements.append(["Li", "Mo", "S"])
        for doc, elem in zip(test_docs, test_elements):
            doc["concentration"] = get_concentration(doc, elem)
            temp_conc = list(doc["concentration"])
            temp_conc.append(1.0)
            for conc in doc["concentration"]:
                temp_conc[-1] -= conc

            Q.append(get_generic_grav_capacity(temp_conc, elem))
        self.assertAlmostEqual(Q[0], 2596.096626125, places=3)
        self.assertAlmostEqual(Q[2], 167.449, places=3)
        self.assertEqual(Q[0], Q[1])
        self.assertEqual(round(8 * Q[2], 3), round(Q[3], 3))
        self.assertEqual(round(Q[2], 3), round(2 * Q[4], 3))
Example #4
0
    def _get_hull_distance(self, generation):
        """ Assign distance from the hull from hull for generation,
        assigning it.

        Parameters:
            generation (Generation): list of optimised structures.

        Returns:
            hull_dist (list(float)): list of distances to the hull.

        """
        for ind, populum in enumerate(generation):
            generation[ind]["concentration"] = get_concentration(
                populum, self.hull.elements)
            generation[ind][
                "formation_enthalpy_per_atom"] = get_formation_energy(
                    self.chempots, populum)
            if self.debug:
                print(
                    generation[ind]["concentration"],
                    generation[ind]["formation_enthalpy_per_atom"],
                )
        if self.testing:
            for ind, populum in enumerate(generation):
                generation[ind][
                    "formation_enthalpy_per_atom"] = np.random.rand() - 0.5
        structures = np.hstack((
            get_array_from_cursor(generation, "concentration"),
            get_array_from_cursor(generation,
                                  "formation_enthalpy_per_atom").reshape(
                                      len(generation), 1),
        ))
        if self.debug:
            print(structures)
        hull_dist = self.hull.get_hull_distances(structures, precompute=False)
        for ind, populum in enumerate(generation):
            generation[ind]["hull_distance"] = hull_dist[ind]
        return hull_dist
Example #5
0
    def construct_structure_attributes(self, doc: Crystal):

        structure_attributes = {}
        # from optimade StructureResourceAttributes
        structure_attributes["elements"] = doc.elems
        structure_attributes["nelements"] = len(doc.elems)

        concentration = get_concentration(doc._data,
                                          elements=doc.elems,
                                          include_end=True)
        structure_attributes["elements_ratios"] = concentration
        structure_attributes["chemical_formula_descriptive"] = doc.formula
        structure_attributes["chemical_formula_reduced"] = doc.formula
        structure_attributes["chemical_formula_hill"] = None

        sorted_stoich = sorted(doc.stoichiometry,
                               key=lambda x: x[1],
                               reverse=True)
        gen = anonymous_element_generator()
        for ind, elem in enumerate(sorted_stoich):
            elem[0] = next(gen)

        structure_attributes[
            "chemical_formula_anonymous"] = get_formula_from_stoich(
                doc.stoichiometry,
                elements=[elem[0] for elem in sorted_stoich])
        structure_attributes["dimension_types"] = [1, 1, 1]
        structure_attributes["nperiodic_dimensions"] = 3
        structure_attributes["lattice_vectors"] = doc.lattice_cart
        structure_attributes["lattice_abc"] = doc.lattice_abc
        structure_attributes["cell_volume"] = cart2volume(doc.lattice_cart)
        structure_attributes["fractional_site_positions"] = doc.positions_frac
        structure_attributes["cartesian_site_positions"] = doc.positions_abs
        structure_attributes["nsites"] = doc.num_atoms
        structure_attributes["species_at_sites"] = doc.atom_types

        species = []
        for ind, atom in enumerate(doc.elems):
            species.append(
                Species(name=atom,
                        chemical_symbols=[atom],
                        concentration=[1.0]))

            structure_attributes["species"] = species
        structure_attributes["assemblies"] = None
        structure_attributes["structure_features"] = []

        # from optimade EntryResourceAttributes
        if "text_id" not in doc._data:
            structure_attributes["local_id"] = " ".join([
                self.wlines[random.randint(0, self.num_words - 1)].strip(),
                self.nlines[random.randint(0, self.num_nouns - 1)].strip(),
            ])
        else:
            structure_attributes["local_id"] = " ".join(doc._data["text_id"])
        structure_attributes["last_modified"] = datetime.datetime.now()
        if "_id" in doc._data:
            structure_attributes["immutable_id"] = str(doc._data["_id"])
        else:
            structure_attributes["immutable_id"] = str(
                bson.objectid.ObjectId())
        # if "date" in doc._data:
        # date = [int(val) for val in doc._data["date"].split("-")]
        # structure_attributes["date"] = datetime.date(
        # year=date[-1], month=date[1], day=date[0]
        # )

        # from matador extensions
        structure_attributes[
            "dft_parameters"] = self.construct_dft_hamiltonian(doc)
        structure_attributes["submitter"] = self.construct_submitter(doc)
        structure_attributes["thermodynamics"] = self.construct_thermodynamics(
            doc)
        structure_attributes["space_group"] = self.construct_spacegroup(doc)
        structure_attributes["calculator"] = self.construct_calculator(doc)

        structure_attributes["stress_tensor"] = doc._data.get("stress")
        structure_attributes["stress"] = doc._data["pressure"]
        structure_attributes["forces"] = doc._data.get("forces")
        structure_attributes["max_force_on_atom"] = doc._data.get(
            "max_force_on_atom")

        return MatadorStructureResourceAttributes(**structure_attributes)
Example #6
0
    def test_toy_ternary(self):
        cursor = [
            {
                "stoichiometry": [["K", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 100,
                "num_atoms": 10,
            },
            {
                "stoichiometry": [["Sn", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 100,
                "num_atoms": 10,
            },
            {
                "stoichiometry": [["P", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 100,
                "num_atoms": 10,
            },
            {
                "stoichiometry": [["K", 1.0], ["Sn", 1.0], ["P", 1.0]],
                "enthalpy_per_atom": -1,
                "cell_volume": 100,
                "num_atoms": 30,
            },
            {
                "stoichiometry": [["K", 1.0], ["Sn", 1.0], ["P", 1.0]],
                "enthalpy_per_atom": -0.5,
                "cell_volume": 100,
                "num_atoms": 30,
            },
            {
                "stoichiometry": [["Sn", 1.0], ["P", 1.0]],
                "enthalpy_per_atom": 0.1,
                "cell_volume": 100,
                "num_atoms": 30,
            },
            {
                "stoichiometry": [["K", 4.0], ["Sn", 2.0], ["P", 2.0]],
                "enthalpy_per_atom": -0.74,
                "cell_volume": 100,
                "num_atoms": 30,
            },
            {
                "stoichiometry": [["K", 2.0], ["Sn", 2.0], ["P", 4.0]],
                "enthalpy_per_atom": -0.74,
                "cell_volume": 100,
                "num_atoms": 30,
            },
            {
                "stoichiometry": [["K", 2.0], ["Sn", 4.0], ["P", 2.0]],
                "enthalpy_per_atom": -0.74,
                "cell_volume": 100,
                "num_atoms": 30,
            },
            {
                "stoichiometry": [["Sn", 1.0], ["P", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 100,
                "num_atoms": 30,
            },
        ]
        for ind, doc in enumerate(cursor):
            cursor[ind]["concentration"] = get_concentration(
                doc, ["K", "Sn", "P"])
            cursor[ind]["source"] = ["abcde"]
            cursor[ind]["num_fu"] = 10
            cursor[ind]["enthalpy"] = (cursor[ind]["enthalpy_per_atom"] *
                                       doc["num_atoms"])

        hull = QueryConvexHull(cursor=cursor,
                               elements=["K", "Sn", "P"],
                               no_plot=True)

        hull_dists = [doc["hull_distance"] for doc in hull.cursor]
        np.testing.assert_array_almost_equal(
            hull_dists, [0, 0, 0, 0, 0.5, 0.1, 0.01, 0.01, 0.01, 0])
Example #7
0
    def test_ternary_volume_curve(self):
        cursor = [
            {
                "stoichiometry": [["K", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 10,
                "num_atoms": 10,
                "num_fu": 10,
            },
            {
                "stoichiometry": [["Sn", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 100,
                "num_atoms": 10,
                "num_fu": 10,
            },
            {
                "stoichiometry": [["P", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 100,
                "num_atoms": 10,
                "num_fu": 10,
            },
            {
                "stoichiometry": [["K", 1.0], ["Sn", 1.0], ["P", 1.0]],
                "enthalpy_per_atom": -1,
                "cell_volume": 210,
                "num_atoms": 30,
                "num_fu": 10,
            },
            {
                "stoichiometry": [["Sn", 2.0], ["P", 1.0]],
                "enthalpy_per_atom": -0.1,
                "cell_volume": 300,
                "num_atoms": 30,
                "num_fu": 10,
            },
        ]
        for ind, doc in enumerate(cursor):
            cursor[ind]["concentration"] = get_concentration(
                doc, ["K", "Sn", "P"])
            cursor[ind]["source"] = ["abcde"]
            cursor[ind]["enthalpy"] = (cursor[ind]["enthalpy_per_atom"] *
                                       doc["num_atoms"])

        hull = QueryConvexHull(cursor=cursor,
                               elements=["K", "Sn", "P"],
                               no_plot=True,
                               voltage=True)

        np.testing.assert_array_almost_equal(
            hull.volume_data["electrode_volume"][0], [30, 31])
        np.testing.assert_array_almost_equal(
            hull.volume_data["volume_ratio_with_bulk"][0], [1, 31 / 30])

        cursor = [
            {
                "stoichiometry": [["K", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 10,
                "num_atoms": 10,
                "num_fu": 10,
            },
            {
                "stoichiometry": [["Sn", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 100,
                "num_atoms": 10,
                "num_fu": 10,
            },
            {
                "stoichiometry": [["P", 1.0]],
                "enthalpy_per_atom": 0,
                "cell_volume": 100,
                "num_atoms": 10,
                "num_fu": 10,
            },
            {
                "stoichiometry": [["K", 1.0], ["Sn", 1.0], ["P", 1.0]],
                "enthalpy_per_atom": -1,
                "cell_volume": 210,
                "num_atoms": 30,
                "num_fu": 10,
            },
            {
                "stoichiometry": [["Sn", 2.0], ["P", 1.0]],
                "enthalpy_per_atom": -0.1,
                "cell_volume": 150,
                "num_atoms": 30,
                "num_fu": 10,
            },
        ]
        for ind, doc in enumerate(cursor):
            cursor[ind]["concentration"] = get_concentration(
                doc, ["K", "Sn", "P"])
            cursor[ind]["source"] = ["abcde"]
            cursor[ind]["enthalpy"] = (cursor[ind]["enthalpy_per_atom"] *
                                       doc["num_atoms"])

        hull = QueryConvexHull(cursor=cursor,
                               elements=["K", "Sn", "P"],
                               no_plot=True,
                               voltage=True)

        np.testing.assert_array_almost_equal(
            hull.volume_data["electrode_volume"][0], [15, 31])
        np.testing.assert_array_almost_equal(
            hull.volume_data["volume_ratio_with_bulk"][0], [1, 31 / 15])