Exemple #1
0
def has_common_oxi_states(row):

    comp = Composition(row.StructuredFormula)
    int_comp = Composition(
        comp.get_integer_formula_and_factor()[0])  # get integer formular

    ###############################################################################################
    # according to the documentation of pymatgen's Composition class' oxi_state_guesses(), the default
    # value of the argument all_oxi_states is False, which means that it should only use most common
    # oxidation states of elements to make the guesses. However, it seems to be using all oxidation states.
    #  E.g. Try the compound - KCa9V10O30, This can't be solved only with Vanadium's common oxidation state (+5)
    # However, this is solved by oxi_state_guesses() function, which means it's using other oxidation states as well.
    # Therefore, we are going to overide the elements' oxidation states with the most common oxidation states
    # by setting the argument oxi_states_override in oxi_state_guesses()
    ################################################################################################

    ## create a common oxidation states dictonary to overide
    dic = {}
    for element in ElementSym('H').ox_st_dict.keys(
    ):  # dummy element to instantiate the ElementSym class
        if element == 'Eu':  # common and most stable ox. st. of Eu is +3, pymatgen provides both (+2 & +3). However, we select only +3
            common_ox_st = (3, )
        else:
            common_ox_st = Element(element).common_oxidation_states
        dic[element] = common_ox_st

    # return true if it could be solved using common oxi states
    if len(int_comp.oxi_state_guesses(oxi_states_override=dic)) > 0:
        return 1
    else:
        return 0
Exemple #2
0
def create_formulas(bounds,
                    charge_balanced=True,
                    oxi_states_extend=None,
                    oxi_states_override=None,
                    all_oxi_states=False,
                    create_subsystems=False,
                    grid=None):
    """
    Creates a list of formulas given the bounds of a chemical space.
    TODO:
        - implement create_subsystems
    """
    stoichs = get_stoichiometric_formulas(len(bounds), grid=grid)

    formulas = []
    for f in stoichs:
        f_ = ''
        for i in range(len(f)):
            f_ += bounds[i] + f.astype(str).tolist()[i]
        formulas.append(f_)

    if charge_balanced:

        charge_balanced_formulas = []

        if oxi_states_extend:
            oxi_states_override = oxi_states_override if oxi_states_override else {}
            for k, v in oxi_states_extend.items():
                v = v if type(v) == list else [v]
                _states = v + list(Element[k].common_oxidation_states)
                if k in oxi_states_override:
                    oxi_states_override[k] += v
                else:
                    oxi_states_override[k] = _states

        for formula in formulas:
            c = Composition(formula)
            if c.oxi_state_guesses(oxi_states_override=oxi_states_override,
                                   all_oxi_states=all_oxi_states):
                charge_balanced_formulas.append(formula)
        return charge_balanced_formulas
    else:
        return formulas
        def has_common_oxi_states(
                row):  # this snippet is borrowed from get_novel_perovskites.py
            comp = Composition(row.StructuredFormula)
            int_comp = Composition(comp.get_integer_formula_and_factor()
                                   [0])  # get integer formular

            ## create a common oxidation states dictonary to overide
            dic = {}
            for element in ElementSym('H').ox_st_dict.keys(
            ):  # dummy element to instantiate the ElementSym class
                if element == 'Eu':
                    common_ox_st = (3, )
                else:
                    common_ox_st = Element(element).common_oxidation_states
                dic[element] = common_ox_st

            # return true if it could be solved using common oxi states
            if len(int_comp.oxi_state_guesses(oxi_states_override=dic)) > 0:
                return 1
            else:
                return 0
Exemple #4
0
def create_formulas(bounds, charge_balanced=True, oxi_states_extend=None,
                    oxi_states_override=None, all_oxi_states=False,
                    grid=None, create_subsystems=False):
    """
    Creates a list of formulas given the bounds of a chemical space.

    TODO:
        - implement create_subsystems

    Args:
        bounds ([str]): list of elements to bound the space
        charge_balanced (bool): whether to balance oxidations
            states in the generated formulae
        oxi_states_extend ({}): dictionary of {element: [int]}
            where the value is the added oxidation state to be
            included
        oxi_states_override ({str: int}): override for oxidation
            states, see Composition.oxi_state_guesses
        all_oxi_states ({str: int): global config for oxidation
            states, see Composition.oxi_state_guesses
        grid ([]): list of integers to use for coefficients
        create_subsystems (bool): whether to create formulas
            for sub-chemical systems, e. g. for Sr-Ti-O,
            whether to create Ti-O and Sr-O

    Returns:
        ([str]): list of chemical formulas

    """
    if create_subsystems:
        raise NotImplementedError("Create subsystems not yet implemented.")

    stoichs = get_stoichiometric_formulas(len(bounds), grid=grid)

    formulas = []
    for f in stoichs:
        f_ = ''
        for i in range(len(f)):
            f_ += bounds[i] + f.astype(str).tolist()[i]
        formulas.append(f_)

    if charge_balanced:
        charge_balanced_formulas = []

        if oxi_states_extend:
            oxi_states_override = oxi_states_override if oxi_states_override else {}
            for element, states in oxi_states_extend.items():
                states = states if isinstance(states, list) else [states]
                _states = states + list(Element[element].common_oxidation_states)
                if element in oxi_states_override:
                    oxi_states_override[element] += states
                else:
                    oxi_states_override[element] = _states

        for formula in formulas:
            c = Composition(formula)
            if c.oxi_state_guesses(oxi_states_override=oxi_states_override,
                                   all_oxi_states=all_oxi_states):
                charge_balanced_formulas.append(formula)
        return charge_balanced_formulas
    else:
        return formulas
    def are_soluble(self, pair):
        """
        Predict whether a pair of compounds are soluble with one another.

        Args:
            pair_info: a tuple containing containing two compounds
                denoted by their filenames
        Returns:
            The pair of compounds, if they are soluble.
            Otherwise, Nonetype is returned.
        """

        reference_directory = self.ref_dir

        cmpd_A, cmpd_B = pair[0], pair[1]
        struc_A = Structure.from_file('%s/%s' % (reference_directory, cmpd_A))
        formula_A = struc_A.composition.reduced_formula
        struc_B = Structure.from_file('%s/%s' % (reference_directory, cmpd_B))
        formula_B = struc_B.composition.reduced_formula

        if formula_A != formula_B:
            if self.matcher.fit(struc_A, struc_B):
                solubility = True
                comp_A = Composition(formula_A)
                comp_B = Composition(formula_B)
                probable_oxis_A = comp_A.oxi_state_guesses()
                probable_oxis_B = comp_B.oxi_state_guesses()
                if len(
                        probable_oxis_A
                ) == 0:  ## This occurs for metals, in which case we'll just use atomic radii
                    oxi_dict_A = {}
                    for elem in [str(f) for f in comp_A.elements]:
                        oxi_dict_A[elem] = 0.0
                else:  ## Take most probable list of oxidation states
                    oxi_dict_A = probable_oxis_A[0]
                if len(probable_oxis_B) == 0:
                    oxi_dict_B = {}
                    for elem in [str(f) for f in comp_B.elements]:
                        oxi_dict_B[elem] = 0.0
                else:
                    oxi_dict_B = probable_oxis_B[0]
                try:
                    struc_B = self.matcher.get_s2_like_s1(struc_A, struc_B)
                except ValueError:  ## Sometimes order matters
                    struc_A = self.matcher.get_s2_like_s1(struc_B, struc_A)
                index = 0
                for (site_A, site_B) in zip(struc_A, struc_B):
                    elem_A = ''.join([
                        char for char in str(site_A.species_string)
                        if char.isalpha()
                    ])
                    elem_B = ''.join([
                        char for char in str(site_B.species_string)
                        if char.isalpha()
                    ])
                    if solubility == True:
                        site_A_oxi = oxi_dict_A[elem_A]
                        site_B_oxi = oxi_dict_B[elem_B]
                        if site_A_oxi.is_integer():
                            if site_A_oxi == 0:
                                possible_rA = [
                                    pt.Element(elem_A).atomic_radius
                                ]
                            else:
                                possible_rA = [
                                    pt.Element(elem_A).ionic_radii[site_A_oxi]
                                ]
                        else:
                            possible_rA = []
                            possible_rA.append(
                                pt.Element(elem_A).ionic_radii[int(
                                    np.floor(site_A_oxi))])
                            possible_rA.append(
                                pt.Element(elem_A).ionic_radii[int(
                                    np.ceil(site_A_oxi))])
                        if site_B_oxi.is_integer():
                            if site_B_oxi == 0:
                                possible_rB = [
                                    pt.Element(elem_B).atomic_radius
                                ]
                            else:
                                possible_rB = [
                                    pt.Element(elem_B).ionic_radii[site_B_oxi]
                                ]
                        else:
                            possible_rB = []
                            possible_rB.append(
                                pt.Element(elem_B).ionic_radii[int(
                                    np.floor(site_B_oxi))])
                            possible_rB.append(
                                pt.Element(elem_B).ionic_radii[int(
                                    np.ceil(site_B_oxi))])
                        possible_diffs = []
                        for rA in possible_rA:
                            for rB in possible_rB:
                                possible_diffs.append(
                                    abs(float(rA) - float(rB)) /
                                    max([float(rA), float(rB)]))
                        if min(possible_diffs) > 0.15:
                            solubility = False

                if solubility == True:
                    return [cmpd_A, cmpd_B]