예제 #1
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_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
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_7(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:
                                                            # 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]
                                                            oxidation_states = [ox_a, ox_b, ox_c, ox_d, ox_e, ox_f, ox_g]
                                                            pauling_electro = [paul_a, paul_b, paul_c, paul_d, paul_e, paul_f, paul_g]
                                                            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], 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
예제 #5
0
pauling_perov = []
anion_stats = []
for C in C_list:
    anion_hex = 0
    anion_cub = 0
    anion_ort = 0
    for B in B_list:
        for A in A_list:
            if B[0] != A[0]:
                if C[0] != A[0] and C[0] != B[0]:
                    if int(A[1]) + int(B[1]) + 3 * int(C[1]) == 0:
                        charge_balanced.append([A[0], B[0], C[0]])
                        paul_a = smact.Element(A[0]).pauling_eneg
                        paul_b = smact.Element(B[0]).pauling_eneg
                        paul_c = smact.Element(C[0]).pauling_eneg
                        electroneg_makes_sense = screening.pauling_test(
                            [A[1], B[1], C[1]], [paul_a, paul_b, paul_c])
                        if electroneg_makes_sense:
                            pauling_perov.append([A[0], B[0], C[0]])
                        tol = (float(A[2]) + C[2]) / (np.sqrt(2) *
                                                      (float(B[2]) + C[2]))
                        if tol > 1.0:
                            a_too_large.append([A[0], B[0], C[0]])
                            anion_hex = anion_hex + 1
                        if tol > 0.9 and tol <= 1.0:
                            goldschmidt_cubic.append([A[0], B[0], C[0]])
                            anion_cub = anion_cub + 1
                        if tol >= 0.71 and tol < 0.9:
                            goldschmidt_ortho.append([A[0], B[0], C[0]])
                            anion_ort = anion_ort + 1
                        if tol < 0.71:
                            A_B_similar.append([A[0], B[0], C[0]])
예제 #6
0
                        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):
                                    BG_OK_count = BG_OK_count + len(cn_r)
                                    entry = [elements, SSE_A, SSE_B, BG_1]
예제 #7
0
pauling_perov = []
anion_stats = []
for C in C_list:
    anion_hex = 0
    anion_cub = 0
    anion_ort = 0
    for B in B_list:
        for A in A_list:
            if B[0] != A[0]:        
                if C[0] != A[0] and C[0] != B[0]:
                    if int(A[1])+int(B[1])+3*int(C[1]) == 0:
                         charge_balanced.append([A[0],B[0],C[0]])
                         paul_a = smact.Element(A[0]).pauling_eneg
                         paul_b = smact.Element(B[0]).pauling_eneg
                         paul_c = smact.Element(C[0]).pauling_eneg
                         electroneg_makes_sense = screening.pauling_test([A[1],B[1],C[1]], [paul_a,paul_b,paul_c])
                         if electroneg_makes_sense:
                             pauling_perov.append([A[0],B[0],C[0]])
                         tol = (float(A[2]) + C[2])/(np.sqrt(2)*(float(B[2])+C[2]))
                         if tol > 1.0:
                            a_too_large.append([A[0],B[0],C[0]])
                            anion_hex = anion_hex+1
                         if tol > 0.9 and tol <= 1.0:
                            goldschmidt_cubic.append([A[0],B[0],C[0]])
                            anion_cub = anion_cub + 1
                         if tol >= 0.71 and tol < 0.9:
                            goldschmidt_ortho.append([A[0],B[0],C[0]])
                            anion_ort = anion_ort + 1
                         if tol < 0.71:
                            A_B_similar.append([A[0],B[0],C[0]])
    anion_stats.append([anion_hex,anion_cub,anion_ort]) 
예제 #8
0
                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):
                                    BG_OK_count = BG_OK_count + len(cn_r)
                                    entry = [elements, SSE_A, SSE_B, BG_1]
                                    if entry not in unique_ABCs:
                                        unique_ABCs.append(entry)
                                elif (BG_2 <= BG_max) and (BG_2 >= BG_min):