예제 #1
0
def check_neutrality_4(formula):
    charge_neutral_count = 0
    comp = mg.Composition(formula)
    reduce_formula = comp.get_el_amt_dict()
    list_of_elements = list(reduce_formula.keys())
    max_num = max(reduce_formula.values())
    for i, ele_a in enumerate(list_of_elements):
        for ox_a in smact.Element(ele_a).oxidation_states:
            for j, ele_b in enumerate(list_of_elements[i+1:]):
                for ox_b in smact.Element(ele_b).oxidation_states:
                    for k, ele_c in enumerate(list_of_elements[i+j+2:]):
                        for ox_c in smact.Element(ele_c).oxidation_states:
                            for m, ele_d in enumerate(list_of_elements[i+j+k+3:]):
                                for ox_d in smact.Element(ele_d).oxidation_states:
                            
                                    # Checks if the combination is charge neutral before printing it out! #                        
                                    cn_e, cn_r = neutral_ratios([ox_a, ox_b, ox_c, ox_d], threshold = int(max_num))
                                    
                                    if cn_e:
                                        for num in cn_r:
                                            if tuple(reduce_formula.values()) == num:
                                                return True

                                                                # print(cn_e)
                                                                # print(cn_r)
                                                                # print(ox_a, ox_b, ox_c)
                                                                # charge_neutral_count = charge_neutral_count + 1
                                                                # print('{0:3s}  {1:3s}  {2:3s}'.format(ele_a, ele_b, ele_c))
    print('Number of combinations = {0}'.format(charge_neutral_count))
    print("--- {0} seconds to run ---".format(time.time() - start_time)) 
    return False
def check_electronegativity_2(formula):
    pauling_count = 0
    comp = mg.Composition(formula)
    reduce_formula = comp.get_el_amt_dict()
    list_of_elements = list(reduce_formula.keys())
    max_num = max(reduce_formula.values())
    for i, ele_a in enumerate(list_of_elements):
        paul_a = smact.Element(ele_a).pauling_eneg
        for ox_a in smact.Element(ele_a).oxidation_states:
            for j, ele_b in enumerate(list_of_elements[i + 1:]):
                paul_b = smact.Element(ele_b).pauling_eneg
                for ox_b in smact.Element(ele_b).oxidation_states:
                    # Puts elements, oxidation states and electronegativites into lists for convenience #
                    elements = [ele_a, ele_b]
                    oxidation_states = [ox_a, ox_b]
                    pauling_electro = [paul_a, paul_b]
                    # Checks if the electronegativity makes sense and if the combination is charge neutral #
                    electroneg_makes_sense = pauling_test(
                        oxidation_states, pauling_electro, elements)
                    cn_e, cn_r = neutral_ratios([ox_a, ox_b],
                                                threshold=int(max_num))

                    if cn_e:
                        if electroneg_makes_sense:
                            pauling_count = pauling_count + 1

                            for num in cn_r:
                                if tuple(reduce_formula.values()) == num:
                                    # print('{0:2s}{1:3d}   {2:2s}{3:3d}   {4:2s}{5:3d}'.format(ele_a, ox_a, ele_b,
                                    #                                               ox_b, ele_c, ox_c))
                                    return True

    print('Number of combinations = {0}'.format(pauling_count))
    print("--- {0} seconds to run ---".format(time.time() - start_time))
    return False
예제 #3
0
def check_neutrality_2(formula):
    charge_neutral_count = 0
    comp = mg.Composition(formula)
    reduce_formula = comp.get_el_amt_dict()
    list_of_elements = list(reduce_formula.keys())
    # stoichs = np.array(list(reduce_formula.values())).astype(np.int32)[:,np.newaxis]
    max_num = max(reduce_formula.values())
    for i, ele_a in enumerate(list_of_elements):
        for ox_a in smact.Element(ele_a).oxidation_states:
            for j, ele_b in enumerate(list_of_elements[i+1:]):
                for ox_b in smact.Element(ele_b).oxidation_states:                    
                            
                    # Checks if the combination is charge neutral before printing it out! #                        
                    # neutral_ratios(oxidations, stoichs=False, threshold=5) #speed up by providing stoichs 
                    # cn_e, cn_r = neutral_ratios([ox_a, ox_b], threshold = int(max_num))
                    cn_e, cn_r = neutral_ratios([ox_a, ox_b], threshold = int(max_num))
                    
                    if cn_e:
                        for num in cn_r:
                            if tuple(reduce_formula.values()) == num:
                                return True

                        # print(cn_e)
                        # print(cn_r)
                        # print(ox_a, ox_b, ox_c)
                        # charge_neutral_count = charge_neutral_count + 1
                        # print('{0:3s}  {1:3s}  {2:3s}'.format(ele_a, ele_b, ele_c))
    print('Number of combinations = {0}'.format(charge_neutral_count))
    print("--- {0} seconds to run ---".format(time.time() - start_time)) 
    return False
예제 #4
0
def ternary_smact_combos(position1, position2, position3, threshold=8):
    """ Combinatorially generate Pymatgen Species compositions using SMACT when up to three different
        lists are needed to draw species from (e.g. Ternary metal halides.)
    Args:
        position(n) (list of species): Species to be considered iteratively for each
                                     position.
        threshold (int): Max stoichiometry threshold.
    Returns:
        species_comps (list): Compositions as tuples of Pymatgen Species objects.
        """

    initial_comps_list = []
    for sp1, sp2, an in tqdm(itertools.product(position1, position2,
                                               position3)):
        e1, oxst1 = sp1.symbol, int(sp1.oxi_state)
        eneg1 = Element(e1).pauling_eneg
        e2, oxst2 = sp2.symbol, int(sp2.oxi_state)
        eneg2 = Element(e2).pauling_eneg
        e3, oxst3 = an.symbol, int(an.oxi_state)
        eneg3 = Element(e3).pauling_eneg

        symbols = [e1, e2, e3]
        ox_states = [oxst1, oxst2, oxst3]
        cn_e, cn_r = neutral_ratios(ox_states, threshold=threshold)

        if cn_e:
            enegs = [eneg1, eneg2, eneg3]
            eneg_ok = pauling_test(ox_states,
                                   enegs,
                                   symbols=symbols,
                                   repeat_cations=False)
            if eneg_ok:
                for ratio in cn_r:
                    comp = (symbols, ox_states, list(ratio))
                    initial_comps_list.append(comp)
    print('Number of compositions before reduction:  {}'.format(
        len(initial_comps_list)))

    # Create a list of pymatgen species for each comp
    print('Converting to Pymatgen Species...')
    species_comps = []
    for i in tqdm(initial_comps_list):
        comp = {}
        for sym, ox, ratio in zip(i[0], i[1], i[2]):
            comp[Specie(sym, ox)] = ratio
        comp_list = [[key] * val for key, val in comp.items()]
        comp_list = [item for sublist in comp_list for item in sublist]
        species_comps.append(comp_list)

    # Sort and ditch duplicates
    print(
        'Ditching duplicates (sorry to have got your hopes up with the big numbers)...'
    )
    for i in species_comps:
        i.sort()
        i.sort(key=lambda x: x.oxi_state, reverse=True)
    species_comps = list(set([tuple(i) for i in species_comps]))
    print('Total number of new compounds unique compositions: {0}'.format(
        len(species_comps)))
    return species_comps
def check_electronegativity_4(formula):
    pauling_count = 0
    comp = mg.Composition(formula)
    reduce_formula = comp.get_el_amt_dict()
    list_of_elements = list(reduce_formula.keys())
    stoichs = list(
        np.array(list(reduce_formula.values())).astype(np.int32)[:,
                                                                 np.newaxis])
    max_num = max(reduce_formula.values())
    for i, ele_a in enumerate(list_of_elements):
        paul_a = smact.Element(ele_a).pauling_eneg
        for ox_a in smact.Element(ele_a).oxidation_states:
            for j, ele_b in enumerate(list_of_elements[i + 1:]):
                paul_b = smact.Element(ele_b).pauling_eneg
                for ox_b in smact.Element(ele_b).oxidation_states:
                    for k, ele_c in enumerate(list_of_elements[i + j + 2:]):
                        paul_c = smact.Element(ele_c).pauling_eneg
                        for ox_c in smact.Element(ele_c).oxidation_states:
                            for m, ele_d in enumerate(
                                    list_of_elements[i + j + k + 3:]):
                                paul_d = smact.Element(ele_d).pauling_eneg
                                for ox_d in smact.Element(
                                        ele_d).oxidation_states:
                                    # Puts elements, oxidation states and electronegativites into lists for convenience #
                                    elements = [ele_a, ele_b, ele_c, ele_d]
                                    oxidation_states = [ox_a, ox_b, ox_c, ox_d]
                                    pauling_electro = [
                                        paul_a, paul_b, paul_c, paul_d
                                    ]
                                    if None in pauling_electro:
                                        print(
                                            "No pauling electronegativity data"
                                        )
                                        return False
                                    # Checks if the electronegativity makes sense and if the combination is charge neutral #
                                    electroneg_makes_sense = pauling_test(
                                        oxidation_states, pauling_electro,
                                        elements)
                                    cn_e, cn_r = neutral_ratios(
                                        [ox_a, ox_b, ox_c, ox_d],
                                        stoichs=stoichs,
                                        threshold=int(max_num))

                                    if cn_e:
                                        if electroneg_makes_sense:
                                            pauling_count = pauling_count + 1

                                            for num in cn_r:
                                                if tuple(reduce_formula.values(
                                                )) == num:
                                                    # print('{0:2s}{1:3d}   {2:2s}{3:3d}   {4:2s}{5:3d}'.format(ele_a, ox_a, ele_b,
                                                    #                                               ox_b, ele_c, ox_c))
                                                    return True

    # print('Number of combinations = {0}'.format(pauling_count))
    # print("--- {0} seconds to run ---".format(time.time() - start_time))
    return False
def check_electronegativity_8(formula):
    pauling_count = 0
    comp = mg.Composition(formula)
    reduce_formula = comp.get_el_amt_dict()
    list_of_elements = list(reduce_formula.keys())
    max_num = max(reduce_formula.values())
    # for element in reduce_formula.keys():
    #     print(len(smact.Element(element).oxidation_states), end = ",")

    for i, ele_a in enumerate(list_of_elements):
        paul_a = smact.Element(ele_a).pauling_eneg
        for ox_a in smact.Element(ele_a).oxidation_states:
            for j, ele_b in enumerate(list_of_elements[i+1:]):
                paul_b = smact.Element(ele_b).pauling_eneg
                for ox_b in smact.Element(ele_b).oxidation_states:
                    for k, ele_c in enumerate(list_of_elements[i+j+2:]):
                        paul_c = smact.Element(ele_c).pauling_eneg
                        for ox_c in smact.Element(ele_c).oxidation_states:
                            for m, ele_d in enumerate(list_of_elements[i+j+k+3:]):
                                paul_d = smact.Element(ele_d).pauling_eneg
                                for ox_d in smact.Element(ele_d).oxidation_states:
                                    for n, ele_e in enumerate(list_of_elements[i+j+k+m+4:]):
                                        paul_e = smact.Element(ele_e).pauling_eneg
                                        for ox_e in smact.Element(ele_e).oxidation_states:
                                            for p, ele_f in enumerate(list_of_elements[i+j+k+m+n+5:]):
                                                paul_f = smact.Element(ele_f).pauling_eneg
                                                for ox_f in smact.Element(ele_f).oxidation_states:
                                                    for q, ele_g in enumerate(list_of_elements[i+j+k+m+n+p+6:]):
                                                        paul_g = smact.Element(ele_g).pauling_eneg
                                                        for ox_g in smact.Element(ele_g).oxidation_states:
                                                            for s, ele_h in enumerate(list_of_elements[i+j+k+m+n+p+q+7:]):
                                                                paul_h = smact.Element(ele_h).pauling_eneg
                                                                for ox_h in smact.Element(ele_h).oxidation_states:
                                                                    # Puts elements, oxidation states and electronegativites into lists for convenience #
                                                                    elements = [ele_a, ele_b, ele_c, ele_d, ele_e, ele_f, ele_g, ele_h]
                                                                    oxidation_states = [ox_a, ox_b, ox_c, ox_d, ox_e, ox_f, ox_g, ox_h]
                                                                    pauling_electro = [paul_a, paul_b, paul_c, paul_d, paul_e, paul_f, paul_g, paul_h]
                                                                    if None in pauling_electro:
                                                                        print("No pauling electronegativity data")
                                                                        return False
                                                                    # Checks if the electronegativity makes sense and if the combination is charge neutral #
                                                                    electroneg_makes_sense = pauling_test(oxidation_states, pauling_electro, elements)
                                                                    cn_e, cn_r = neutral_ratios([ox_a, ox_b, ox_c, ox_d, ox_e, ox_f, ox_g, ox_h], threshold = int(max_num))
                                                                    
                                                                    if cn_e:
                                                                        if electroneg_makes_sense:
                                                                            pauling_count = pauling_count + 1

                                                                            for num in cn_r:
                                                                                if tuple(reduce_formula.values()) == num:
                                                                                    # print('{0:2s}{1:3d}   {2:2s}{3:3d}   {4:2s}{5:3d}'.format(ele_a, ox_a, ele_b,
                                                                                    #                                               ox_b, ele_c, ox_c))
                                                                                    return True
                                                              
    # print('Number of combinations = {0}'.format(pauling_count))
    # print("--- {0} seconds to run ---".format(time.time() - start_time)) 
    return False
def check_neutrality_8(formula):
    charge_neutral_count = 0
    comp = mg.Composition(formula)
    reduce_formula = comp.get_el_amt_dict()
    list_of_elements = list(reduce_formula.keys())
    stoichs = list(
                np.array(list(reduce_formula.values())).astype(np.int32)[:,np.newaxis]
            )
    max_num = max(reduce_formula.values())
    for element in reduce_formula.keys():
        print(len(smact.Element(element).oxidation_states), end = ",")

    for i, ele_a in enumerate(list_of_elements):
        for ox_a in smact.Element(ele_a).oxidation_states:
            for j, ele_b in enumerate(list_of_elements[i+1:]):
                for ox_b in smact.Element(ele_b).oxidation_states:
                    for k, ele_c in enumerate(list_of_elements[i+j+2:]):
                        for ox_c in smact.Element(ele_c).oxidation_states:
                            for m, ele_d in enumerate(list_of_elements[i+j+k+3:]):
                                for ox_d in smact.Element(ele_d).oxidation_states:
                                    for n, ele_e in enumerate(list_of_elements[i+j+k+m+4:]):
                                        for ox_e in smact.Element(ele_e).oxidation_states:
                                            for p, ele_f in enumerate(list_of_elements[i+j+k+m+n+5:]):
                                                for ox_f in smact.Element(ele_f).oxidation_states:
                                                    for q, ele_g in enumerate(list_of_elements[i+j+k+m+n+p+6:]):
                                                        for ox_g in smact.Element(ele_g).oxidation_states:
                                                            for s, ele_h in enumerate(list_of_elements[i+j+k+m+n+p+q+7:]):
                                                                for ox_h in smact.Element(ele_h).oxidation_states:
                                                                    # Checks if the combination is charge neutral before printing it out! #                        
                                                                    cn_e, cn_r = neutral_ratios([ox_a, ox_b, ox_c, ox_d, ox_e, ox_f, ox_g, ox_h], stoichs = stoichs, threshold = int(max_num))
                                                                    
                                                                    if cn_e:
                                                                        for num in cn_r:
                                                                            if tuple(reduce_formula.values()) == num:
                                                                                return True

                                                                            # print(cn_e)
                                                                            # print(cn_r)
                                                                            # print(ox_a, ox_b, ox_c)
                                                                            # charge_neutral_count = charge_neutral_count + 1
                                                                            # print('{0:3s}  {1:3s}  {2:3s}'.format(ele_a, ele_b, ele_c))
    print('Number of combinations = {0}'.format(charge_neutral_count))
    print("--- {0} seconds to run ---".format(time.time() - start_time)) 
    return False
예제 #8
0
def smact_test(els, threshold=8, species_unique=True):
    """Function that applies the charge neutrality and electronegativity
    tests in one go for simple application in external scripts that
    wish to apply the general 'smact test'.

    Args:
        els (tuple/list): A list of smact.Element objects
        threshold (int): Threshold for stoichiometry limit, default = 8
        species_unique (bool): Whether or not to consider elements in different
        oxidation states as unique in the results.
    Returns:
        allowed_comps (list): Allowed compositions for that chemical system
        in the form [(elements), (oxidation states), (ratios)] if species_unique=True
        or in the form [(elements), (ratios)] if species_unique=False.
    """
    compositions = []

    # Get symbols and electronegativities
    # print(els)
    # exit()
    symbols = tuple(e.symbol for e in els)
    electronegs = [e.pauling_eneg for e in els]
    ox_combos = [e.oxidation_states for e in els]
    for i, ox_states in enumerate(itertools.product(*ox_combos)):
        # Test for charge balance
        # print(i)
        cn_e, cn_r = neutral_ratios(ox_states, threshold=threshold)
        # Electronegativity test
        if cn_e:
            electroneg_OK = pauling_test(ox_states, electronegs)
            if electroneg_OK:
                for ratio in cn_r:
                    compositions.append(tuple([symbols, ox_states, ratio]))
    # exit()

    # Return list depending on whether we are interested in unique species combinations
    # or just unique element combinations.
    if species_unique:
        return (compositions)
    else:
        compositions = [(i[0], i[2]) for i in compositions]
        compositions = list(set(compositions))
        return compositions
예제 #9
0
파일: screening.py 프로젝트: ssthurai/SMACT
def smact_test(els, threshold=8, include=None):
    """Function that applies the charge neutrality and electronegativity
    tests in one go for simple application in external scripts that
    wish to apply the general 'smact test'.

    Args:
        els (tuple): A list of Element objects or symbols.
        threshold (int): Threshold for stoichiometry limit, default = 8.
        include (list): (optional) List of Element objects that must be in every composition.
    Returns:
        allowed_comps (list): Allowed compositions for that chemical system
        in the form [[elements], [ratios]]

    Note: Info on oxidation states is not returned, only the list of elements and unique allowed ratios.
    """
    ratios = []
    els = list(els)
    els = els + include if include != None else els

    # Get symbols and electronegativities
    symbols = [e.symbol for e in els]
    electronegs = [e.pauling_eneg for e in els]
    ox_combos = [e.oxidation_states for e in els]

    for ox_states in itertools.product(*ox_combos):
        # Test for charge balance
        cn_e, cn_r = neutral_ratios(ox_states, threshold=threshold)
        # Electronegativity test
        if cn_e:
            electroneg_OK = pauling_test(ox_states, electronegs)
            if electroneg_OK:
                ratios.append(cn_r)
    ratios = [item for sublist in ratios for item in sublist]
    ratios = list(set(ratios))
    compositions = [[symbols, x] for x in ratios]
    return compositions
예제 #10
0
파일: test.py 프로젝트: WMD-group/SMACT
 def test_neutral_ratios(self):
     ox = [1, -2, 1]
     is_neutral, neutral_combos = smact.neutral_ratios(ox)
     self.assertTrue((is_neutral))
     self.assertEqual(len(neutral_combos), 9)
     self.assertTrue((3, 2, 1) in neutral_combos)
예제 #11
0
 def test_neutral_ratios(self):
     ox = [1, -2, 1]
     is_neutral, neutral_combos = smact.neutral_ratios(ox)
     self.assertTrue((is_neutral))
     self.assertEqual(len(neutral_combos), 9)
     self.assertTrue((3, 2, 1) in neutral_combos)
예제 #12
0
    paul_A = smact.Element(ele_A).pauling_eneg
    for ox_A in smact.Element(ele_A).oxidation_states:
        for j, ele_B in enumerate(B_elements):
            paul_B = smact.Element(ele_B).pauling_eneg
            for ox_B in smact.Element(ele_B).oxidation_states:
                for k, ele_C in enumerate(C_elements):
                    paul_C = smact.Element(ele_C).pauling_eneg
                    for ox_C in smact.Element(ele_C).oxidation_states:

                        raw_ion_count = raw_ion_count + 1
                        elements = [ele_A, ele_B, ele_C]
                        ox_states = [ox_A, ox_B, ox_C]
                        electronegativities = [paul_A, paul_B, paul_C]

                        # Test for charge balance
                        cn_e, cn_r = smact.neutral_ratios(
                            ox_states, threshold=stoichiometry_limit)
                        if cn_e:
                            charge_balanced_count = charge_balanced_count + len(
                                cn_r)

                            # Electronegativity test
                            electroneg_OK = screening.pauling_test(
                                ox_states,
                                electronegativities,
                                elements,
                                threshold=0.0)
                            if electroneg_OK:
                                electroneg_OK_count = electroneg_OK_count + len(
                                    cn_r)

                                # Band gap test
예제 #13
0
 def n_neutral_ratios(oxidation_states, threshold=8):
     return len(smact.neutral_ratios(oxidation_states,
                                     threshold=threshold)[1])
예제 #14
0
 def n_neutral_ratios(oxidation_states, threshold=8):
     return len(smact.neutral_ratios(oxidation_states,
                                     threshold=threshold)[1])
예제 #15
0
    paul_A = smact.Element(ele_A).pauling_eneg
    for ox_A in smact.Element(ele_A).oxidation_states:
        for j, ele_B in enumerate(B_elements):
            paul_B = smact.Element(ele_B).pauling_eneg
            for ox_B in smact.Element(ele_B).oxidation_states:     
                for k, ele_C in enumerate(C_elements):
                    paul_C = smact.Element(ele_C).pauling_eneg
                    for ox_C in smact.Element(ele_C).oxidation_states:
                        
                        raw_ion_count = raw_ion_count + 1
                        elements = [ele_A, ele_B, ele_C]
                        ox_states = [ox_A, ox_B, ox_C]
                        electronegativities = [paul_A, paul_B, paul_C]

                        # Test for charge balance
                        cn_e, cn_r = smact.neutral_ratios(ox_states,threshold = stoichiometry_limit)
                        if cn_e:
                            charge_balanced_count = charge_balanced_count + len(cn_r)
                            
                            # Electronegativity test
                            electroneg_OK = screening.pauling_test(ox_states, electronegativities, elements, threshold = 0.0)
                            if electroneg_OK:
                                electroneg_OK_count = electroneg_OK_count + len(cn_r)
                                
                                # Band gap test
                                SSE_A = smact.Element(ele_A).SSE
                                SSE_B = smact.Element(ele_B).SSE
                                SSE_C = smact.Element(ele_C).SSE
                                BG_1 = abs(SSE_A - SSE_B)
                                BG_2 = abs(SSE_A - SSE_C)
                                if (BG_1 <= BG_max) and (BG_1 >= BG_min):