__all__ = ['get_gaunt', 'umat_slater', 'get_umat_kanamori_ge', 'get_F0',
'get_umat_slater', 'get_umat_kanamori', 'get_umat_slater_3shells']
import numpy as np
from sympy.physics.wigner import gaunt
from .basis_transform import tmat_c2r, tmat_r2c, tmat_c2j, transform_utensor
from .utils import info_atomic_shell, case_to_shell_name, slater_integrals_name
[docs]def get_gaunt(l1, l2):
"""
Calculate the Gaunt coefficents :math:`C_{l_1,l_2}(k,m_1,m_2)`
.. math::
C_{l_1,l_2}(k,m_1,m_2)=\\sqrt{\\frac{4\\pi}{2k+1}} \\int
\\mathop{d\\phi} \\mathop{d\\theta} sin(\\theta)
Y_{l_1}^{m_1\\star}(\\theta,\\phi) Y_{k}^{m_1-m_2}(\\theta,\\phi)
Y_{l_2}^{m_2}(\\theta,\\phi)
Parameters
----------
l1: int
The first quantum number of angular momentum.
l2: int
The second quantum number of angular momentum.
Returns
-------
res: 3d float array
The calculated Gaunt coefficents.
The 1st index (:math:`= 0, 1, ..., l_1+l_2+1`) is the order :math:`k`.
The 2nd index (:math:`= 0, 1, ... ,2l_1`) is the magnetic quantum
number :math:`m_1` plus :math:`l_1`
The 3nd index (:math:`= 0, 1, ... ,2l_2`) is the magnetic quantum
number :math:`m_2` plus :math:`l_2`
Notes
-----
It should be noted that :math:`C_{l_1,l_2}(k,m_1,m_2)` is
nonvanishing only when
:math:`k + l_1 + l_2 = \\text{even}`,
and
:math:`|l_1 - l_2| \\leq k \\leq l_1 + l_2`.
Please see Ref. [1]_ p. 10 for more details.
References
----------
.. [1] Sugano S, Tanabe Y and Kamimura H. 1970. Multiplets of
Transition-Metal Ions in Crystals. Academic Press, New York and London.
Examples
--------
>>> import edrixs
Get gaunt coefficients between :math:`p`-shell and :math:`d`-shell
>>> g = edrixs.get_gaunt(1, 2)
"""
from sympy import N
res = np.zeros((l1 + l2 + 1, 2 * l1 + 1, 2 * l2 + 1), dtype=np.float64)
for k in range(l1 + l2 + 1):
if not (np.mod(l1 + l2 + k, 2) == 0 and np.abs(l1 - l2) <= k <= l1 + l2):
continue
for i1, m1 in enumerate(range(-l1, l1 + 1)):
for i2, m2 in enumerate(range(-l2, l2 + 1)):
res[k, i1, i2] = (N(gaunt(l1, k, l2, -m1, m1 - m2, m2)) *
(-1.0)**m1 * np.sqrt(4 * np.pi / (2 * k + 1)))
return res
[docs]def umat_slater(l_list, fk):
"""
Calculate the Coulomb interaction tensor which is parameterized by
Slater integrals :math:`F^{k}`:
.. math::
U_{m_{l_i}m_{s_i}, m_{l_j}m_{s_j}, m_{l_t}m_{s_t},
m_{l_u}m_{s_u}}^{i,j,t,u}
=\\frac{1}{2} \\delta_{m_{s_i},m_{s_t}}\\delta_{m_{s_j},m_{s_u}}
\\delta_{m_{l_i}+m_{l_j}, m_{l_t}+m_{l_u}}
\\sum_{k}C_{l_i,l_t}(k,m_{l_i},m_{l_t})C_{l_u,l_j}
(k,m_{l_u},m_{l_j})F^{k}_{i,j,t,u}
where :math:`m_s` is the magnetic quantum number for spin
and :math:`m_l` is the magnetic quantum number for orbital.
:math:`F^{k}_{i,j,t,u}` are Slater integrals.
:math:`C_{l_i,l_j}(k,m_{l_i},m_{l_j})` are Gaunt coefficients.
Parameters
----------
l_list: list of int
contains the quantum number of orbital angular momentum
:math:`l` for each shell.
fk: dict of float
contains all the possible Slater integrals between the shells
in l_list, the key is a tuple of 5 ints (:math:`k,i,j,t,u`),
where :math:`k` is the order,
:math:`i,j,t,u` are the shell indices begin with 1.
Returns
-------
umat: 4d array of complex
contains the Coulomb interaction tensor.
Examples
--------
>>> import edrixs
For only one :math:`d`-shell
>>> l_list = [2]
>>> fk={}
>>> F0, F2, F4 = 5.0, 4.0 2.0
>>> fk[(0,1,1,1,1)] = F0
>>> fk[(2,1,1,1,1)] = F2
>>> fk[(4,1,1,1,1)] = F4
>>> umat_d = edrixs.umat_slater(l_list, fk)
For one :math:`d`-shell and one :math:`p`-shell
>>> l_list = [2,1]
>>> fk={}
>>> F0_dd, F2_dd, F4_dd = 5.0, 4.0, 2.0
>>> F0_dp, F2_dp = 4.0, 2.0
>>> G1_dp, G3_dp = 2.0, 1.0
>>> F0_pp, F2_pp = 2.0, 1.0
>>> fk[(0,1,1,1,1)] = F0_dd
>>> fk[(2,1,1,1,1)] = F2_dd
>>> fk[(4,1,1,1,1)] = F4_dd
>>> fk[(0,1,2,1,2)] = F0_dp
>>> fk[(0,2,1,2,1)] = F0_dp
>>> fk[(2,1,2,1,2)] = F2_dp
>>> fk[(2,2,1,2,1)] = F2_dp
>>> fk[(1,1,2,2,1)] = G1_dp
>>> fk[(1,2,1,1,2)] = G1_dp
>>> fk[(3,1,2,2,1)] = G3_dp
>>> fk[(3,2,1,1,2)] = G3_dp
>>> fk[(0,2,2,2,2)] = F0_pp
>>> fk[(2,2,2,2,2)] = F2_pp
>>> umat_dp = edrixs.umat_slater(l_list, fk)
See also
--------
coulomb_utensor.get_umat_slater
coulomb_utensor.get_umat_kanamori
coulomb_utensor.get_umat_kanamori_ge
"""
k_list = list(range(0, 2 * max(l_list) + 1))
ck = {}
orb_label = []
# for each shell
for i, l in enumerate(l_list):
# magnetic quantum number
for m in range(-l, l + 1):
# spin part, up,dn
for spin in range(2):
orb_label.append((i + 1, l, m, spin))
# all the possible gaunt coefficient
for l1 in l_list:
for l2 in l_list:
ck_tmp = get_gaunt(l1, l2)
for m1 in range(-l1, l1 + 1):
for m2 in range(-l2, l2 + 1):
for k in k_list:
if (np.mod(l1 + l2 + k, 2) == 0 and np.abs(l1 - l2) <= k <= l1 + l2):
ck[(k, l1, m1, l2, m2)] = ck_tmp[k, m1 + l1, m2 + l2]
else:
ck[(k, l1, m1, l2, m2)] = 0
# build the coulomb interaction tensor
norbs = len(orb_label)
umat = np.zeros((norbs, norbs, norbs, norbs), dtype=np.complex128)
for orb1 in range(norbs):
for orb2 in range(norbs):
for orb3 in range(norbs):
for orb4 in range(norbs):
i1, l1, m1, sigma1 = orb_label[orb1]
i2, l2, m2, sigma2 = orb_label[orb2]
i3, l3, m3, sigma3 = orb_label[orb3]
i4, l4, m4, sigma4 = orb_label[orb4]
if (m1 + m2) != (m3 + m4):
continue
if (sigma1 != sigma3) or (sigma2 != sigma4):
continue
res = 0.0
for k in k_list:
tmp_key = (k, i1, i2, i3, i4)
if tmp_key in list(fk.keys()):
res += ck[(k, l1, m1, l3, m3)] * ck[(k, l4, m4, l2, m2)] * fk[tmp_key]
umat[orb1, orb2, orb4, orb3] = res
umat = umat / 2.0
return umat
[docs]def get_umat_kanamori_ge(norbs, U1, U2, J, Jx, Jp):
"""
Calculate the Coulomb interaction tensor for a Kanamori-type interaction.
For the general case, it is parameterized by :math:`U_1, U_2, J, J_x, J_p`.
Parameters
----------
norbs: int
number of orbitals (including spin).
U1: float
Hubbard :math:`U` for electrons residing on the same orbital with opposite spin.
U2: float
Hubbard :math:`U` for electrons residing on different orbitals.
J: float
Hund's coupling for density-density interaction.
Jx: float
Hund's coupling for spin flip.
Jp: float
Hund's coupling for pair-hopping.
Returns
-------
umat: 4d complex array
The calculated Coulomb interaction tensor
Notes
-----
The order of spin index is: up, down, up, down, ..., up, down.
See Also
--------
coulomb_utensor.get_umat_kanamori
coulomb_utensor.get_umat_slater
coulomb_utensor.umat_slater
"""
umat = np.zeros((norbs, norbs, norbs, norbs), dtype=np.complex128)
for alpha in range(0, norbs - 1):
for beta in range(alpha + 1, norbs):
for gamma in range(0, norbs - 1):
for delta in range(gamma + 1, norbs):
aband = alpha // 2
aspin = alpha % 2
bband = beta // 2
bspin = beta % 2
gband = gamma // 2
gspin = gamma % 2
dband = delta // 2
dspin = delta % 2
dtmp = 0.0
if ((alpha == gamma) and (beta == delta)):
if ((aband == bband) and (aspin != bspin)):
dtmp = dtmp + U1
if ((alpha == gamma) and (beta == delta)):
if (aband != bband):
dtmp = dtmp + U2
if ((alpha == gamma) and (beta == delta)):
if ((aband != bband) and (aspin == bspin)):
dtmp = dtmp - J
if ((aband == gband) and (bband == dband)):
if ((aspin != gspin) and (bspin != dspin)
and (aspin != bspin)):
dtmp = dtmp - Jx
if ((aband == bband) and (dband == gband)
and (aband != dband)):
if ((aspin != bspin) and (dspin != gspin)
and (aspin == gspin)):
dtmp = dtmp + Jp
umat[alpha, beta, delta, gamma] = dtmp
return umat
def get_F0(case, *args):
case = case.strip()
if case == 's':
return 0.0
elif case == 'p':
F2 = args[0]
return 2.0 / 25.0 * F2
elif case == 'd':
F2, F4 = args[0:2]
return 2.0 / 63.0 * F2 + 2.0 / 63.0 * F4
elif case == 'f':
F2, F4, F6 = args[0:3]
return 4.0 / 195.0 * F2 + 2.0 / 143.0 * F4 + 100.0 / 5577.0 * F6
elif case == 'ss':
G0 = args[0]
return 0.5 * G0
elif case == 'sp' or case == 'ps':
G1 = args[0]
return 1.0 / 6.0 * G1
elif case == 'sd' or case == 'ds':
G2 = args[0]
return 1.0 / 10.0 * G2
elif case == 'sf' or case == 'fs':
G3 = args[0]
return 1.0 / 14.0 * G3
elif case == 'pp':
G0, G2 = args[0:2]
return 1.0 / 6.0 * G0 + 1.0 / 15.0 * G2
elif case == 'pd' or case == 'dp':
G1, G3 = args[0:2]
return 1.0 / 15.0 * G1 + 3.0 / 70.0 * G3
elif case == 'pf' or case == 'fp':
G2, G4 = args[0:2]
return 3.0 / 70.0 * G2 + 2.0 / 63.0 * G4
elif case == 'dd':
G0, G2, G4 = args[0:3]
return 1.0 / 10.0 * G0 + 1.0 / 35.0 * G2 + 1.0 / 35.0 * G4
elif case == 'df' or case == 'fd':
G1, G3, G5 = args[0:3]
return 3.0 / 70.0 * G1 + 2.0 / 105.0 * G3 + 5.0 / 231.0 * G5
elif case == 'ff':
G0, G2, G4, G6 = args[0:4]
return 1.0 / 14.0 * G0 + 2.0 / 105.0 * G2 + 1.0 / 77.0 * G4 + 50.0 / 3003.0 * G6
else:
raise Exception("error in get_F0(): Unknown case name:", case)
[docs]def get_umat_slater(case, *args):
"""
Convenient adapter function to return the Coulomb interaction tensor for common case.
Parameters
----------
case: string
Indicates atomic shells, should be one of
For single shell:
- 's': single :math:`s`-shell (:math:`l=0`)
- 'p': single :math:`p`-shell (:math:`l=1`)
- 'p12': single :math:`p_{1/2}`-shell (:math:`l=1`)
- 'p32': single :math:`p_{3/2}`-shell (:math:`l=1`)
- 't2g': single :math:`t_{2g}`-shell (:math:`l_{\\text{eff}}=1`)
- 'd': single :math:`d`-shell (:math:`l=2`)
- 'd32': single :math:`d_{3/2}`-shell (:math:`l=2`)
- 'd52': single :math:`d_{5/2}`-shell (:math:`l=2`)
- 'f': single :math:`f`-shell (:math:`l=3`)
- 'f52': single :math:`f_{5/2}`-shell (:math:`l=3`)
- 'f72': single :math:`f_{7/2}`-shell (:math:`l=3`)
For two shells:
case = str1 + str2
where, str1 and str2 are strings and they can be any of
['s', 'p', 'p12', 'p32', 't2g', 'd', 'd32', 'd52', 'f', 'f52', 'f72']
For examples,
- 'dp': 1st :math:`d`-shell and 2nd :math:`p`-shell
- 'dp12': 1st :math:`d`-shell and 2nd :math:`p_{1/2}`-shell
- 'f52p32': 1st :math:`f_{5/2}`-shell and 2nd :math:`p_{3/2}`-shell
- 't2gp': 1st :math:`t_{2g}`-shell and 2nd :math:`p`-shell
*args: floats
Variable length argument list. Slater integrals.
The order of these integrals shoule be
For only one shell case,
args = [F0, F2, F4, F6, ....]
For two shells case,
args = [FX_11, FX_12, GX_12, FX_22]
where, 1 (2) means 1st (2nd)-shell, and X=0, 2, 4, ... or X=1, 3, 5 ...,
and X should be in ascending order. The following are possible cases:
- 's':
args = [F0]
- 'p', 'p12', 'p32':
args = [F0, F2]
- 'd', 'd32', 'd52', 't2g':
args = [F0, F2, F4]
- 'f', 'f52', 'f72':
args = [F0, F2, F4, F6]
- 'ss':
args = [F0_11, F0_12, G0_12, F0_22]
- 'ps', 'p12s', 'p32s':
args = [F0_11, F2_11, F0_12, G1_12, F0_22]
- 'ds', 'd32s', 'd52s', 't2gs':
args = [F0_11, F2_11, F4_11, F0_12, G2_12, F0_22]
- 'fs', 'f52s', 'f72s':
args = [F0_11, F2_11, F4_11, F6_11, F0_12, G3_12, F0_22]
- 'sp', 'sp12', 'sp32':
args = [F0_11, F0_12, G1_12, F0_22, F2_22]
- 'pp', 'pp12', 'pp32', 'p12p', 'p12p12', 'p12p32', 'p32p', 'p32p12', 'p32p32':
args = [F0_11, F2_11, F0_12, F2_12, G0_12, G2_12, F0_22, F2_22]
- 'dp', 'dp12', 'dp32', 'd32p', 'd32p12', 'd32p32', 'd52p', 'd52p12', 'd52p32',
't2gp', 't2gp12', t2gp32':
args = [F0_11, F2_11, F4_11, F0_12, F2_12, G1_12, G3_12, F0_22, F2_22]
- 'fp', 'fp12', 'fp32', 'f52p', 'f52p12', 'f52p32', 'f72p', 'f72p12', 'f72p32':
args = [F0_11, F2_11, F4_11, F6_11, F0_12, F2_12, G2_12, G4_12, F0_22, F2_22]
- 'sd', 'sd32', 'sd52':
args = [F0_11, F0_12, G2_12, F0_22, F2_22, F4_22]
- 'pd', 'pd32', 'pd52', 'p12d', 'p12d32', 'p12d52', 'p32d', 'p32d32', 'p32d52':
args = [F0_11, F2_11, F0_12, F2_12, G1_12, G3_12, F0_22, F2_22, F4_22]
- 'dd', 'dd32', 'dd52', 'd32d', 'd32d32', 'd32d52', 'd52d', 'd52d32', 'd52d52',
't2gd', 't2gd32', 't2gd52':
args = [F0_11, F2_11, F4_11, F0_12, F2_12, F4_12, G0_12, G2_12, G4_12, F0_22, F2_22, F4_22]
- 'fd', 'fd32', 'fd52', 'f52d', 'f52d32', 'f52d52', 'f72d', 'f72d32', 'f72d52':
args = [F0_11, F2_11, F4_11, F6_11, F0_12, F2_12, F4_12, G1_12, G3_12, G5_12,
F0_22, F2_22, F4_22]
- 'sf', 'sf52', 'sf72':
args = [F0_11, F0_12, G3_12, F0_22, F2_22, F4_22, F6_22]
- 'pf', 'pf52', 'pf72', 'p12f', 'p12f52', 'p12f72', 'p32f', 'p32f52', 'p32f72':
args = [F0_11, F2_11, F0_12, F2_12, G2_12, G4_12, F0_22, F2_22, F4_22, F6_22]
- 'df', 'df52', 'df72', 'd32f', 'd32f52', 'd32f72', 'd52f', 'd52f52', 'd52f72',
't2gf', 't2gf52', 't2gf72':
args = [F0_11, F2_11, F4_11, F0_12, F2_12, F4_12, G1_12, G3_12, G5_12,
F0_22, F2_22, F4_22, F6_22]
- 'ff', 'ff52', 'ff72', 'f52f', 'f52f52', 'f52f72', 'f72f', 'f72f52', 'f72f72':
args = [F0_11, F2_11, F4_11, F6_11, F0_12, F2_12, F4_12, F6_12,
G0_12, G2_12, G4_12, G6_12, F0_22, F2_22, F4_22, F6_22]
Returns
-------
umat: 4d array of complex
the Coulomb interaction tensor
Examples
--------
>>> import edrixs
>>> F0_dd, F2_dd, F4_dd = 3.0, 1.0, 0.5
>>> F0_dp, F2_dp, G1_dp, G3_dp = 2.0, 1.0, 0.2, 0.1
>>> F0_pp, F2_pp = 0.0, 0.0
>>> slater = [F0_dd, F2_dd, F4_dd, F0_dp, F2_dp, G1_dp, G3_dp, F0_pp, F2_pp]
>>> umat_d = edrixs.get_umat_slater('d', F0_dd, F2_dd, F4_dd)
>>> umat_dp = edrixs.get_umat_slater('dp', *slater)
>>> umat_t2gp = edrixs.get_umat_slater('t2gp', *slater)
>>> umat_dp32 = edrixs.get_umat_slater('dp32', *slater)
See Also
--------
coulomb_utensor.umat_slater
coulomb_utensor.get_umat_kanamori
coulomb_utensor.get_umat_kanamori_ge
"""
info = info_atomic_shell()
shells = case_to_shell_name(case)
nslat = len(slater_integrals_name(shells))
if nslat != len(args):
raise Exception("Number of Slater integrals", len(args), " is not equal to ", nslat)
special_shell = ['t2g', 'p12', 'p32', 'd32', 'd52', 'f52', 'f72']
orb_indx = {
special_shell[0]: [2, 3, 4, 5, 8, 9],
special_shell[1]: [0, 1],
special_shell[2]: [2, 3, 4, 5],
special_shell[3]: [0, 1, 2, 3],
special_shell[4]: [4, 5, 6, 7, 8, 9],
special_shell[5]: [0, 1, 2, 3, 4, 5],
special_shell[6]: [6, 7, 8, 9, 10, 11, 12, 13]
}
# only one shell
if len(shells) == 1:
orbl = info[shells[0]][0]
l_list = [orbl]
fk = {}
it = 0
for rank in range(0, 2*orbl+1, 2):
fk[(rank, 1, 1, 1, 1)] = args[it]
it += 1
umat = umat_slater(l_list, fk)
# truncate to a sub-shell if necessary
if shells[0] in special_shell:
if shells[0] == 't2g':
tmat = tmat_c2r('d', True)
else:
tmat = tmat_c2j(orbl)
umat = transform_utensor(umat, tmat)
indx = orb_indx[shells[0]]
umat_tmp = np.zeros((len(indx), len(indx), len(indx), len(indx)), dtype=complex)
umat_tmp[:, :, :, :] = umat[indx][:, indx][:, :, indx][:, :, :, indx]
if shells[0] == 't2g':
umat_tmp[:, :, :, :] = transform_utensor(umat_tmp, tmat_r2c('t2g', True))
umat = umat_tmp
# two shells
elif len(shells) == 2:
name1, name2 = shells
l1, l2 = info[name1][0], info[name2][0]
n1, n2 = 2*(2*l1+1), 2*(2*l2+1)
ntot = n1 + n2
l_list = [l1, l2]
fk = {}
it = 0
for rank in range(0, 2 * l1 + 1, 2):
fk[(rank, 1, 1, 1, 1)] = args[it]
it += 1
for rank in range(0, min(2 * l1, 2 * l2) + 1, 2):
fk[(rank, 1, 2, 1, 2)] = args[it]
fk[(rank, 2, 1, 2, 1)] = args[it]
it += 1
for rank in range(abs(l1 - l2), l1 + l2 + 1, 2):
fk[(rank, 1, 2, 2, 1)] = args[it]
fk[(rank, 2, 1, 1, 2)] = args[it]
it += 1
for rank in range(0, 2 * l2 + 1, 2):
fk[(rank, 2, 2, 2, 2)] = args[it]
it += 1
umat = umat_slater(l_list, fk)
# truncate to a sub-shell if necessary
if (name1 in special_shell) or (name2 in special_shell):
tmat = np.eye(ntot, dtype=complex)
indx1 = list(range(0, n1))
if name1 in special_shell:
if name1 == 't2g':
tmat[0:n1, 0:n1] = tmat_c2r('d', True)
else:
tmat[0:n1, 0:n1] = tmat_c2j(l1)
indx1 = orb_indx[name1]
indx2 = [n1 + i for i in range(0, n2)]
if name2 in special_shell:
if name2 == 't2g':
tmat[n1:ntot, n1:ntot] = tmat_c2r('d', True)
else:
tmat[n1:ntot, n1:ntot] = tmat_c2j(l2)
indx2 = [n1 + i for i in orb_indx[name2]]
indx = indx1 + indx2
umat = transform_utensor(umat, tmat)
umat_tmp = np.zeros((len(indx), len(indx), len(indx), len(indx)), dtype=complex)
umat_tmp[:, :, :, :] = umat[indx][:, indx][:, :, indx][:, :, :, indx]
if name1 == 't2g' or name2 == 't2g':
tmat = np.eye(len(indx), dtype=np.complex128)
if name1 == 't2g':
tmat[0:6, 0:6] = tmat_r2c('t2g', True)
if name2 == 't2g':
tmat[-6:, -6:] = tmat_r2c('t2g', True)
umat_tmp[:, :, :, :] = transform_utensor(umat_tmp, tmat)
umat = umat_tmp
else:
raise Exception("Not implemented for this case: ", shells)
return umat
[docs]def get_umat_slater_3shells(shell_name, *args):
"""
Given three shells, build the slater type of Coulomb tensors among
the three shells.
Parameters
----------
shell_name: tuple of three strings
Shells names.
*args: floats
Slater integrals. The order should be
FX_11, FX_12, GX_12, FX_22, FX_13, GX_13, FX_23, GX_23, FX_33
where, 1, 2, 3 means 1st, 2nd, 3rd shell, and X=0, 2, 4, ... or X=1, 3, 5 ...,
and X should be in ascending order.
Returns
-------
umat: 4d complex array
Rank-4 Coulomb tensors.
"""
v1_name = shell_name[0].strip()
v2_name = shell_name[1].strip()
v3_name = shell_name[2].strip()
info_shell = info_atomic_shell()
v1_orbl = info_shell[v1_name][0]
v2_orbl = info_shell[v2_name][0]
v3_orbl = info_shell[v3_name][0]
v1_norb = info_shell[v1_name][1]
v2_norb = info_shell[v2_name][1]
v3_norb = info_shell[v3_name][1]
# total number of orbitals
ntot = v1_norb + v2_norb + v3_norb
v1v2_norb = v1_norb + v2_norb
indx = []
it = 0
it += len(range(0, 2*v1_orbl+1, 2))
indx.append(it)
it += len(range(0, min(2*v1_orbl, 2*v2_orbl)+1, 2))
it += len(range(abs(v1_orbl-v2_orbl), v1_orbl+v2_orbl+1, 2))
indx.append(it)
it += len(range(0, 2*v2_orbl+1, 2))
indx.append(it)
it += len(range(0, min(2*v1_orbl, 2*v3_orbl)+1, 2))
it += len(range(abs(v1_orbl-v3_orbl), v1_orbl+v3_orbl+1, 2))
indx.append(it)
it += len(range(0, min(2*v2_orbl, 2*v3_orbl)+1, 2))
it += len(range(abs(v2_orbl-v3_orbl), v2_orbl+v3_orbl+1, 2))
indx.append(it)
it += len(range(0, 2*v3_orbl+1, 2))
indx.append(it)
if it != len(args):
raise Exception("Number of Slater integrals", len(args), " is not equal to ", it)
umat = np.zeros((ntot, ntot, ntot, ntot), dtype=complex)
# v1-v2
case = v1_name + v2_name
arg_list = list(args[0:indx[0]]) + list(args[indx[0]:indx[1]]) + list(args[indx[1]:indx[2]])
umat_tmp = get_umat_slater(case, *arg_list)
umat[0:v1v2_norb, 0:v1v2_norb, 0:v1v2_norb, 0:v1v2_norb] = umat_tmp
# v1-v3
case = v1_name + v3_name
arg_list = [0.0] * indx[0] + list(args[indx[2]:indx[3]]) + list(args[indx[4]:indx[5]])
umat_tmp = get_umat_slater(case, *arg_list)
aa = list(range(0, v1_norb)) + list(range(v1v2_norb, ntot))
for i in range(v1_norb + v3_norb):
for j in range(v1_norb + v3_norb):
for k in range(v1_norb + v3_norb):
for m in range(v1_norb + v3_norb):
umat[aa[i], aa[j], aa[k], aa[m]] += umat_tmp[i, j, k, m]
# v2-v3
case = v2_name + v3_name
arg_list = ([0.0] * (indx[2] - indx[1]) +
list(args[indx[3]:indx[4]]) +
[0.0] * (indx[5] - indx[4]))
umat_tmp = get_umat_slater(case, *arg_list)
aa = list(range(v1_norb, ntot))
for i in range(v2_norb + v3_norb):
for j in range(v2_norb + v3_norb):
for k in range(v2_norb + v3_norb):
for m in range(v2_norb + v3_norb):
umat[aa[i], aa[j], aa[k], aa[m]] += umat_tmp[i, j, k, m]
return umat
[docs]def get_umat_kanamori(norbs, U, J):
"""
Calculate the Coulomb interaction tensor for a Kanamori-type interaction.
For the :math:`t2g`-shell case, it is parameterized by :math:`U, J`.
Parameters
----------
norbs: int
number of orbitals (including spin).
U: float
Hubbard :math:`U` for electrons residing on the same orbital with opposite spin.
J: float
Hund's coupling.
Returns
-------
umat: 4d complex array
The calculated Coulomb interaction tensor
Notes
-----
The order of spin index is: up, down, up, down, ..., up, down.
See Also
--------
coulomb_utensor.get_umat_kanamori_ge
coulomb_utensor.get_umat_slater
coulomb_utensor.umat_slater
"""
return get_umat_kanamori_ge(norbs, U, U - 2 * J, J, J, J)