PES
asked by Riccardo Piombo (2020/04/30 12:10)
Hi there, it seems I've got a problem in PES spectrum computation: I obtain the correct spectrum of a d10 system if I set all the Coulomb interaction equal to zero. It should be the same also in the interacting case because I'm adding a single hole to the system, but it doesn't happen. Anyone can give me any advice?
Here is the part of the script where I compute the PES Spectrum. If necessary, I can also send you the part of the code in which the Hamiltonian is defined.
A small clarification: the system is a molecule formed by a transition metal and a Ligand atom. I'm considering only the sub-shell 4d of the TM while I'm considering a sub-shell with the same symmetry as the 4d in the Ligand: the latter is formed by the bonding linear combinations of p spin-orbitals.
-- number of fermionic spin-orbitals NF=20 -- number of bosonic modes NB=0 -- 4d spin-orbitals in spherical harmonics basis IndexDn_4d={ 0, 2, 4, 6, 8} IndexUp_4d={ 1, 3, 5, 7, 9} -- Ligand-P spin-orbitals in spherical harmonics basis IndexDn_Ld={10, 12, 14, 16, 18} IndexUp_Ld={11, 13, 15, 17, 19} --######################################### PES Spectrum ######################################### ----------- Hamiltonian diagonalization ----------- Npsi_i = 1 psiList_N = Eigensystem(H_tot, StartRestrictions1, Npsi_i) psiList_N = {psiList_N} oppList={H_tot, OppHopLd4d, OppCF_4d, OppCF_Ld, OppUdd, OppULpLp, OppN_4d, OppN_Ld} print("Done") print("") print("---------- Energies in eV ----------") print("") print(" # <E> <Ehyb> <CF4d> <CFLd> <Udd> <Upp> <N_4d> <N_Ld>"); for i = 1,#psiList_N do io.write(string.format("%3i ",i)) for j = 1,#oppList do expectationvalue = Chop(psiList_N[i]*oppList[j]*psiList_N[i]) io.write(string.format("%9.5f ",expectationvalue)) end io.write("\n") end if ToDo['Scalar Product'] then print("") print("---------- Scalar product <ψ[i]|ψ[j]> ----------") print("") for i = 1,#psiList_N do for j = 1,#psiList_N do io.write(string.format("%3i %3i ",i,j)) scalar_product = Chop(psiList_N[i]*psiList_N[j]) io.write(string.format("%8.3f ",scalar_product)) end io.write("\n") end end ----------- chemical potential ----------- -- Fermi energy is not defined in the experimental data so we have to fix -- it and then freely translate the experimental spectrum along w axis -- Three possible choices: μ+ , μ- , mean μ -- μ- : chemical potential to remove a particle print("") print("(N-1)-body states energies computation") StartRestrictions_rem = {NF, NB, {"1111111111 1111111111",nL + (n4d-1),nL + (n4d-1)}} psiList_Nminus1 = Eigensystem(H_tot, StartRestrictions_rem, 1) psiList_Nminus1 = {psiList_Nminus1} E_gs_N = psiList_N[1]*(H_tot)*psiList_N[1] E_gs_Nminus1 = psiList_Nminus1[1]*(H_tot)*psiList_Nminus1[1] remove_mu = E_gs_N - E_gs_Nminus1 print("E_gs_N = ", E_gs_N) print("E_GS_N-1 = ", E_gs_Nminus1) print("mu- = ", remove_mu) print("Done") print("") -- μ+ : chemical potential to add a particle print("(N+1)-body states energies computation") StartRestrictions_add = {NF, NB, {"1111111111 1111111111",nL + (n4d+1), nL + (n4d+1)}} psiList_Nplus1 = Eigensystem(H_tot, StartRestrictions_add, 1) psiList_Nplus1 = {psiList_Nplus1} -- check for n4d = 10 -- print(psiList_Nplus1) == is nhil -- E_Gs(N+1) = 0 E_gs_Nplus1 = psiList_Nplus1[1]*(H_tot)*psiList_Nplus1[1] add_mu = E_gs_Nplus1 - E_gs_N print("E_gs_N = ", E_gs_N) print("E_GS_N+1 = ", E_gs_Nplus1) print("mu+ = ", add_mu) print("Done") print("") -- mean μ mean_mu = (add_mu + remove_mu)/2.0 print("mean mu = [(mu+) + (mu-)]/2 = ", mean_mu) print("") ----------- change-basis matrix ----------- Orbitals = {"4d","Ligand-P_d"} YtoK = YtoKMatrix(Orbitals) KtoY = ConjugateTranspose(YtoK) print("YtoK = ") print(YtoK) print("") print("KtoY =") print(KtoY) ----------- PES Spectrum Computation ----------- -- Rotate returns M' = R* M R^T -- the hermitian conjugate to KtoY is YtoK -- we use rotate to obtain Kubic harmonics -- We create a list of operators related to the removal and adding spectrum -- Then the spectral function of each operator in this list is computed -- the output file contains as many columns as many operators are specified in the list. -- The columns can be later combined using a python program to obtain the operators in -- the requested representation -- from T_SW[1] to T_SW[20] there are the operators related to the removal spectrum T_SW = {} for k,v in pairs(IndexUp_4d) do T_SW[#T_SW + 1] = Rotate(NewOperator("An", NF, v-1), KtoY) ---> v-1 provides for the down components -- here #T_SW increases by one T_SW[#T_SW + 1] = Rotate(NewOperator("An", NF, v), KtoY) ---> v provides for the up components end print(T_SW) for k,v in pairs(IndexUp_Ld) do T_SW[#T_SW + 1] = Rotate(NewOperator("An", NF, v-1), KtoY) T_SW[#T_SW + 1] = Rotate(NewOperator("An", NF, v), KtoY) end -- from T_SW[21] to T_SW[40] there are the operators related to the adding spectrum for k,v in pairs(IndexUp_4d) do T_SW[#T_SW + 1] = Rotate(NewOperator("Cr", NF, v-1), KtoY) T_SW[#T_SW + 1] = Rotate(NewOperator("Cr", NF, v), KtoY) end for k,v in pairs(IndexUp_Ld) do T_SW[#T_SW + 1] = Rotate(NewOperator("Cr", NF, v-1), KtoY) T_SW[#T_SW + 1] = Rotate(NewOperator("Cr", NF, v), KtoY) end print("Gamma = ", Gamma) print("Npoint = ", Npoint) print("Gamma unb = ", Gamma_unb) print("Npoint unb = ", Npoint_unb) -- CreateSpectra returns G(ω) = <ψ|O*_2 (ω + E0 + iΓ/2 - O_1)^-1 O_2|ψ> -- where E0 = <ψ|O_1|ψ>. Here O_2 = Σ_m d_m and O_1 = Htot. -- Total spectral wieght G_SW = CreateSpectra(H_tot, T_SW , psiList_N[1], {{"Emin",E_min}, {"Emax",E_max}, {"NE",Npoint}, {"Gamma",Gamma}} ) --G_SW.Shift(remove_mu) G_SW = -(1/math.pi)*G_SW peaks_SW = CreateSpectra(H_tot, T_SW, psiList_N[1], {{"Emin", E_min}, {"Emax",E_max}, {"NE",Npoint_unb}, {'Gamma',Gamma_unb}} ) --peaks_SW.Shift(remove_mu) peaks_SW = -(1/math.pi)*peaks_SW G_SW.Print({{"file","PES_Spectra.dat"}}) peaks_SW.Print({{"file", "Peaks.dat"}})
Answers
Dear Ricardo,
I have not had the time to look in detail to your files, but if I understood your problem correctly your input file works for the case where you set F0=0, but not for the case where F0 is finite.
Correlations will shift the range of the spectrum. The models we normally use (ligand field theory with the parameterisation in terms of U and Delta do not set the chemical potential to the right value. This is not a problem as we restrict our Hilbert space to a given filling. It does mean that a PES spectrum can end up going from -100 to -80 eV with the Fermi energy / Chemical potential at -100. (Any other arbitrary range of numbers between -1000 and 1000 eV is allowed)
As a first try, what happens if you set the spectrum range from -200 to 200 and the broadening to 10 eV?
PS you can calculate the chemical potential form you model
Dear Maurits, If there is the possibility to upload some images I will show you the differences, but I do not know how to do it. In particular, the shape of the PES Spectrum changes between the two cases (interacting and non-interacting).
When the interaction is turned on the whole PES Spectrum shifts about 50 eV which is roughly 9*Udd (in my simulation Udd is approximately 5.8 eV). Furthermore, the set of the energy states changes. It can be seen from the position of the peaks found through the diagonalization of the Hamiltonian.
Thanks, Riccardo
Yes, adding pictures would be nice. (I'm not super happy with docu wiki, especially not with the options to make a forum). If you sent them to me by mail I'll add them to the Forum post.
Maurits
Sorry for editing completely the message but I found a “strange bug” that could be responsible for the problem. To simplify you can just take a shell d with 10 spin-orbital and this hamiltonian
H = lambda*OppUdd + Bz*(OppLz + 2*OppSz) + zeta_3d*Oppldots + (ed + Udd*(1-lambda))*OppN_d
lambda is a coupling constant to turn on/off the Coulomb repulsion. While diagonalizing a d9 system I obtain random values for the J^2 eigenvalue. Here are some example of the output. Look at the J^2 column.
I could have shown you countless others. At each run that column changes randomly BUT If I repeat the same calculation for a d^1 system (equal to the d^9 one thanks to particle-hole symmetry) I instead obtain the right multiplets:
It's kinda weird, don't you think? It involves the d9 system only!!
Here is the script. You can run it to check this strange thing
Input.in is a file with l and Nelec
I made some tests and I've found that while diagonalizing a d10 system if zeta spin-orbit is too small with respect to F0 then states with different J mixes and j is not still a good quantum number. The problem is resolved by putting a larger spin-orbit but if my system has a spin-orbit coupling of the order of 0.01 eV and an F0 of the order of 6 eV for the 4d levels and Quanty is not able to diagonalize the Hamiltonian correctly with these values, how can I do it? Is there any variable related to the number of iterations involved in the diagonalization?
Dear Riccardo,
Quanty stops the calculation when a given accuracy is reached. Determining if this is the case is not always easy. The difference between 10.001 and 10.002 might seem small, but is the same as the difference between 0.001 and 0.002 where it is a factor of two. For your d9 case the energy difference between the two SOC states is on the sub per mile level. This is due to a shift of the energy of all your states. The code should recognise this, but in your case did not. I will have a look to see if I can improve this.
At the same time you can tell the code the accuracy of the calculation you want
Change line 117 from
to
and the problem should disappear.
Sorry for that
Maurits
I've seen you noticed that Quanty / Lua can handle more than ASCII characters….. (You can now generate the most obfuscated code by using the different space characters in unicode as the different variables. On top of that redefine all functions by similar variables made of space characters and you can have an seemingly empty file doing your calculations…)
PS If you would leave the verbosity to its standard value you would get this extra output With standard value for convergence
With better convergence
Quanty decided that the random starting vectors were converged enough for the accuracy asked for and never started to diagonalise… When I start to diagonalise I apply a shift, and after the shift the variance is no longer below the threshold.