nano_exit

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

多重項を数える(1)

前回、binary表現を使って、電子配置を作ることを試みた。
koideforest.hatenadiary.com

次のステップとして多重項を数え上げるため、電子配置を作るのと同時に角運動量とスピンも一緒にリストで保存するように改良した。

def add_electron( configurations0, l ):
    configurations = []
    if configurations0 == []:
        for m in range( -l, l + 1 ):
            for ms in ( 0, 1 ):
                configurations.append([ binary_configuration( l, m, ms ), ms - 0.5, m ])
    else:
        for conf0 in configurations0:
            m0 = check_highest_m( conf0[ 0 ], l )
            for m in range( -l, l + 1 ):
                if m < m0: continue
                for ms in ( 0, 1 ):
                    if   check_unoccupied( conf0[ 0 ], l, m, ms ) \
                       & check_unpair( conf0[ 0 ], l, m, ms ):
                        configurations.append([ 
                            conf0[ 0 ] | binary_configuration( l, m, ms ),
                            conf0[ 1 ] + ( ms - 0.5 ),
                            conf0[ 2 ] + m
                        ])
    return configurations

角運動量とスピンの組から、多重項を抜き出す方法として、スレーターの方法(正式名称なのかは不明)を用いる。

  1. 角運動量およびスピンが最大の多重項から探索を始める。
  2. 必要な要素が全て揃った場合に多重項が存在すると判定。
  3. 判定後、それらの要素をリストから消す。
  4. リストが空になるまで繰り返す。

スピンが半整数の時と整数の時とあるので、ループの設定に多少苦労した。

def slater_s2l( s2l, l, n_ele ):
    lmax = l * n_ele
    smax = 1/2 * n_ele
    s_range = 1/2 if n_ele % 2 == 1 else 1
    multiplet = []
    for s_inv in range( int( smax + s_range ) ):
        for l_inv in range( lmax + 1 ):
            if not s2l: break
            multiplet_exist = True
            while multiplet_exist == True:
                for mms in np.arange( - ( smax - s_inv ), ( smax - s_inv ) + 1, 1 ):
                    for mm in range( - ( lmax - l_inv ), ( lmax - l_inv ) + 1 ):
                        if not [ int( 2 * mms ), mm ] in s2l:
                            multiplet_exist = False
                if multiplet_exist == True:
                    multiplet.append([ int( 2 * ( smax - s_inv ) ) + 1, ( lmax - l_inv ) ])
                    for mms in np.arange( - ( smax - s_inv ), ( smax - s_inv ) + 1 ):
                        for mm in range( - ( lmax - l_inv ), ( lmax - l_inv ) + 1 ):
                            s2l.remove( [ int( 2 * mms ), mm ] )
    return multiplet, s2l

def slater_configurations( configurations, l, n_ele ):
    s2l = [ [ int( 2 * conf[1] ), conf[2] ] for conf in configurations ]
    multiplet, s2l_rest =  slater_s2l( s2l, l, n_ele )
    if not s2l_rest == []:
        print( 'multiplet still exists in')
    return multiplet

 (nd)^3の電子状態に対して、適用してみる。

l = 2
n_ele = 3

conf = []
for i in range( n_ele ):
    conf = add_electron( conf, l )

multiplet = slater_configurations( conf, l, n_ele )
print( multiplet )

結果は、

[[4, 3], [4, 1], [2, 5], [2, 4], [2, 3], [2, 2], [2, 2], [2, 1]]

つまり、 {}^4F,  {}^4P,  {}^2H,  {}^2G,  {}^2F,  {}^2D,  {}^2D,  {}^2P であり、正しい結果と一致している。

 (nd)^3の時の多重項は、以下のサイトを参照。
LS多重項((nd)^3)の場合) [物理のかぎしっぽ]

後は、異なる軌道毎に多重項を出して、各多重項の合成が出来れば、任意の電子状態に対して多重項を求めることが出来る。