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_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
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 test_smact_test(self): Na, Fe, Cl = (smact.Element(label) for label in ('Na', 'Fe', 'Cl')) self.assertEqual(smact.screening.smact_test([Na, Fe, Cl], threshold=2), [(('Na', 'Fe', 'Cl'), (1, -1, -1), (2, 1, 1)), (('Na', 'Fe', 'Cl'), (1, 1, -1), (1, 1, 2))]) self.assertEqual( len(smact.screening.smact_test([Na, Fe, Cl], threshold=8)), 77)
def test_pauling_test(self): Sn, S = (smact.Element(label) for label in ('Sn', 'S')) self.assertTrue( smact.screening.pauling_test( (+2, -2), (Sn.pauling_eneg, S.pauling_eneg), )) self.assertFalse( smact.screening.pauling_test((-2, +2), (Sn.pauling_eneg, S.pauling_eneg))) self.assertFalse( smact.screening.pauling_test( (-2, -2, +2), (S.pauling_eneg, S.pauling_eneg, Sn.pauling_eneg), symbols=('S', 'S', 'Sn'), repeat_anions=False)) self.assertTrue( smact.screening.pauling_test( (-2, -2, +2), (S.pauling_eneg, S.pauling_eneg, Sn.pauling_eneg), symbols=('S', 'S', 'Sn'), repeat_cations=False)) self.assertFalse( smact.screening.pauling_test( (-2, +2, +2), (S.pauling_eneg, Sn.pauling_eneg, Sn.pauling_eneg), symbols=('S', 'Sn', 'Sn'), repeat_cations=False)) self.assertTrue( smact.screening.pauling_test( (-2, +2, +2), (S.pauling_eneg, Sn.pauling_eneg, Sn.pauling_eneg), symbols=('S', 'Sn', 'Sn'), repeat_anions=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 test_eneg_states_test_alternate(self): Na, Fe, Cl = (smact.Element(label) for label in ('Na', 'Fe', 'Cl')) self.assertTrue( smact.screening.eneg_states_test_alternate( [1, 3, -1], [Na.pauling_eneg, Fe.pauling_eneg, Cl.pauling_eneg])) self.assertFalse( smact.screening.eneg_states_test_alternate( [-1, 3, 1], [Na.pauling_eneg, Fe.pauling_eneg, Cl.pauling_eneg]))
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
def test_ml_rep_generator(self): Pb, O = (smact.Element(label) for label in ('Pb', 'O')) PbO2_ml = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6666666666666666, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3333333333333333, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] self.assertEqual(smact.screening.ml_rep_generator(['Pb', 'O'], [1, 2]), PbO2_ml) self.assertEqual(smact.screening.ml_rep_generator([Pb, O], [1, 2]), PbO2_ml)
def eneg_mulliken(element): """Get Mulliken electronegativity from the IE and EA. Arguments: symbol (smact.Element or str): Element object or symbol Returns: mulliken (float): Mulliken electronegativity """ if type(element) == str: element = smact.Element(element) elif type(element) != smact.Element: raise Exception("Unexpected type: {0}".format(type(element))) mulliken = (element.ionpot + element.e_affinity) / 2.0 return mulliken
def possible_elements(elements, oxidations): """Identify possible atoms to occupy a site Args: elements: oxidations: Returns: Array of atoms """ atoms = [] for element in elements: elemental_oxidations = smact.Element(element).oxidation_states for ox_state_a in oxidations: for element_ox in elemental_oxidations: if int(element_ox) == int(ox_state_a): atoms.append(element) return atoms
def main(): crystal_elements = input( 'Which elements? Separate chemical symbols with a space. ') crystal_elements = crystal_elements.split() a_lattices = [lp.fcc, lp.bcc, lp.hcp, lp.diamond, lp.bct] b_lattices = [lp.rocksalt, lp.b2, lp.zincblende, lp.wurtzite, lp.b10] e_lattices = [lp.cubic_perovskite] # Processing Lattices #------------------------------------------------------------------------------------------ ## A-types print(" \n=========================================") print(" AAA ####### ## ## ##### #####") print(" AA A ## ## ## ## ## ##") print(" AAAAAA #### ## ## ##### #####") print(" AA AA ## ## ## ##") print("AA AA ## ## ## #####") print("=========================================") print(" \n ### A type lattices ###\n ") for lattice in a_lattices: print((' \n===============\n ') + lattice.__name__.upper() + (' Lattice \n===============\n ')) for elements in crystal_elements: x = smact.Element(elements) a, b, c, alpha, beta, gamma = lattice(x.covalent_radius) print(elements, "%.2f" % a, "%.2f" % b, "%.2f" % c, "%.1f" % alpha, "%.1f" % beta, "%.1f" % gamma) print( ' \n Key :: Element a b c alpha beta gamma \n///////////////////////////////////////////////////////////////////////////////////////\n ' ) oxidation = [] coordination = [] i = 0 for elements in crystal_elements: poss_ox = [] poss_cood = [] with open('data/shannon_radii.csv', 'rU') as f: reader = csv.reader(f) for row in reader: if row[0] == elements: poss_ox.append(row[1]) poss_cood.append(row[2]) poss_ox_clean = [] ### Duplicates removed for ox in poss_ox: if ox not in poss_ox_clean: poss_ox_clean.append(ox) print(elements) print(poss_ox_clean) if len(poss_ox_clean) == 1: oxidation.append(int(poss_ox_clean[0])) else: oxidation.append(int(input('Oxidation state of ' + elements + ' '))) poss_co_clean = [] ### Duplicates removed with open('data/shannon_radii.csv', 'rU') as f: reader = csv.reader(f) poss_cood = [] for row in reader: if row[0] == elements and int(row[1]) == int(oxidation[-1]): poss_cood.append(row[2]) for co in poss_cood: if co not in poss_co_clean: poss_co_clean.append(co) print(elements) print(poss_co_clean) if len(poss_co_clean) == 1: coordination.append(poss_co_clean[0]) else: coordination.append( input('Coordination state of ' + elements + ' ')) print(elements, oxidation[i], coordination[i]) i += 1 ## B-types #-------------------------------------------------------------------------------------# print(" \n=========================================") print(" BBBB ####### ## ## ##### #####") print(" BB BB ## ## ## ## ## ##") print(" BBBB ### ## ## ##### #####") print(" BB BB ## ## ## ##") print("BBBB ## ## ## #####") print("=========================================") print(" \n ### B type lattices ###\n ") for lattice in b_lattices: print((' \n===============\n ') + lattice.__name__.upper() + (' Lattice \n===============\n ')) shannon_radius = [] for i, elements in enumerate(crystal_elements): print(elements, oxidation[i], coordination[i]) x = smact.Species(elements, oxidation[i], coordination[i]) shannon_radius.append(float(x.shannon_radius)) a, b, c, alpha, beta, gamma = lattice(shannon_radius) if lattice.__name__ == 'wurtzite': inner_space = a * (6**0.5) - (4 * shannon_radius[0]) print("With a gap in the middle of " + "%.2f" % inner_space + " (diameter)") print(crystal_elements[0:2], "%.2f" % a, "%.2f" % b, "%.2f" % c, "%.1f" % alpha, "%.1f" % beta, "%.1f" % gamma) # E Types #-------------------------------------------------------------------------------------# print(" \n=========================================") print(" EEEEE ####### ## ## ##### #####") print(" EE ## ## ## ## ## ##") print(" EEEE ### ## ## ##### #####") print(" EE ## ## ## ##") print("EEEEE ## ## ## #####") print("=========================================") print(" \n ### E type lattices ###\n ") for lattice in e_lattices: print((' \n===============\n ') + lattice.__name__.upper() + (' Lattice \n===============\n ')) shannon_radius = [] for i, elements in enumerate(crystal_elements): print(elements, oxidation[i], coordination[i]) x = smact.Species(elements, oxidation[i], coordination[i]) shannon_radius.append(float(x.shannon_radius)) a, b, c, space, alpha, beta, gamma = lattice(shannon_radius) print(crystal_elements[0:], "%.2f" % a, "%.2f" % b, "%.2f" % c, "%.1f" % alpha, "%.1f" % beta, "%.1f" % gamma) print("With a gap in the middle of " + "%.2f" % space + " (diameter)")
#!/usr/bin/env python import smact from numpy import product,sqrt from smact.data import get_covalent from scipy.constants import hbar, m_e # Get element info An =raw_input("Enter Anion Symbol: ") Cat =raw_input("Enter Cation Symbol: ") eig_an = smact.Element(An).eig eig_cat = smact.Element(Cat).eig # Calculations V2 = (2.16*(hbar)**2)/m_e*(((get_covalent(An)**-9))+((get_covalent(Cat))**-9)**2) V3 = (eig_cat - eig_an)/2 Ev = ((eig_cat + eig_an)/2) - (sqrt((V2**2)+(V3**2))) print An, get_covalent(An) print Cat, get_covalent(Cat) print "V2:", V2, "V3:", V3 print "Valence Band Maximum = ", Ev
row[1]) in site_B.oxidation_states: B_list.append([row[0], float(row[1]), float(row[4])]) # ## Iterative search # Having constructed potential element lists for each of the sites we now do an iterative search through all poaaible combinations, applying different levels of screening. # 1. A =/= B. # 2. Charge neutrality. # 3. Goldschmidt tolerance factors. # 4. Environmental screening (greater HHI resource than CZTS). # In[7]: elements_dict = {} for symbol, _, __ in A_list + B_list + C_list: if symbol not in elements_dict: elements_dict.update({symbol: smact.Element(symbol)}) # In[11]: charge_balanced = [] goldschmidt_cubic = [] goldschmidt_ortho = [] a_too_large = [] A_B_similar = [] pauling_perov = [] anion_stats = [] hhi_cdte = 2904 enviro_perovskites = 0 total = 0 for C_sym, C_ox, C_r in C_list: C_el = elements_dict[C_sym]
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 ] # 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
goldschmidt_ortho = [] a_too_large = [] A_B_similar = [] 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:
def test_Element_class_Pt(self): Pt = smact.Element('Pt') self.assertEqual(Pt.name, 'Platinum') self.assertEqual(Pt.ionpot, 8.95883) self.assertEqual(Pt.number, 78) self.assertEqual(Pt.dipol, 44.00)
# ## Setting up the chemical space for the search # Initially we define all the A elements to consider as those which have an SSE value considered_elements = [] with open(path.join(smact.data_directory, 'SSE.csv'), 'rU') as f: reader = csv.reader(f) for row in reader: considered_elements.append(row[0]) # We define a minimum SSE that the A element must have in order that it lies above the reduction potential for water splitting SSE_min = -4.5 A_elements = [] for cation in considered_elements: A_SSE = smact.Element(cation).SSE if A_SSE >= SSE_min: A_elements.append(cation) # We define our B and C elements B_elements = ['O', 'S', 'Se', 'Te'] C_elements = ['F', 'Cl', 'Br', 'I'] # ## Iterative search # We now screen for possible element combinations and apply various levels of screening: # # 1. There must exist a charge neutral combination for some stoichiometry where x,y,z are between 1 and 8 # 2. The combination must not contravene the electronegativity rule # 3. The predicted band gap must be between 1.5 and 2.5 eV # 4. Environmental screening based on HHI$_R$
def compound_electroneg(verbose=False, elements=None, stoichs=None, source='Mulliken'): """Estimate electronegativity of compound from elemental data. Uses Mulliken electronegativity by default, which uses elemental ionisation potentials and electron affinities. Alternatively, can use Pauling electronegativity, re-scaled by factor 2.86 to achieve same scale as Mulliken method (Nethercot, 1974) DOI:10.1103/PhysRevLett.33.1088 . Geometric mean is used (n-th root of product of components), e.g.: X_Cu2S = (X_Cu * X_Cu * C_S)^(1/3) Args: elements (list) : Elements given as standard elemental symbols. stoichs (list) : Stoichiometries, given as integers or floats. verbose (bool) : An optional True/False flag. If True, additional information is printed to the standard output. [Default: False] source: String 'Mulliken' or 'Pauling'; type of Electronegativity to use. Note that in SMACT, Pauling electronegativities are rescaled to a Mulliken-like scale. Returns: Electronegativity (float) : Estimated electronegativity (no units). """ if type(elements[0]) == str: elementlist = [smact.Element(i) for i in elements] elif type(elements[0]) == smact.Element: elementlist = elements else: raise Exception( "Please supply a list of element symbols or SMACT Element objects") stoichslist = stoichs # Convert stoichslist from string to float stoichslist = list(map(float, stoichslist)) # Get electronegativity values for each element if source == 'Mulliken': elementlist = [(el.ionpot + el.e_affinity) / 2.0 for el in elementlist] elif source == 'Pauling': elementlist = [(2.86 * el.pauling_eneg) for el in elementlist] else: raise Exception("Electronegativity type '{0}'".format(source), "is not recognised") # Print optional list of element electronegativities. # This may be a useful sanity check in case of a suspicious result. if verbose: print("Electronegativities of elements=", elementlist) # Raise each electronegativity to its appropriate power # to account for stoichiometry. for i in range(0, len(elementlist)): elementlist[i] = [elementlist[i]**stoichslist[i]] # Calculate geometric mean (n-th root of product) prod = product(elementlist) compelectroneg = (prod)**(1.0 / (sum(stoichslist))) if verbose: print("Geometric mean = Compound 'electronegativity'=", compelectroneg) return compelectroneg