Atomic term symbols
Posted on 10 February 2017
The problem of predicting the term symbols for states derived from a $nl^r$ atomic configuration (without using group theory!) provides a good use of Python's collections
and itertools
libraries.
The function below can be passed the orbital angular momentum quantum number, $l$, and number of electrons, $r$ and returns a list of the term symbols for the corresponding configuration. Because of the way this list is constructed, the ground state is guaranteed to be the first item in this list. For example,
In [4]: get_term_symbols(1, 2) # p2 configuration
Out[4]: ['3P', '1D', '1S']
In [5]: get_term_symbols(3, 2) # f2 configuration
Out[5]: ['3H', '3F', '3P', '1I', '1G', '1D', '1S']
The code defining the function get_term_symbols
is below.
from itertools import repeat, product, combinations
from collections import Counter
term_letters = 'SPDFGHIKLMNOQRTUVWXYZ'
def get_term_symbols(l, r):
"""Return a list of term symbols for the configuration l^r."""
# Total number of (ml, ms) pairs for this subshell.
n = (2*l+1)*2
# All possible values of ml = -l, -l+1, ..., l-1, l.
ml = list(range(-l,l+1))
# All possible values of 2ms = -1, 1. That is, ms = -1/2, +1/2. We work
# with 2ms instead of ms so that we can handle integers only.
ms2 = [-1,1]
# All possible (ml, 2ms) pairs for this subshell.
ml_ms2 = list(product(ml, ms2))
# All possible microstates for r electrons in this subshell.
microstates = list(combinations(range(n), r))
# The totals ML = sum(ml) and MS2 = sum(2ms) for each microstate
ML = [sum([ml_ms2[microstate[j]][0] for j in range(r)])
for microstate in microstates]
MS2 = [sum([ml_ms2[microstate[j]][1] for j in range(r)])
for microstate in microstates]
# Count the microstates (MS, ML). Store them this way round so we can
# pick off the ground state term (maximum S) first.
MS2_ML = Counter(zip(MS2,ML))
N = len(microstates)
# Extract the term symbols by starting at the minimum (ML, MS) value and
# removing microstates corresponding to the (L, S) term it belongs to.
# Repeat until we're out of microstates.
terms = []
while N>0:
S, L = min(MS2_ML)
terms.append('{}{}'.format(-S+1, term_letters[-L]))
for ML in range(L, -L+1):
for MS in range(S, -S+1,2):
MS2_ML[MS,ML] -= 1
if MS2_ML[MS,ML] == 0:
del MS2_ML[MS,ML]
N -= 1
return terms