コード例 #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()
コード例 #2
0
def diagonlize(scaleU=1):
    umat = edrixs.get_umat_slater('d',
                                  slater[0][1]*scaleU,
                                  slater[1][1]*scaleU,
                                  slater[2][1]*scaleU)
    cfmat = edrixs.angular_momentum.cf_tetragonal_d(ten_dq=ten_dq, d1=d1, d3=d3)
    H = edrixs.build_opers(2, cfmat, basis) + edrixs.build_opers(4, umat, basis)
    e, v = scipy.linalg.eigh(H)
    e = e - np.min(e)  # define ground state as zero energy
    return e, v
コード例 #3
0
def diagonalize(U, t, extra_emat=None):
    """Diagonalize 2 site Hubbard Hamiltonian"""
    umat = np.zeros((norb, norb, norb, norb), dtype=np.complex128)
    emat = np.zeros((norb, norb), dtype=np.complex128)
    U_mat_1site = edrixs.get_umat_slater('s', U)
    umat[:2, :2, :2, :2,] = umat[2:, 2:, 2:, 2:] = U_mat_1site
    emat[2, 0] = emat[3, 1] = emat[0, 2] = emat[1, 3] = t
    
    if extra_emat is not None:
        emat = emat + extra_emat

    H = (edrixs.build_opers(2, emat, basis)
         + edrixs.build_opers(4, umat, basis))
 
    e, v = scipy.linalg.eigh(H)
    return e, v
コード例 #4
0
ファイル: run_ed.py プロジェクト: shenmidelin/edrixs
# quantum number of orbital angular momentum for t2g: l=1
ll = 1
# Matrices of lx,ly,lz,sx,sy,sz,jx,jy,jz in the single-particle basis
# lx: l_orb[0], ly: l_orb[1], lz: l_orb[2]
l_orb = edrixs.get_orb_momentum(ll, True)
# sx: s_spin[0], sy: s_spin[1], sz: s_spin[2]
s_spin = edrixs.get_spin_momentum(ll)
# jx: j_so[0], jy: j_so[1], jz: j_so[2]
j_so = l_orb + s_spin

# very small Zeeman splitting along z-direction
emat_zeeman = (l_orb[2] + s_spin[2]) * 1e-10

# many-body operators of L^2, Lz
Lxyz = edrixs.build_opers(2, l_orb, basis)
L2 = np.dot(Lxyz[0], Lxyz[0]) + np.dot(Lxyz[1], Lxyz[1]) + np.dot(
    Lxyz[2], Lxyz[2])
Lz = Lxyz[2]
# many-body operators of S^2, Sz
Sxyz = edrixs.build_opers(2, s_spin, basis)
S2 = np.dot(Sxyz[0], Sxyz[0]) + np.dot(Sxyz[1], Sxyz[1]) + np.dot(
    Sxyz[2], Sxyz[2])
Sz = Sxyz[2]
# many-body operators of J^2, Jz
Jxyz = edrixs.build_opers(2, j_so, basis)
J2 = np.dot(Jxyz[0], Jxyz[0]) + np.dot(Jxyz[1], Jxyz[1]) + np.dot(
    Jxyz[2], Jxyz[2])
Jz = Jxyz[2]

# We can also calculate the expectation values of the occupancy number of
コード例 #5
0
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
# :math:`20` spin orbitals,  specifying that they are occuplied by :math:`18`
# electrons. See the :ref:`sphx_glr_auto_examples_example_0_ed_calculator.py`
# example for more details if needed. We also set the ground state to zero
# energy.
basis = np.array(edrixs.get_fock_bin_by_N(ntot, v_noccu))
H = (edrixs.build_opers(2, emat_chb, basis) +
     edrixs.build_opers(4, umat, basis))

e, v = scipy.linalg.eigh(H)
e -= e[0]

################################################################################
# State analysis
# ------------------------------------------------------------------------------
# Now we have all the eigenvectors in the Fock basis, we need to pick out the
# states that have 8, 9 and 10 :math:`d`-electrons, respectively.
# The modulus squared of these coeffcients need to be added up to get
# :math:`\alpha`, :math:`\beta`, and :math:`\gamma`.

num_d_electrons = basis[:, :norb_d].sum(1)
コード例 #6
0
# electrons, the edrixs convention is to list the valence electrons first.

################################################################################
# Transform interactions into Fock basis
# ------------------------------------------------------------------------------
# edrixs works by creating a Hamiltonian matrix :math:`\hat{H}` transformed into
# this Fock basis. These are four fermion interactions with this form
#
#     .. math::
#        \hat{H} = <F_l|\sum_{ij}U_{ijkl}\hat{f}_{i}^{\dagger}
#                  \hat{f}_{j}^{\dagger}
#                  \hat{f}_{k}\hat{f}_{l}|F_r>
#
# generated as
n_fermion = 4
H = edrixs.build_opers(n_fermion, umat, basis)

################################################################################
# We needed to specify :code:`n_fermion = 4` because the
# :code:`edrixs.build_opers` function can also make two fermion terms.

################################################################################
# Diagonalize the matrix
# ------------------------------------------------------------------------------
# For a small problem such as this it is convenient to use the native
# `scipy <https://scipy.org>`_ diagonalization routine. This returns eigenvalues
# :code:`e` and eignvectors :code:`v` where eigenvalue :code:`e[i]` corresponds
# to eigenvector :code:`v[:,i]`.
e, v = scipy.linalg.eigh(H)
print("{} eignvalues and {} eigvenvectors {} elements long.".format(
    len(e), v.shape[1], v.shape[0]))
コード例 #7
0
# :math:`|zx,\uparrow>`, :math:`|zx,\downarrow>`, etc.
# In this basis, they take a simple form: only the diagonal terms have element
# 1. We therefore make a 3D empty array and assign the diagonal as 1. Check
# out the
# `numpy indexing notes <https://numpy.org/doc/stable/reference/arrays.indexing.html>`_
# if needed.
nd_real_harmoic_basis = np.zeros((norb, norb, norb), dtype=np.complex)
indx = np.arange(norb)
nd_real_harmoic_basis[indx, indx, indx] = 1

################################################################################
# Recalling the necessity to put everything in the same basis, we transform
# into the complex harmonic basis and then transform into our Fock basis
nd_complex_harmoic_basis = edrixs.cb_op(nd_real_harmoic_basis,
                                        edrixs.tmat_r2c('d', True))
nd_op = edrixs.build_opers(2, nd_complex_harmoic_basis, basis)

################################################################################
# We apply the operator and print out as follows. Check the
# `numpy docs <https://numpy.org/doc/1.18/reference/generated/numpy.reshape.html>`_
# if the details of how the spin pairs have been added up is not immediately
# transparent.
nd_expt = np.array(
    [edrixs.cb_op(nd_vec, v).diagonal().real for nd_vec in nd_op])

message = "{:>3s}" + "\t{:>6s}" * 5
print(message.format(*"E 3z2-r2 zx zy x2-y2 xy".split(" ")))

message = "{:>3.1f}" + "\t{:>6.1f}" * 5
for evalue, row in zip(e, nd_expt.T):
    spin_pairs = row.reshape(-1, 2).sum(1)
コード例 #8
0
# The large :math:`U` limit
# ------------------------------------------------------------------------------
# Let us see what happens with :math:`U \gg t`.
e, v = diagonalize(1000, 1)
print("Energies are")
print(e)

################################################################################
# To analyze what is going on we can determine the spin expectation values
# of the cluster. Building the operators follows the same form as the 
# Hamiltonian and the previous example.
spin_mom_one_site = edrixs.get_spin_momentum(ll)
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}"
コード例 #9
0
    # prepare files for ed.x
    # write control parameters to file
    edrixs.write_config(ed_solver=2,
                        num_val_orbs=norbs,
                        neval=100,
                        ncv=200,
                        nvector=1,
                        idump=True)
    # write nonzeros terms of two-fermion terms hsoc_i to file 'hopping_i.in', read by ed.x
    edrixs.write_emat(hsoc_i, 'hopping_i.in', 1E-10)
    # write nonzeros terms of four-fermion terms umat to file 'coulomb_i.in', read by ed.x
    edrixs.write_umat(umat_i, 'coulomb_i.in', 1E-10)
    # write fock basis of decimal format to file 'fock_i.in', read by ed.x
    edrixs.write_fock_dec_by_N(norbs, noccu, "fock_i.in")

    # we also use pure Python ED solver to get the eigenvalues
    print("edrixs >>> building Fock basis ...")
    basis_i = edrixs.get_fock_bin_by_N(norbs, noccu)
    print("edrixs >>> Done!")

    print("edrixs >>> building Hamiltonian ...")
    H = edrixs.build_opers(2, hsoc_i, basis_i)
    H += edrixs.build_opers(4, umat_i, basis_i)
    print("edrixs >>> Done!")

    print("edrixs >>> diagonalize Hamiltonian ...")
    eval_i, evec_i = scipy.linalg.eigh(H)
    edrixs.write_tensor(eval_i, "eval_i.dat", fmt_float='{:20.10f}')
    print("edrixs >>> Done!")
コード例 #10
0
# set print options
np.set_printoptions(precision=6, linewidth=200, suppress=True)

# number of orbitals
norb = 6
# number of occupancy
noccu = 2
# Slater integrals
F0, F2 = 4.0, 1.0
# Coulomb interaction tensor
umat = edrixs.get_umat_slater('p', F0, F2)
# build Fock basis
basis = edrixs.get_fock_bin_by_N(norb, noccu)
# build Hamiltonian, four fermion terms
H = edrixs.build_opers(4, umat, basis)
# do ED
e1, v1 = scipy.linalg.eigh(H)
# add spin-orbit coupling (SOC)
soc = edrixs.atom_hsoc('p', 0.2)
# build Hamiltonian, two_fermion terms
H2 = H + edrixs.build_opers(2, soc, basis)
# do ED
e2, v2 = scipy.linalg.eigh(H2)

orb_mom = edrixs.get_orb_momentum(1, True)
spin_mom = edrixs.get_spin_momentum(1)
tot_mom = orb_mom + spin_mom
opL, opS, opJ = edrixs.build_opers(2, [orb_mom, spin_mom, tot_mom], basis)
# L^2 = Lx^2 + Ly^2 +Lz^2, S^2 = Sx^2 + Sy^2 + Sz^2, J^2 = Jx^2 + Jy^2 + Jz^2
L2 = np.dot(opL[0], opL[0]) + np.dot(opL[1], opL[1]) + np.dot(opL[2], opL[2])