Exemple #1
0
def diagonalize(ten_dq, umat):
    emat = edrixs.cb_op(edrixs.cf_cubic_d(ten_dq),
                        edrixs.tmat_c2r('d', ispin=True))
    H = (edrixs.build_opers(4, umat, basis) +
         edrixs.build_opers(2, emat, basis))
    e, v = scipy.linalg.eigh(H)
    return e - e.min()
orbital_energies = np.array([e for orbital_energy in
                             [+0.6 * ten_dq, # dz2
                              -0.4 * ten_dq, # dzx
                              -0.4 * ten_dq, # dzy
                              +0.6 * ten_dq, # dx2-y2
                              -0.4 * ten_dq] # dxy)
                             for e in [orbital_energy]*2])


CF[diagonal_indices, diagonal_indices] = orbital_energies

################################################################################
# The valence band SOC is constructed in the normal way and transformed into the
# real harmonic basis.
soc = edrixs.cb_op(edrixs.atom_hsoc('d', zeta_d_i), edrixs.tmat_c2r('d', True))

################################################################################
# The total impurity matrices for the ground and core-hole states are then
# the sum of crystal field and spin-orbit coupling. We further needed to apply
# an energy shift along the matrix diagonal, which we do using the
# :code:`np.eye` function which creates a diagonal matrix of ones.
E_d_mat = E_d*np.eye(norb_d)
E_dc_mat = E_dc*np.eye(norb_d)
imp_mat = CF + soc + E_d_mat
imp_mat_n = CF + soc + E_dc_mat

################################################################################
# The energy level of the bath(s) is described by a matrix where the row index
# denotes which bath and the column index denotes which orbital. Here we have
# only one bath, with 10 spin-orbitals. We initialize the matrix to
Exemple #3
0
def get_hopping_coulomb(locaxis):
    # Number of orbitals
    nt2g, nporb, norbs = 6, 6, 24

    # On-site Coulomb interaction tensor
    Ud, JH = edrixs.UJ_to_UdJH(2, 0.3)
    F0_d, F2_d, F4_d = edrixs.UdJH_to_F0F2F4(Ud, JH)

    G1_dp, G3_dp = 0.957, 0.569
    F0_dp, F2_dp = edrixs.get_F0('dp', G1_dp, G3_dp), 1.107

    umat_t2g_i = edrixs.get_umat_slater('t2g', F0_d, F2_d, F4_d)

    params = [
        F0_d,
        F2_d,
        F4_d,  # Fk for d
        F0_dp,
        F2_dp,  # Fk for dp
        G1_dp,
        G3_dp,  # Gk for dp
        0.0,
        0.0  # Fk for p
    ]
    umat_t2gp_n = edrixs.get_umat_slater('t2gp', *params)

    # static core-hole potential
    static_v = 2.0
    for i in range(0, nt2g):
        for j in range(nt2g, nt2g + nporb):
            umat_t2gp_n[i, j, j, i] += static_v

    umat_i = np.zeros((norbs, norbs, norbs, norbs), dtype=np.complex128)
    umat_n = np.zeros((norbs, norbs, norbs, norbs), dtype=np.complex128)

    umat_i[0:6, 0:6, 0:6, 0:6] = umat_t2g_i
    umat_i[6:12, 6:12, 6:12, 6:12] = umat_t2g_i

    indx = np.array([[0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17],
                     [6, 7, 8, 9, 10, 11, 18, 19, 20, 21, 22, 23]])
    for m in range(2):
        for i in range(12):
            for j in range(12):
                for k in range(12):
                    for l in range(12):
                        umat_n[indx[m, i], indx[m, j], indx[m, k],
                               indx[m, l]] += umat_t2gp_n[i, j, k, l]

    emat_i = np.zeros((norbs, norbs), dtype=np.complex128)
    emat_n = np.zeros((norbs, norbs), dtype=np.complex128)

    # SOC
    zeta_d_i, zeta_p_n = 0.35, 1072.6666666666667
    soc_d = edrixs.atom_hsoc('t2g', zeta_d_i)
    soc_p = edrixs.atom_hsoc('p', zeta_p_n)

    emat_i[0:6, 0:6] += soc_d
    emat_i[6:12, 6:12] += soc_d

    emat_n[0:6, 0:6] += soc_d
    emat_n[6:12, 6:12] += soc_d

    emat_n[12:18, 12:18] += soc_p
    emat_n[18:24, 18:24] += soc_p
    for i in range(2 * nt2g):
        emat_n[i, i] -= 6 * static_v

    # Crystal field and hoppings between the two Ir-sites
    t1, t2, delta = -0.18, 0.036, -0.03
    # Uncomment the following line to do calculation without hopping and crystal filed splitting.
    # t1, t2, delta = 0, 0, -0.03
    crys_tmp = np.array(
        [[0, delta, delta, t1, t2, t1], [delta, 0, delta, t2, t1, t1],
         [delta, delta, 0, t1, t1, t2], [t1, t2, t1, 0, delta, delta],
         [t2, t1, t1, delta, 0, delta], [t1, t1, t2, delta, delta, 0]],
        dtype=np.complex)

    # transform spin to local axis
    dmat = np.zeros((2, 2, 2), dtype=np.complex128)
    ang1, ang2, ang3 = edrixs.rmat_to_euler(locaxis[0])
    dmat[0] = edrixs.dmat_spinor(ang1, ang2, ang3)
    ang1, ang2, ang3 = edrixs.rmat_to_euler(locaxis[1])
    dmat[1] = edrixs.dmat_spinor(ang1, ang2, ang3)

    t_spinor = np.zeros((12, 12), dtype=np.complex128)
    for i in range(2):
        off = i * 6
        t_spinor[off + 0:off + 2, off + 0:off + 2] = dmat[i]
        t_spinor[off + 2:off + 4, off + 2:off + 4] = dmat[i]
        t_spinor[off + 4:off + 6, off + 4:off + 6] = dmat[i]

    crys_spin = np.zeros((12, 12), dtype=np.complex128)
    crys_spin[0:12:2, 0:12:2] = crys_tmp
    crys_spin[1:12:2, 1:12:2] = crys_tmp
    t_orb = np.zeros((12, 12), dtype=np.complex128)
    t_orb[0:6, 0:6] = edrixs.tmat_r2c('t2g', True)
    t_orb[6:12, 6:12] = edrixs.tmat_r2c('t2g', True)
    crys_spin[:, :] = edrixs.cb_op(crys_spin, np.dot(t_spinor, t_orb))

    emat_i[0:12, 0:12] += crys_spin
    emat_n[0:12, 0:12] += crys_spin

    # Write to files
    # ED inputs
    edrixs.write_emat(emat_i, "ed/hopping_i.in")
    edrixs.write_umat(umat_i, "ed/coulomb_i.in")

    # XAS inputs
    edrixs.write_emat(emat_n, "xas/hopping_n.in")
    edrixs.write_umat(umat_n, "xas/coulomb_n.in")

    # RIXS inputs
    edrixs.write_emat(emat_i, "rixs_pp/hopping_i.in")
    edrixs.write_umat(umat_i, "rixs_pp/coulomb_i.in")
    edrixs.write_emat(emat_n, "rixs_pp/hopping_n.in")
    edrixs.write_umat(umat_n, "rixs_pp/coulomb_n.in")

    edrixs.write_emat(emat_i, "rixs_ps/hopping_i.in")
    edrixs.write_umat(umat_i, "rixs_ps/coulomb_i.in")
    edrixs.write_emat(emat_n, "rixs_ps/hopping_n.in")
    edrixs.write_umat(umat_n, "rixs_ps/coulomb_n.in")
Exemple #4
0
# t2g orbitals, dxz, dyz, dxy, :math:`\\hat{d}^{\\dagger}_{\\alpha}\\hat{d}_{\\alpha}`
# First, write their matrice in the real harmonics basis
# |dxz,up>, |dxz,dn>, |dyz,up>, |dyz,dn>, |dxy,up>, |dxy,dn>
# In this basis, they take simple form, only the diagonal terms have element 1
nd_oper = np.zeros((norb, norb, norb), dtype=np.complex)
nd_oper[0, 0, 0] = 1
nd_oper[1, 1, 1] = 1
nd_oper[2, 2, 2] = 1
nd_oper[3, 3, 3] = 1
nd_oper[4, 4, 4] = 1
nd_oper[5, 5, 5] = 1
# Then transform to the complex harmonics basis
# |-1,up>, |-1,dn>, |0,up>, |0,dn>, |+1,up>, |+1,dn>
# comment the following line to calculate the occupancy number
# of the complex harmonics orbitals
nd_oper = edrixs.cb_op(nd_oper, edrixs.tmat_r2c('t2g', True))
# Build the many-body operators for nd
nd_manybody_oper = edrixs.build_opers(2, nd_oper, basis)

# Build many-body Hamiltonian for four-fermion terms in the Fock basis
# H has the dimension of 15*15
H_U = edrixs.build_opers(4, umat, basis)
# Build many-body Hamiltonian for two-fermion terms in the Fock basis
H_soc = edrixs.build_opers(2, emat_soc, basis)
H_zeeman = edrixs.build_opers(2, emat_zeeman, basis)

# The scipy diagonalization returns eigenvalues in ascending order, each repeated according
# to its multiplicity. eigenvectors are returned as a set of column vectors.
# eigenvalue eigenval[n] is associated with eignevector eigenvec[:, n]
# case 1: without SOC
H = H_U + H_zeeman
Exemple #5
0
# applied to the off-diagonal terms of :code:`emat`.
indx1 = np.arange(norb_d)
indx2 = np.arange(norb_d, norb_d * 2)
emat_rhb[indx1, indx2] += hyb[0]
emat_rhb[indx2, indx1] += np.conj(hyb[0])

################################################################################
# We now need to transform into the complex harmonic basis. We assign
# the two diagonal blocks of a :math:`20\times20` matrix to the
# conjugate transpose of the transition matrix.
tmat = np.eye(ntot, dtype=complex)
for i in range(2):
    off = i * norb_d
    tmat[off:off + norb_d, off:off + norb_d] = np.conj(np.transpose(trans_c2n))

emat_chb = edrixs.cb_op(emat_rhb, tmat)

################################################################################
# The spin exchange is built from the spin operators and the effective field
# is applied to the :math:`d`-shell region of the matrix.
v_orbl = 2
sx = edrixs.get_sx(v_orbl)
sy = edrixs.get_sy(v_orbl)
sz = edrixs.get_sz(v_orbl)
zeeman = ext_B[0] * (2 * sx) + ext_B[1] * (2 * sy) + ext_B[2] * (2 * sz)
emat_chb[0:norb_d, 0:norb_d] += zeeman

################################################################################
# Build the Fock basis and Hamiltonain and Diagonalize
# ------------------------------------------------------------------------------
# We create the fock basis and build the Hamiltonian using the full set of
# these operators i.e.
#
#     .. math::
#        \mathbf{S}^2 = S^2_x + S^2_y + S^2_z\\
#        \mathbf{L}^2 = L^2_x + L^2_y + L^2_z\\
#        \mathbf{J}^2 = J^2_x + J^2_y + J^2_z
#
L2 = np.dot(opL[0], opL[0]) + np.dot(opL[1], opL[1]) + np.dot(opL[2], opL[2])
S2 = np.dot(opS[0], opS[0]) + np.dot(opS[1], opS[1]) + np.dot(opS[2], opS[2])
J2 = np.dot(opJ[0], opJ[0]) + np.dot(opJ[1], opJ[1]) + np.dot(opJ[2], opJ[2])

################################################################################
# Remember that the eigenvalues of :math:`\mathbf{S}^2` are in the form
# :math:`S(S+1)` etc. and that they can be obtained by calculating the
# projection of the operators onto our eigenvectors.
L2_val = edrixs.cb_op(L2, v).diagonal().real
S2_val = edrixs.cb_op(S2, v).diagonal().real
J2_val = edrixs.cb_op(J2, v).diagonal().real
################################################################################
# We can determine the degeneracy of the eigenvalues numerically and print out
# the values as follows
e = np.round(e, decimals=6)
degeneracy = [sum(eval == e) for eval in e]
header = "{:<3s}\t{:>8s}\t{:>8s}\t{:>8s}\t{:>8s}"
print(header.format("#  ", "E  ", "S(S+1)", "L(L+1)", "Degen."))
for i, eigenvalue in enumerate(e):
    values_list = [i, eigenvalue, S2_val[i], L2_val[i], degeneracy[i]]
    print("{:<3d}\t{:8.3f}\t{:8.3f}\t{:8.3f}\t{:>3d}".format(*values_list))

################################################################################
# We see :math:`S=0` and :math:`S=1` states coming from the
Exemple #7
0
def ed():
    # 1-10: Ni-3d valence orbitals, 11-16: Ni-2p core orbitals
    # Single particle basis: complex shperical Harmonics
    ndorb, nporb, ntot = 10, 6, 16
    emat_i = np.zeros((ntot, ntot), dtype=np.complex)
    emat_n = np.zeros((ntot, ntot), dtype=np.complex)

    # 4-index Coulomb interaction tensor, parameterized by
    # Slater integrals, which are obtained from Cowan's code
    F2_d, F4_d = 7.9521, 4.9387
    # Averaged dd Coulomb interaction is set to be zero
    F0_d = edrixs.get_F0('d', F2_d, F4_d)
    G1_dp, G3_dp = 4.0509, 2.3037
    # Averaged dp Coulomb interaction is set to be zero
    F0_dp, F2_dp = edrixs.get_F0('dp', G1_dp, G3_dp), 7.33495
    umat_i = edrixs.get_umat_slater(
        'dp',
        F0_d,
        F2_d,
        F4_d,  # dd
        0,
        0,
        0,
        0,  # dp
        0,
        0)  # pp
    umat_n = edrixs.get_umat_slater(
        'dp',
        F0_d,
        F2_d,
        F4_d,  # dd
        F0_dp,
        F2_dp,
        G1_dp,
        G3_dp,  # dp
        0,
        0)  # pp

    # Atomic spin-orbit coupling
    zeta_d, zeta_p = 0.083, 11.24
    emat_i[0:ndorb, 0:ndorb] += edrixs.atom_hsoc('d', zeta_d)
    emat_n[0:ndorb, 0:ndorb] += edrixs.atom_hsoc('d', zeta_d)
    emat_n[ndorb:ntot, ndorb:ntot] += edrixs.atom_hsoc('p', zeta_p)

    # Tetragonal crystal field splitting terms,
    # which are first defined in the real cubic Harmonics basis,
    # and then transformed to complex shperical Harmonics basis.
    dt, ds, dq = 0.011428, 0.035714, 0.13
    tmp = np.zeros((5, 5), dtype=np.complex)
    tmp[0, 0] = 6 * dq - 2 * ds - 6 * dt  # d3z2-r2
    tmp[1, 1] = -4 * dq - 1 * ds + 4 * dt  # dzx
    tmp[2, 2] = -4 * dq - 1 * ds + 4 * dt  # dzy
    tmp[3, 3] = 6 * dq + 2 * ds - 1 * dt  # dx2-y2
    tmp[4, 4] = -4 * dq + 2 * ds - 1 * dt  # dxy
    tmp[:, :] = edrixs.cb_op(tmp, edrixs.tmat_r2c('d'))
    emat_i[0:ndorb:2, 0:ndorb:2] += tmp
    emat_i[1:ndorb:2, 1:ndorb:2] += tmp
    emat_n[0:ndorb:2, 0:ndorb:2] += tmp
    emat_n[1:ndorb:2, 1:ndorb:2] += tmp

    # Build Fock basis in its binary form
    basis_i = edrixs.get_fock_bin_by_N(ndorb, 8, nporb, nporb)
    basis_n = edrixs.get_fock_bin_by_N(ndorb, 9, nporb, nporb - 1)
    ncfg_i, ncfg_n = len(basis_i), len(basis_n)

    # Build many-body Hamiltonian in Fock basis
    hmat_i = np.zeros((ncfg_i, ncfg_i), dtype=np.complex)
    hmat_n = np.zeros((ncfg_n, ncfg_n), dtype=np.complex)
    hmat_i[:, :] += edrixs.two_fermion(emat_i, basis_i, basis_i)
    hmat_i[:, :] += edrixs.four_fermion(umat_i, basis_i)
    hmat_n[:, :] += edrixs.two_fermion(emat_n, basis_n, basis_n)
    hmat_n[:, :] += edrixs.four_fermion(umat_n, basis_n)

    # Do exact-diagonalization to get eigenvalues and eigenvectors
    eval_i, evec_i = np.linalg.eigh(hmat_i)
    eval_n, evec_n = np.linalg.eigh(hmat_n)

    # Build dipolar transition operators
    dipole = np.zeros((3, ntot, ntot), dtype=np.complex)
    T_abs = np.zeros((3, ncfg_n, ncfg_i), dtype=np.complex)
    T_emi = np.zeros((3, ncfg_i, ncfg_n), dtype=np.complex)
    tmp = edrixs.get_trans_oper('dp')
    for i in range(3):
        dipole[i, 0:ndorb, ndorb:ntot] = tmp[i]
        # First, in the Fock basis
        T_abs[i] = edrixs.two_fermion(dipole[i], basis_n, basis_i)
        # Then, transfrom to the eigenvector basis
        T_abs[i] = edrixs.cb_op2(T_abs[i], evec_n, evec_i)
        T_emi[i] = np.conj(np.transpose(T_abs[i]))

    return eval_i, eval_n, T_abs, T_emi
Exemple #8
0
print(v[:, 6:].real)

################################################################################
# These are the set of so-called :math:`e_{g}` orbitals, composed of
# :math:`Y^2_2, Y^{-2}_2, Y^{0}_2`. We can use edrixs to prove that
# :code:`cfmat` would be diagonal in the real
# harmonic basis. An operator :math:`\hat{O}` can be transformed into an
# operator in another basis :math:`\hat{O}^{\prime}` using a unitary
# transformation matrix :math:`T` as
#
#    .. math::
#
#          \hat{O}^{\prime} = (T)^{\dagger} \hat{O} (T).
#
# This is computed as follows
cfmat_rhb = edrixs.cb_op(cfmat, edrixs.tmat_c2r('d', ispin=True))
print(cfmat_rhb.real)

################################################################################
# where :code:`edrixs.tmat_c2r('d', ispin=True)` is the transformation matrix.
# We needed to tell edrixs that we are working with a :math:`d`-shell and that it
# should include spin. We could also have transformed :code:`v` to see how these
# eignevectors are  composed of the real harmonic basis. We will see an example
# of this later.

################################################################################
# Crystal field on an atom
# ------------------------------------------------------------------------------
# To simulate the solid state, we need to combine the crystal field with Coulomb
# interactions. Let us choose an atomic model for Ni.
l = 2
Exemple #9
0
    indx = np.array([[0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17],
                     [6, 7, 8, 9, 10, 11, 18, 19, 20, 21, 22, 23]])

    for m in range(2):
        for i in range(12):
            for j in range(12):
                for k in range(12):
                    for l in range(12):
                        umat_n[m, indx[m, i], indx[m, j], indx[m, k],
                               indx[m, l]] += umat_t2gp_n[i, j, k, l]

    emat_i = np.zeros((norbs, norbs), dtype=np.complex128)
    emat_n = np.zeros((2, norbs, norbs), dtype=np.complex128)

    soc_d = edrixs.cb_op(edrixs.atom_hsoc('t2g', zeta_d_i),
                         edrixs.tmat_c2r('t2g', True))
    soc_p = edrixs.cb_op(edrixs.atom_hsoc('p', zeta_p_n),
                         edrixs.tmat_c2r('p', True))

    emat_i[0:6, 0:6] += soc_d
    emat_i[6:12, 6:12] += soc_d
    emat_n[0, 0:6, 0:6] += soc_d
    emat_n[0, 6:12, 6:12] += soc_d
    emat_n[0, 12:18, 12:18] += soc_p
    emat_n[1, 0:6, 0:6] += soc_d
    emat_n[1, 6:12, 6:12] += soc_d
    emat_n[1, 18:24, 18:24] += soc_p

    # crystal field and hopping between the two Ir atom
    a, b, c = -0.18, 0.036, -0.03
    # a, b, c = -0.0, 0.00, -0.00
Exemple #10
0
spin_mom = np.zeros((3, norb, norb), dtype=np.complex128)
spin_mom[:, :2, :2] = spin_mom[:, 2:, 2:] = spin_mom_one_site

opS = edrixs.build_opers(2, spin_mom, basis)
opS_squared = (np.dot(opS[0], opS[0]) + np.dot(opS[1], opS[1])
               + np.dot(opS[2], opS[2]))

################################################################################
# This time let us include a tiny magnetic field along the :math:`z`-axis, so
# that we have a well-defined measurement axis and print out the expectation 
# values.
zeeman = np.zeros((norb, norb), dtype=np.complex128)
zeeman[:2, :2] = zeeman[2:, 2:] = 1e-8*spin_mom_one_site[2]
e, v = diagonalize(1000, 1, extra_emat=zeeman)

Ssq_exp = edrixs.cb_op(opS_squared, v).diagonal().real
Sz_exp = edrixs.cb_op(opS[2], v).diagonal().real

header = "{:<10s}\t{:<6s}\t{:<6s}"
print(header.format("E", "S(S+1)", "<Sz>"))
for i in range(len(e)):
    print("{:<2f}\t{:.1f}\t{:.1f}".format(e[i], Ssq_exp[i], Sz_exp[i]))
    
################################################################################
# For :math:`U \gg t` the two states with double occupancy acquire an energy of 
# approximately :math:`U`. The low energy states are a :math:`S=0` singlet and
# and :math:`S=1` triplet, which are split by :math:`4t^2/U`, which is the
# magnetic exchange term. 

################################################################################
# :math:`U` dependence
def get_hopping_coulomb(locaxis):
    # Number of orbitals for each site
    ndorb, nporb = 6, 4
    # Number of sites
    nsite = 2
    # Total number of orbitals
    ntot = nsite * (ndorb + nporb)
    # orbital orders:
    # 0-5:    1st-site-t2g
    # 6-11:   2nd-site-t2g
    # 12-15:  1st-site-2p
    # 16-19:  2nd-site-2p

    # On-site Coulomb interaction tensor
    U, J = 2.0, 0.3
    Ud, JH = edrixs.UJ_to_UdJH(U, J)
    F0_dd, F2_dd, F4_dd = edrixs.UdJH_to_F0F2F4(Ud, JH)  # k=0, 2, 2*l

    G1_dp, G3_dp = 0.957, 0.569  # k=|2-1|, |2+1|
    F0_dp, F2_dp = edrixs.get_F0('dp', G1_dp,
                                 G3_dp), 1.107  # k=0, min(2*2, 2*1)

    # just one site t2g-subspace
    umat_tmp_i = edrixs.get_umat_slater('t2g', F0_dd, F2_dd, F4_dd)

    params = [
        F0_dd,
        F2_dd,
        F4_dd,  # FX for dd
        F0_dp,
        F2_dp,  # FX for dp
        G1_dp,
        G3_dp,  # GX for dp
        0,
        0  # FX for pp
    ]
    # just one site
    umat_tmp_n = edrixs.get_umat_slater('t2gp32', *params)  # 2p_3/2 -> t2g

    # static core-hole potential
    static_v = 2.0
    for i in range(0, ndorb):
        for j in range(ndorb, ndorb + nporb):
            umat_tmp_n[i, j, j, i] += static_v

    # two sites as a whole
    umat_i = np.zeros((ntot, ntot, ntot, ntot), dtype=np.complex)
    umat_n = np.zeros((ntot, ntot, ntot, ntot), dtype=np.complex)

    umat_i[0:ndorb, 0:ndorb, 0:ndorb,
           0:ndorb] = umat_tmp_i  # 1st site 5d-valence
    umat_i[ndorb:2 * ndorb, ndorb:2 * ndorb, ndorb:2 * ndorb,
           ndorb:2 * ndorb] = umat_tmp_i  # 2nd site 5d-valence

    indx = np.array([
        [
            0,
            1,
            2,
            3,
            4,
            5,  # orbital indices for 1st site 5d-t2g
            12,
            13,
            14,
            15
        ],  # orbital indices for 1st site 2p-core
        [
            6,
            7,
            8,
            9,
            10,
            11,  # orbital indices for 2nd site 5d-t2g
            16,
            17,
            18,
            19
        ]  # orbital indices for 2nd site 2p-core
    ])
    # copy umat_tmp_n (one site) to umat_n (two sites)
    ndp = ndorb + nporb
    for m in range(nsite):
        for i in range(ndp):
            for j in range(ndp):
                for k in range(ndp):
                    for l in range(ndp):
                        umat_n[indx[m, i], indx[m, j], indx[m, k],
                               indx[m, l]] += umat_tmp_n[i, j, k, l]

    # two fermion terms, SOC, crystal field, and hopping between the two sites
    emat_i = np.zeros((ntot, ntot), dtype=np.complex)
    emat_n = np.zeros((ntot, ntot), dtype=np.complex)

    # SOC
    zeta_d_i = 0.35
    soc_d = edrixs.atom_hsoc('t2g', zeta_d_i)

    emat_i[0:ndorb, 0:ndorb] += soc_d
    emat_i[ndorb:2 * ndorb, ndorb:2 * ndorb] += soc_d

    emat_n[0:ndorb, 0:ndorb] += soc_d
    emat_n[ndorb:2 * ndorb, ndorb:2 * ndorb] += soc_d

    # Terms from static core-hole potential
    for i in range(2 * ndorb):
        emat_n[i, i] -= nporb * static_v

    # Crystal field and hoppings between the two Ir-sites
    d = -0.03  # trgional splitting in t2g-subspace

    # Uncomment the following line to do calculation without hopping and crystal filed splitting.
    t1, t2 = -0.18, 0.036  # hopping between the two-sites in t2g-subspace

    cf_tmp = np.array([  # dzx_1, dzy_1,  dxy_1,    dzx_2, dzy_2,  dxy_2
        [0, d, d, t1, t2, t1],  # dzx_1
        [d, 0, d, t2, t1, t1],  # dzy_1
        [d, d, 0, t1, t1, t2],  # dxy_1
        [t1, t2, t1, 0, d, d],  # dzx_2
        [t2, t1, t1, d, 0, d],  # dzy_2
        [t1, t1, t2, d, d, 0],  # dxy_2
    ])
    # Including spin degree of freedom, in global axis
    cf_spin = np.zeros((2 * ndorb, 2 * ndorb), dtype=np.complex)
    cf_spin[0:2 * ndorb:2, 0:2 * ndorb:2] = cf_tmp
    cf_spin[1:2 * ndorb:2, 1:2 * ndorb:2] = cf_tmp

    # Transform spin basis to local axis
    # 1/2-spinor matrix
    t_spinor = np.zeros((2 * ndorb, 2 * ndorb), dtype=np.complex128)
    for i in range(nsite):
        alpha, beta, gamma = edrixs.rmat_to_euler(locaxis[i])
        dmat = edrixs.dmat_spinor(alpha, beta, gamma)
        for j in range(ndorb // 2):
            off = i * ndorb + j * 2
            t_spinor[off:off + 2, off:off + 2] = dmat

    # Transform orbital basis from real cubic to complex harmonics
    t_orb = np.zeros((2 * ndorb, 2 * ndorb), dtype=np.complex128)
    t_orb[0:ndorb, 0:ndorb] = edrixs.tmat_r2c('t2g', True)
    t_orb[ndorb:2 * ndorb, ndorb:2 * ndorb] = edrixs.tmat_r2c('t2g', True)
    # Do the tranformation
    cf_spin[:, :] = edrixs.cb_op(cf_spin, np.dot(t_spinor, t_orb))

    emat_i[0:2 * ndorb, 0:2 * ndorb] += cf_spin
    emat_n[0:2 * ndorb, 0:2 * ndorb] += cf_spin

    # Write emat and umat to files
    # ED inputs
    edrixs.write_emat(emat_i, "ed/hopping_i.in")
    edrixs.write_umat(umat_i, "ed/coulomb_i.in")

    # XAS inputs
    edrixs.write_emat(emat_n, "xas/hopping_n.in")
    edrixs.write_umat(umat_n, "xas/coulomb_n.in")

    # RIXS inputs
    edrixs.write_emat(emat_i, "rixs_pp/hopping_i.in")
    edrixs.write_umat(umat_i, "rixs_pp/coulomb_i.in")
    edrixs.write_emat(emat_n, "rixs_pp/hopping_n.in")
    edrixs.write_umat(umat_n, "rixs_pp/coulomb_n.in")

    edrixs.write_emat(emat_i, "rixs_ps/hopping_i.in")
    edrixs.write_umat(umat_i, "rixs_ps/coulomb_i.in")
    edrixs.write_emat(emat_n, "rixs_ps/hopping_n.in")
    edrixs.write_umat(umat_n, "rixs_ps/coulomb_n.in")