コード例 #1
0
ファイル: test_conversions.py プロジェクト: utf/matminer
    def test_composition_to_oxidcomposition(self):
        df = DataFrame(data={"composition": [Composition("Fe2O3")]})
        cto = CompositionToOxidComposition()
        df = cto.featurize_dataframe(df, 'composition')
        self.assertEqual(df["composition_oxid"].tolist()[0],
                         Composition({
                             "Fe3+": 2,
                             "O2-": 3
                         }))

        # test error handling
        df = DataFrame(data={"composition": [Composition("Fe2O3")]})
        cto = CompositionToOxidComposition(return_original_on_error=False,
                                           max_sites=2)
        self.assertRaises(ValueError, cto.featurize_dataframe, df,
                          'composition')

        # check non oxi state structure returned correctly
        cto = CompositionToOxidComposition(return_original_on_error=True,
                                           max_sites=2)
        df = cto.featurize_dataframe(df, 'composition')
        self.assertEqual(df["composition_oxid"].tolist()[0],
                         Composition({
                             "Fe": 2,
                             "O": 3
                         }))
コード例 #2
0
    def std_rel_energies(self) -> Tuple["StandardEnergies", "RelativeEnergies"]:
        std, rel = StandardEnergies(), RelativeEnergies()
        abs_energies_per_atom = {k.reduced_formula: v.energy / k.num_atoms
                                 for k, v in self.items()}
        std_energies_list = []
        for vertex_element in self.elements:
            # This target is needed as some reduced formulas shows molecule
            # ones such as H2 and O2.
            reduced_formula = Composition({vertex_element: 1.0}).reduced_formula
            candidates = filter(lambda x: x[0] == reduced_formula,
                                abs_energies_per_atom.items())
            try:
                min_abs_energy = min([abs_energy_per_atom[1]
                                      for abs_energy_per_atom in candidates])
            except ValueError:
                print(f"Element {vertex_element} does not exist in "
                      f"CompositionEnergies.")
                raise NoElementEnergyError
            std[vertex_element] = min_abs_energy
            std_energies_list.append(min_abs_energy)

        for formula, abs_energy_per_atom in abs_energies_per_atom.items():
            if Composition(formula).is_element:
                continue
            frac = atomic_fractions(formula, self.elements)
            offset = sum([a * b for a, b in zip(frac, std_energies_list)])
            rel[formula] = abs_energy_per_atom - offset

        return std, rel
コード例 #3
0
    def test_fit(self):
        """
        Take two known matched structures
            1) Ensure match
            2) Ensure match after translation and rotations
            3) Ensure no-match after large site translation
            4) Ensure match after site shuffling
            """
        sm = StructureMatcher()

        self.assertTrue(sm.fit(self.struct_list[0], self.struct_list[1]))

        # Test rotational/translational invariance
        op = SymmOp.from_axis_angle_and_translation([0, 0, 1], 30, False,
                                                    np.array([0.4, 0.7, 0.9]))
        self.struct_list[1].apply_operation(op)
        self.assertTrue(sm.fit(self.struct_list[0], self.struct_list[1]))

        #Test failure under large atomic translation
        self.struct_list[1].translate_sites([0], [.4, .4, .2],
                                            frac_coords=True)
        self.assertFalse(sm.fit(self.struct_list[0], self.struct_list[1]))

        self.struct_list[1].translate_sites([0], [-.4, -.4, -.2],
                                            frac_coords=True)
        # random.shuffle(editor._sites)
        self.assertTrue(sm.fit(self.struct_list[0], self.struct_list[1]))
        #Test FrameworkComporator
        sm2 = StructureMatcher(comparator=FrameworkComparator())
        lfp = read_structure(os.path.join(test_dir, "LiFePO4.cif"))
        nfp = read_structure(os.path.join(test_dir, "NaFePO4.cif"))
        self.assertTrue(sm2.fit(lfp, nfp))
        self.assertFalse(sm.fit(lfp, nfp))

        #Test anonymous fit.
        self.assertEqual(sm.fit_anonymous(lfp, nfp),
                         {Composition("Li"): Composition("Na")})
        self.assertAlmostEqual(sm.get_minimax_rms_anonymous(lfp, nfp)[0],
                               0.096084154118549828)

        #Test partial occupancies.
        s1 = Structure([[3, 0, 0], [0, 3, 0], [0, 0, 3]],
                       [{"Fe": 0.5}, {"Fe": 0.5}, {"Fe": 0.5}, {"Fe": 0.5}],
                       [[0, 0, 0], [0.25, 0.25, 0.25],
                        [0.5, 0.5, 0.5], [0.75, 0.75, 0.75]])
        s2 = Structure([[3, 0, 0], [0, 3, 0], [0, 0, 3]],
                       [{"Fe": 0.25}, {"Fe": 0.5}, {"Fe": 0.5}, {"Fe": 0.75}],
                       [[0, 0, 0], [0.25, 0.25, 0.25],
                        [0.5, 0.5, 0.5], [0.75, 0.75, 0.75]])
        self.assertFalse(sm.fit(s1, s2))
        self.assertFalse(sm.fit(s2, s1))
        s2 = Structure([[3, 0, 0], [0, 3, 0], [0, 0, 3]],
                       [{"Fe": 0.25}, {"Fe": 0.25}, {"Fe": 0.25},
                        {"Fe": 0.25}],
                       [[0, 0, 0], [0.25, 0.25, 0.25],
                        [0.5, 0.5, 0.5], [0.75, 0.75, 0.75]])
        self.assertEqual(sm.fit_anonymous(s1, s2),
                         {Composition("Fe0.5"): Composition("Fe0.25")})

        self.assertAlmostEqual(sm.get_minimax_rms_anonymous(s1, s2)[0], 0)
コード例 #4
0
    def test_electronegativity(self):
        sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5)

        s1 = read_structure(os.path.join(test_dir, "Na2Fe2PAsO4S4.cif"))
        s2 = read_structure(os.path.join(test_dir, "Na2Fe2PNO4Se4.cif"))
        self.assertAlmostEqual(sm.fit_with_electronegativity(s1, s2),
                               {Composition('S'): Composition('Se'), Composition('As'): Composition('N')})
コード例 #5
0
def mp_query_mock(mocker):
    mock = mocker.patch(
        "pydefect.cli.vasp.make_composition_energies_from_mp.MpEntries")
    mock.return_value.materials = \
        [ComputedEntry(Composition("O8"), -39.58364375, entry_id="mp-1"),
         ComputedEntry(Composition("Mg3"), -4.79068775, entry_id="mp-2"),
         ComputedEntry(Composition("Mg1O1"), -11.96742144, entry_id="mp-3")]
    return mock
コード例 #6
0
 def side_effect_structure(key):
     mock_structure = mocker.Mock()
     if key == Path("Mg") / defaults.contcar:
         mock_structure.composition = Composition("Mg2")
     elif key == Path("O") / defaults.contcar:
         mock_structure.composition = Composition("O2")
     else:
         raise ValueError
     return mock_structure
コード例 #7
0
def comp_energies():
    return CompositionEnergies({
        Composition('O8'):
        CompositionEnergy(-39.58364375, "mp-1"),
        Composition('Mg3'):
        CompositionEnergy(-4.79068775, "mp-2"),
        Composition('Mg1O1'):
        CompositionEnergy(-11.96742144, "mp-3")
    })
コード例 #8
0
def comp_energies_corr():
    return CompositionEnergies({
        Composition('O8'):
        CompositionEnergy(-39.58364375 + diff["O"] * 8, "mp-1"),
        Composition('Mg3'):
        CompositionEnergy(-4.79068775 + diff["Mg"] * 3, "mp-2"),
        Composition('Mg1O1'):
        CompositionEnergy(-11.96742144 + diff["Mg"] + diff["O"], "mp-3")
    })
コード例 #9
0
ファイル: utils.py プロジェクト: jmmshn/api
def formula_to_criteria(formula: str) -> Dict:
    """
    Santizes formula into a dictionary to search with wild cards

    Arguments:
        formula: a chemical formula with wildcards in it for unknown elements

    Returns:
        Mongo style search criteria for this formula
    """
    dummies = "ADEGJLMQRXZ"

    if "*" in formula:
        # Wild card in formula
        nstars = formula.count("*")

        formula_dummies = formula.replace("*", "{}").format(*dummies[:nstars])

        integer_formula = Composition(
            formula_dummies).get_integer_formula_and_factor()[0]
        comp = Composition(integer_formula).reduced_composition
        crit = dict()
        crit["formula_anonymous"] = comp.anonymized_formula
        real_elts = [
            str(e) for e in comp.elements
            if not e.as_dict().get("element", "A") in dummies
        ]

        for el, n in comp.to_reduced_dict.items():
            if el in real_elts:
                crit[f"composition_reduced.{el}"] = n

        return crit

    elif "-" in formula:
        crit = {}
        eles = formula.split("-")
        chemsys = "-".join(sorted(eles))

        crit["chemsys"] = chemsys

        return crit

    elif any(isinstance(el, DummySpecies) for el in Composition(formula)):
        # Assume fully anonymized formula
        return {"formula_anonymous": Composition(formula).anonymized_formula}

    else:
        comp = Composition(formula)
        # Paranoia below about floating-point "equality"
        crit = {}
        crit["nelements"] = len(comp)
        for el, n in comp.to_reduced_dict.items():
            crit[f"composition_reduced.{el}"] = n

        return crit
コード例 #10
0
    def test_composition_to_structurefromMP(self):
        df = DataFrame(data={"composition": [Composition("Fe2O3"),
                                             Composition("N9Al34Fe234")]})

        cto = CompositionToStructureFromMP()
        df = cto.featurize_dataframe(df, 'composition')
        structures = df["structure"].tolist()
        self.assertTrue(isinstance(structures[0], Structure))
        self.assertGreaterEqual(len(structures[0]), 5)  # has at least 5 sites
        self.assertTrue(math.isnan(structures[1]))
コード例 #11
0
 def setUp(self):
     self.df = pd.DataFrame({
         "composition": [
             Composition("Fe2O3"),
             Composition({
                 Specie("Fe", 2): 1,
                 Specie("O", -2): 1
             })
         ]
     })
コード例 #12
0
 def test_get_sc_structures(self):
     dist_ref = self.m_hop.length
     start, end, b_sc = self.m_hop.get_sc_structures(vac_mode=False)
     start_site = next(
         filter(lambda x: x.species_string == "Li", start.sites))
     end_site = next(filter(lambda x: x.species_string == "Li", end.sites))
     assert start.composition == end.composition == Composition(
         "Li1 Fe24 P24 O96")
     assert b_sc.composition == Composition("Fe24 P24 O96")
     self.assertAlmostEqual(start_site.distance(end_site), dist_ref, 3)
コード例 #13
0
def test_remove_higher_energy_comp():
    comp_es = CompositionEnergies(
        {Composition('Mg1'): CompositionEnergy(-1.9, "mp-2"),
         Composition('Mg2'): CompositionEnergy(-4.0, "mp-3"),
         Composition('O2'): CompositionEnergy(-4.0, "mp-4")})
    actual = remove_higher_energy_comp(comp_es)
    expected = CompositionEnergies(
        {Composition('Mg2'): CompositionEnergy(-4.0, "mp-3"),
         Composition('O2'): CompositionEnergy(-4.0, "mp-4"),})

    assert actual == expected
コード例 #14
0
 def side_effect(key):
     mock_vasprun = mocker.Mock()
     if key == Path("Mg") / defaults.vasprun:
         mock_vasprun.final_structure.composition = Composition("Mg2")
         mock_vasprun.final_energy = -10
     elif key == Path("O") / defaults.vasprun:
         mock_vasprun.final_structure.composition = Composition("O2")
         mock_vasprun.final_energy = -20
     else:
         raise ValueError
     return mock_vasprun
コード例 #15
0
def remove_higher_energy_comp(comp_energies: Dict[Composition,
                                                  CompositionEnergy]):
    _l = [[k, v] for k, v in comp_energies.items()]
    result = {}
    for _, grouped_k_v in groupby(
            _l, key=lambda x: Composition(x[0]).reduced_formula):
        formula, comp_e = min(list(grouped_k_v),
                              key=lambda y:
                              (y[1].energy / Composition(y[0]).num_atoms))
        result[formula] = comp_e
    return result
コード例 #16
0
    def test_str_to_composition(self):
        d = {'comp_str': ["Fe2", "MnO2"]}

        df = DataFrame(data=d)
        df["composition"] = str_to_composition(df["comp_str"])
        self.assertEqual(df["composition"].tolist(), [Composition("Fe2"),
                                                      Composition("MnO2")])

        df["composition_red"] = str_to_composition(df["comp_str"], reduce=True)
        self.assertEqual(df["composition_red"].tolist(), [Composition("Fe"),
                                                           Composition("MnO2")])
コード例 #17
0
    def test_is_ionic(self):
        """Test checking whether a compound is ionic"""

        self.assertTrue(
            is_ionic(Composition({
                Specie("Fe", 2): 1,
                Specie("O", -2): 1
            })))
        self.assertFalse(
            is_ionic(Composition({
                Specie("Fe", 0): 1,
                Specie("Al", 0): 1
            })))
コード例 #18
0
    def test_structure_to_composition(self):
        coords = [[0, 0, 0], [0.75, 0.5, 0.75]]
        lattice = Lattice([[3.8401979337, 0.00, 0.00],
                           [1.9200989668, 3.3257101909, 0.00],
                           [0.00, -2.2171384943, 3.1355090603]])
        struct = Structure(lattice, ["Si"] * 2, coords)
        df = DataFrame(data={'structure': [struct]})

        df["composition"] = structure_to_composition(df["structure"])
        self.assertEqual(df["composition"].tolist()[0], Composition("Si2"))

        df["composition_red"] = structure_to_composition(df["structure"],
                                                         reduce=True)
        self.assertEqual(df["composition_red"].tolist()[0], Composition("Si"))
コード例 #19
0
    def test_str_to_composition(self):
        d = {'comp_str': ["Fe2", "MnO2"]}

        df = DataFrame(data=d)
        df = StrToComposition().featurize_dataframe(df, 'comp_str')

        self.assertEqual(df["composition"].tolist(),
                         [Composition("Fe2"), Composition("MnO2")])

        stc = StrToComposition(reduce=True, target_col_id='composition_red')
        df = stc.featurize_dataframe(df, 'comp_str')

        self.assertEqual(df["composition_red"].tolist(),
                         [Composition("Fe"), Composition("MnO2")])
コード例 #20
0
    def test_stoich(self):
        featurizer = Stoichiometry(num_atoms=True)
        df_stoich = Stoichiometry(num_atoms=True).featurize_dataframe(
            self.df, col_id="composition")
        self.assertAlmostEqual(df_stoich["num atoms"][0], 5)
        self.assertAlmostEqual(df_stoich["0-norm"][0], 2)
        self.assertAlmostEqual(df_stoich["7-norm"][0], 0.604895199)

        # Test whether the number of formula units affects result
        original_value = featurizer.featurize(Composition("FeO"))
        self.assertArrayAlmostEqual(
            featurizer.featurize(Composition("Fe0.5O0.5")), original_value)
        self.assertArrayAlmostEqual(featurizer.featurize(Composition("Fe2O2")),
                                    original_value)
コード例 #21
0
ファイル: utils.py プロジェクト: rkingsbury/MPContribs
def get_composition_from_string(comp_str):
    """validate and return composition from string `comp_str`."""
    from pymatgen.core import Composition, Element

    comp = Composition(comp_str)
    for element in comp.elements:
        Element(element)
    formula = comp.get_integer_formula_and_factor()[0]
    comp = Composition(formula)
    return "".join(
        [
            "{}{}".format(key, int(value) if value > 1 else "")
            for key, value in comp.as_dict().items()
        ]
    )
コード例 #22
0
    def test_miedema_all(self):
        df = pd.DataFrame({
            "composition": [
                Composition("TiZr"),
                Composition("Mg10Cu50Ca40"),
                Composition("Fe2O3")
            ]
        })
        miedema = Miedema(struct_types='all')
        self.assertTrue(miedema.precheck(df["composition"].iloc[0]))
        self.assertFalse(miedema.precheck(df["composition"].iloc[-1]))
        self.assertAlmostEqual(miedema.precheck_dataframe(df, "composition"),
                               2 / 3)

        # test precheck for oxidation-state decorated compositions
        df = CompositionToOxidComposition(return_original_on_error=True).\
            featurize_dataframe(df, 'composition')
        self.assertTrue(miedema.precheck(df["composition_oxid"].iloc[0]))
        self.assertFalse(miedema.precheck(df["composition_oxid"].iloc[-1]))
        self.assertAlmostEqual(
            miedema.precheck_dataframe(df, "composition_oxid"), 2 / 3)

        mfps = miedema.featurize_dataframe(df, col_id="composition")
        self.assertAlmostEqual(mfps['Miedema_deltaH_inter'][0],
                               -0.003445022152)
        self.assertAlmostEqual(mfps['Miedema_deltaH_amor'][0], 0.0707658836300)
        self.assertAlmostEqual(mfps['Miedema_deltaH_ss_min'][0], 0.03663599755)

        self.assertAlmostEqual(mfps['Miedema_deltaH_inter'][1],
                               -0.235125978427)
        self.assertAlmostEqual(mfps['Miedema_deltaH_amor'][1], -0.164541848271)
        self.assertAlmostEqual(mfps['Miedema_deltaH_ss_min'][1],
                               -0.05280843311)

        self.assertAlmostEqual(math.isnan(mfps['Miedema_deltaH_inter'][2]),
                               True)
        self.assertAlmostEqual(math.isnan(mfps['Miedema_deltaH_amor'][2]),
                               True)
        self.assertAlmostEqual(math.isnan(mfps['Miedema_deltaH_ss_min'][2]),
                               True)

        # make sure featurization works equally for compositions with or without
        # oxidation states
        mfps = miedema.featurize_dataframe(df, col_id="composition_oxid")
        self.assertAlmostEqual(mfps['Miedema_deltaH_inter'][0],
                               -0.003445022152)
        self.assertAlmostEqual(mfps['Miedema_deltaH_amor'][0], 0.0707658836300)
        self.assertAlmostEqual(mfps['Miedema_deltaH_ss_min'][0], 0.03663599755)
コード例 #23
0
ファイル: misc.py プロジェクト: zezhong-zhang/vsc-workflows
    def update_sites(self, directory, ignore_magmom=False):
        """
        Based on the CONTCAR and OUTCAR of a geometry optimization, update the
        site coordinates and magnetic moments that were optimized. Note that
        this method relies on the cation configuration of the cathode not
        having changed.

        Args:
            directory (str): Directory in which the geometry optimization
                output files (i.e. CONTCAR and OUTCAR) are stored.
            ignore_magmom (bool): Flag that indicates that the final magnetic
                moments of the optimized structure should be ignored. This means
                that the magnetic moments of the Cathode structure will
                remain the same.

        Returns:
            None

        """

        new_cathode = Cathode.from_file(os.path.join(directory, "CONTCAR"))

        out = Outcar(os.path.join(directory, "OUTCAR"))

        if ignore_magmom:
            magmom = [site.properties["magmom"] for site in self.sites
                      if site.species != Composition()]
        else:
            magmom = [site["tot"] for site in out.magnetization]

        if len(out.magnetization) != 0:
            new_cathode.add_site_property("magmom", magmom)

        # Update the lattice
        self.lattice = new_cathode.lattice

        # Update the coordinates of the occupied sites.
        new_index = 0
        for i, site in enumerate(self):

            # If the site is not empty
            if site.species != Composition():
                new_site = new_cathode.sites[new_index]
                # Update the site coordinates
                self.replace(i, species=new_site.species,
                             coords=new_site.frac_coords,
                             properties=new_site.properties)
                new_index += 1
コード例 #24
0
    def run(self):
        logger.info("Starting FileMaterials Builder.")
        with open(self._data_file, 'rt') as f:
            line_no = 0
            lines = [line for line in f]  # only good for smaller files
            pbar = tqdm(lines)
            for line in pbar:
                line = line.strip()
                if line and not line.startswith("#"):
                    line_no += 1
                    if line_no > self.header_lines:
                        line = line.split(self._delimiter)
                        if "-" in line[0]:
                            search_val = line[0]
                            search_key = "material_id"
                        else:
                            search_key = "formula_reduced_abc"
                            search_val = Composition(line[0]).\
                                reduced_composition.alphabetical_formula

                        key = line[1]
                        val = line[2]
                        try:
                            val = float(val)
                        except:
                            pass

                        self._materials.update({search_key: search_val}, {"$set": {key: val}})

        logger.info("FileMaterials Builder finished processing")
コード例 #25
0
def prepare_entry(structure_type, tot_e, species):
    """
    Prepare entries from total energy and species.

    Args:
        structure_type(str): "garnet" or "perovskite"
        tot_e (float): total energy in eV/f.u.
        species (dict): species in dictionary.

    Returns:
        ce (ComputedEntry)
    """

    formula = spe2form(structure_type, species)
    composition = Composition(formula)
    elements = [el.name for el in composition]

    potcars = ["pbe %s" % CONFIG['POTCAR'][el] for el in elements]

    parameters = {"potcar_symbols": list(potcars), "oxide_type": 'oxide'}

    for el in elements:
        if el in LDAUU:
            parameters.update({"hubbards": {el: LDAUU[el]}})

    ce = ComputedEntry(composition=composition,
                       energy=0,
                       parameters=parameters)
    ce.uncorrected_energy = tot_e
    compat = MaterialsProjectCompatibility()
    ce = compat.process_entry(ce)  # Correction added

    return ce
コード例 #26
0
ファイル: pourbaix.py プロジェクト: munrojm/crystaltoolkit
        def update_heatmap_choices(entries):

            if not entries:
                raise PreventUpdate

            options = []
            for entry in entries:
                if entry["entry_id"].startswith("mp"):
                    composition = Composition(entry["entry"]["composition"])
                    formula = unicodeify(composition.reduced_formula)
                    mpid = entry["entry_id"]
                    options.append({
                        "label": f"{formula} ({mpid})",
                        "value": mpid
                    })

            heatmap_options = self.get_choice_input(
                "heatmap_choice",
                state={},
                label="Heatmap Entry",
                help_str="Choose the entry to use for heatmap generation.",
                options=options,
                disabled=False,
            )

            return heatmap_options
コード例 #27
0
def make_poscars_from_query(materials_query: List[dict], path: Path) -> None:
    for query in materials_query:
        reduced_formula = Composition(query["full_formula"]).reduced_formula
        if reduced_formula in MOLECULE_DATA.keys():
            _make_molecular_directory(path, reduced_formula)
        else:
            _make_solid_directory(path, reduced_formula, query)
コード例 #28
0
 def test_band_center(self):
     df_band_center = BandCenter().featurize_dataframe(self.df,
                                                       col_id="composition")
     self.assertAlmostEqual(df_band_center["band center"][0], -2.672486385)
     self.assertAlmostEqual(
         BandCenter().featurize(Composition('Ag33O500V200'))[0],
         -2.7337150991)
コード例 #29
0
    def test_structure_to_composition(self):
        coords = [[0, 0, 0], [0.75, 0.5, 0.75]]
        lattice = Lattice([[3.8401979337, 0.00, 0.00],
                           [1.9200989668, 3.3257101909, 0.00],
                           [0.00, -2.2171384943, 3.1355090603]])
        struct = Structure(lattice, ["Si"] * 2, coords)
        df = DataFrame(data={'structure': [struct]})

        stc = StructureToComposition()
        df = stc.featurize_dataframe(df, 'structure')
        self.assertEqual(df["composition"].tolist()[0], Composition("Si2"))

        stc = StructureToComposition(reduce=True,
                                     target_col_id='composition_red')
        df = stc.featurize_dataframe(df, 'structure')
        self.assertEqual(df["composition_red"].tolist()[0], Composition("Si"))
コード例 #30
0
def FullChemicalPotentialWindow(target_phase, key_element):
    chemsys = key_element + '-' + Composition(target_phase).chemical_system
    with MPRester(api_key='') as mpr:
        entries = mpr.get_entries_in_chemsys(chemsys)

    pd_closed = PhaseDiagram(entries)
    transition_chempots = pd_closed.get_transition_chempots(
        Element(key_element))
    # The exact mu value used to construct the plot for each range is
    # the average of the endpoints of the range, with the exception of the last range,
    # which is plotted at the value of the last endpoint minus 0.1.
    # https://matsci.org/t/question-on-phase-diagram-app-chemical-potential/511
    average_chempots = []
    if len(transition_chempots) > 1:
        for i in range(len(transition_chempots) - 1):
            ave = (transition_chempots[i] + transition_chempots[i + 1]) / 2
            average_chempots.append(ave)
        average_chempots.append(transition_chempots[-1] - 0.1)
    elif len(transition_chempots) == 1:
        # prepare for binary systems, of which two endnodes tielined directly, like Li-Zr
        average_chempots.append(transition_chempots[0])
    average_chempots = np.round(average_chempots, 3)

    boolean_list = []
    for chempot in average_chempots:
        # GrandPotentialPhaseDiagram works good even for binary systems to find stable phases
        pd_open = GrandPotentialPhaseDiagram(entries,
                                             {Element(key_element): chempot})
        stable_phases = [entry.name for entry in pd_open.stable_entries]
        boolean_list.append(target_phase in stable_phases)
    return (False not in boolean_list)