nano_exit

基礎的なことこそ、簡単な例が必要だと思うのです。

多重項を数える(2)

以前に、軌道内の多重項を求めるスクリプトを書いた。
koideforest.hatenadiary.com

ここではそれらを用いた上で、さらに軌道間で多重項を合成する。

  • 軌道の記号と値を行き来する関数
def spec2l( spec ):
    if spec in { "s", "S" }:
        l = 0
    elif spec in { "p", "P" }:
        l = 1
    elif spec in { "d", "D" }:
        l = 2
    elif spec in { "f", "F" }:
        l = 3
    elif spec in { "g", "G" }:
        l = 4
    elif spec in { "h", "H" }:
        l = 5
    elif spec in { "i", "I" }:
        l = 6
    elif spec in { "k", "K" }:
        l = 7
    elif spec in { "l", "L" }:
        l = 8
    elif spec in { "m", "M" }:
        l = 9
    elif spec in { "n", "N" }:
        l = 10
    elif spec in { "o", "O" }:
        l = 11
    elif spec in { "p", "P" }:
        l = 12
    elif spec in { "q", "Q" }:
        l = 13
    elif spec in { "r", "R" }:
        l = 14
    elif spec in { "s", "S" }:
        l = 15
    elif spec in { "t", "T" }:
        l = 16
    elif spec in { "u", "U" }:
        l = 17
    else:
        l = -1
    return l

def l2spec( l ):
    if l == 0:
        spec = "S"
    elif l == 1:
        spec = "P"
    elif l == 2:
        spec = "D"
    elif l == 3:
        spec = "F"
    elif l == 4:
        spec = "G"
    elif l == 5:
        spec = "H"
    elif l == 6:
        spec = "I"
    elif l == 7:
        spec = "K"
    elif l == 8:
        spec = "L"
    elif l == 9:
        spec = "M"
    elif l == 10:
        spec = "N"
    elif l == 11:
        spec = "O"
    elif l == 12:
        spec = "P"
    elif l == 13:
        spec = "Q"
    elif l == 14:
        spec = "R"
    elif l == 15:
        spec = "S"
    elif l == 16:
        spec = "T"
    elif l == 17:
        spec = "U"
    else:
        spec = "NaN"
    return spec
  • 電子配置から軌道角運動量と電子数を得る関数
def n_l_num( orbital ):
    n = int( orbital[ 0 ] )
    l = spec2l( orbital[ 1 ] )
    num = int( orbital[ 2: ] )
    return [ n, l, num ]

def separate( configuration ):
    orb_eles = configuration.split( " " )
    while "" in orb_eles: orb_eles.remove("")    
    conf = []
    for oe in orb_eles:
        conf.append( n_l_num( oe ) )
    return cons
  • 多重項同士を合成する関数
def spin2_add( s1, s2 ):
    # s = 2S
    ss = []
    for s in range( abs( s1 - s2 ), s1 + s2 + 2, 2 ):
        ss.append( s )
    return ss

def om_add( om1, om2 ):  # orbital momentum addition
    oms = []
    for om in np.arange( abs( om1 - om2 ), om1 + om2 + 1 ):
        oms.append( int( om ) )
    return omg

def orb2sl( orb ):  # mp_sl_orb to mp_sl
    if len( orb ) == 2:
        sl = []
        s1 = orb[0][0] - 1
        s2 = orb[1][0] - 1
        l1 = orb[0][1]
        l2 = orb[1][1]
        for s in spin2_add( s1, s2 ):
            for l in om_add( l1, l2 ):
                sl.append( [ s + 1, l ] )
        return sl
    else:
        return "NaN"
def sl2slj( sl ):  # mp_sl to mp_slj
    # Caution: j = 2 * J + 1
    s = ( sl[0] - 1 ) / 2.
    l = sl[1]
    slj = []
    for ss in np.arange( - s, s + 1, 1. ):
        j = int( 2 * abs( l + ss ) + 1 )
        slj.append([ sl[0], sl[1], j ])
    return slj

def mp_sl_2_mp_slj( mp_sl ):
    mp_slj = []
    for mp in mp_sl:
        mp_slj += sl2slj( mp )
    return mp_slj
  • 多重項を記号で表す関数
def value2symbol( v ):
    return "{:d}{:s}{:d}".format( v[0], l2spec( v[1] ), v[2] )


例として、Ce {}^{3+}イオンの L_{2,3} edgeの終状態について多重項を求めてみる。

# input
configuration = "2p5 4f1 5d1"  # Ce3+ L2,3 edge
orbs = separate( configuration )

# multiplet within each orbital
mp_sl_orb = []
for orb in orbs:
    n   = orb[0]
    l   = orb[1]
    num = orb[2]
    conf = []
    for i in range( num ):
        conf = add_electron( conf, l )
    mp_sl_orb.append( slater_configurations( conf, l, num ) )

# multiplet including all orbitals
mp_sl = []
for mp1 in mp_sl_orb[0]:
    for mp2 in mp_sl_orb[1]:
            mp_sl += orb2sl([ mp1, mp2 ])
if len( mp_sl_orb ) > 2:
    for i in range( len( mp_sl_orb ) )[ 2: ]:
        old = copy.deepcopy( mp_sl )
        mp_sl = []
        for mp1 in old:
            for mp2 in mp_sl_orb[ i ]:
                mp_sl += orb2sl([ mp1, mp2 ])    

# add total angular momentum j (j = 2J + 1)
mp_slj = mp_sl_2_mp_slj( mp_sl )
print( [ value2symbol( mp ) for mp in mp_slj ] )


結果、多重項がこれでもかと出てくる。

['2S2', '2S2', '2P2', '2P4', '2D4', '2D6', '2F6', '2F8', '2G8', '2G10', '2P2', '2P4', '2D4', '2D6', '2F6', '2F8', '2G8', '2G10', '2H10', '2H12', '2D4', '2D6', '2F6', '2F8', '2G8', '2G10', '2H10', '2H12', '2I12', '2I14', '2S2', '2S2', '2P2', '2P4', '2D4', '2D6', '2F6', '2F8', '2G8', '2G10', '4S4', '4S2', '4S2', '4S4', '4P2', '4P2', '4P4', '4P6', '4D2', '4D4', '4D6', '4D8', '4F4', '4F6', '4F8', '4F10', '4G6', '4G8', '4G10', '4G12', '2P2', '2P4', '2D4', '2D6', '2F6', '2F8', '2G8', '2G10', '2H10', '2H12', '4P2', '4P2', '4P4', '4P6', '4D2', '4D4', '4D6', '4D8', '4F4', '4F6', '4F8', '4F10', '4G6', '4G8', '4G10', '4G12', '4H8', '4H10', '4H12', '4H14', '2D4', '2D6', '2F6', '2F8', '2G8', '2G10', '2H10', '2H12', '2I12', '2I14', '4D2', '4D4', '4D6', '4D8', '4F4', '4F6', '4F8', '4F10', '4G6', '4G8', '4G10', '4G12', '4H8', '4H10', '4H12', '4H14', '4I10', '4I12', '4I14', '4I16']

これを手でやる気にはなれない。

ここでは多重項のみを求めたが、実際にエネルギーを求めるには、ちゃんと波動関数の組み合わせまで再現する必要がある。
その場合には、おそらく他の方法が必要だが、とりあえずは目的が達成出来たと思う。