Density matrix plot
An intuitive way to look at eigenstates is to plot the charge density. For multi-electron wave-functions one can not plot the wave-function (it depends on $3\times n$ coordinates) but the charge density is a well defined simple quantity. We here use the rendering options of \textit{Mathematica} in combination with the package for \textit{Mathematica} (Quanty.nb) to plot the density matrix of the lowest three eigenstates in NiO.
The input script is:
- density_matrix_plots_Mathematica.Quanty
-- It is often nice to make plots of the resulting "wave-functions" Now one can not -- simply plot a multi-electron wavefunction \psi(r_1,r_2,r_3, ..., r_n) as it depends -- on 3n coordinates. -- One can plot the resulting charge density. -- This example calculates the density matrix of a state and then calls Mathematica to -- make a density plot of this matrix. -- the script for mathematica is included in the input file -- the input string needs calculated data which will be substituted before calling mathematica Verbosity(0) -- You need to change the absolute path in the script below mathematicaInput = [[ Needs["Quanty`PlotTools`"]; rho=%s; pl = Table[ Rasterize[ DensityMatrixPlot[IdentityMatrix[10] - rho[ [i] ], PlotRange -> {{-0.4, 0.4}, {-0.4, 0.4}, {-0.4, 0.4}}] ], {i, 1, Length[rho]}]; For[i = 1, i <= Length[pl], i++, Export["/Users/haverkort/Documents/Quanty/Example_and_Testing/History/current/Tutorials/20_NiO_Crystal_Field/Rho" <> ToString[i] <> ".png", pl[ [i] ] ]; ]; Quit[]; ]] NF=10 NB=0 dIndexDn={0,2,4,6,8} dIndexUp={1,3,5,7,9} OppSx =NewOperator("Sx" ,NF, dIndexUp, dIndexDn) OppSy =NewOperator("Sy" ,NF, dIndexUp, dIndexDn) OppSz =NewOperator("Sz" ,NF, dIndexUp, dIndexDn) OppSsqr =NewOperator("Ssqr" ,NF, dIndexUp, dIndexDn) OppSplus=NewOperator("Splus",NF, dIndexUp, dIndexDn) OppSmin =NewOperator("Smin" ,NF, dIndexUp, dIndexDn) OppLx =NewOperator("Lx" ,NF, dIndexUp, dIndexDn) OppLy =NewOperator("Ly" ,NF, dIndexUp, dIndexDn) OppLz =NewOperator("Lz" ,NF, dIndexUp, dIndexDn) OppLsqr =NewOperator("Lsqr" ,NF, dIndexUp, dIndexDn) OppLplus=NewOperator("Lplus",NF, dIndexUp, dIndexDn) OppLmin =NewOperator("Lmin" ,NF, dIndexUp, dIndexDn) OppJx =NewOperator("Jx" ,NF, dIndexUp, dIndexDn) OppJy =NewOperator("Jy" ,NF, dIndexUp, dIndexDn) OppJz =NewOperator("Jz" ,NF, dIndexUp, dIndexDn) OppJsqr =NewOperator("Jsqr" ,NF, dIndexUp, dIndexDn) OppJplus=NewOperator("Jplus",NF, dIndexUp, dIndexDn) OppJmin =NewOperator("Jmin" ,NF, dIndexUp, dIndexDn) Oppldots=NewOperator("ldots",NF, dIndexUp, dIndexDn) -- define the coulomb operator -- we here define the part depending on F0 seperately from the part depending on F2 -- when summing we can put in the numerical values of the slater integrals OppF0 =NewOperator("U", NF, dIndexUp, dIndexDn, {1,0,0}) OppF2 =NewOperator("U", NF, dIndexUp, dIndexDn, {0,1,0}) OppF4 =NewOperator("U", NF, dIndexUp, dIndexDn, {0,0,1}) -- Akm = {{k1,m1,Akm1},{k2,m2,Akm2}, ... } Akm = PotentialExpandedOnClm("Oh", 2, {0.6,-0.4}) OpptenDq = NewOperator("CF", NF, dIndexUp, dIndexDn, Akm) Akm = PotentialExpandedOnClm("Oh", 2, {1,0}) OppNeg = NewOperator("CF", NF, dIndexUp, dIndexDn, Akm) Akm = PotentialExpandedOnClm("Oh", 2, {0,1}) OppNt2g = NewOperator("CF", NF, dIndexUp, dIndexDn, Akm) Hamiltonian = 10.0 * OppF2 + 6.25 * OppF4 + 2.0 * OpptenDq + 0.06 * Oppldots + 0.000001 * (2*OppSz + OppLz) -- we now can create the lowest Npsi eigenstates: Npsi=3 -- in order to make sure we have a filling of 2 electrons we need to define some restrictions StartRestrictions = {NF, NB, {"1111111111",8,8}} psiList = Eigensystem(Hamiltonian, StartRestrictions, Npsi) oppList={Hamiltonian, OppSsqr, OppLsqr, OppJsqr, OppSz, OppLz, Oppldots, OppF2, OppF4, OppNeg, OppNt2g} print(" <E> <S^2> <L^2> <J^2> <S_z> <L_z> <l.s> <F[2]> <F[4]> <Neg> <Nt2g>"); for key,psi in pairs(psiList) do expvalue = psi * oppList * psi for k,v in pairs(expvalue) do io.write(string.format("%6.3f ",v)) end; io.write("\n") end io:flush() function tableToMathematica(t) local ret = "{ " for k,v in pairs(t) do if k~=1 then ret = ret.." , " end if (type(v) == "table") then ret = ret..tableToMathematica(v) else ret = ret..string.format("%18.15f + (%18.15f) I ",Complex.Re(v),Complex.Im(v)) end end ret = ret.." }" return ret end rhoList = DensityMatrix(psiList, {0,1,2,3,4,5,6,7,8,9}) rhoListMathematicaForm = tableToMathematica(rhoList) file = io.open("densitymatrix.nb", "w") file:write( mathematicaInput:format( rhoListMathematicaForm ) ) file:close() os.execute("/Applications/Mathematica08.app/Contents/MacOS/MathKernel -run '<<densitymatrix.nb'") os.execute("convert Rho1.png -transparent white temp.png ; convert temp.png Rho1.eps ; rm temp.png") os.execute("convert Rho2.png -transparent white temp.png ; convert temp.png Rho2.eps ; rm temp.png") os.execute("convert Rho3.png -transparent white temp.png ; convert temp.png Rho3.eps ; rm temp.png")
The produced figures are:
$S_z=-1$ | $S_z=0$ | $S_z=1$ |
---|---|---|
Density matrix of the ground, first and second excited state of Ni in NiO. |
The plots can be seen in the figure above. We show the hole density (identity matrix minus the density matrix) which has lobes towards the O atoms. Ni in NiO has a hole in the $x^2-y^2$ and in the $z^2$ orbital. The color represent the spin down, $S_z=0$ and spin up state of the lowest triplet.
The output to the screen is:
- density_matrix_plots_Mathematica.out
<E> <S^2> <L^2> <J^2> <S_z> <L_z> <l.s> <F[2]> <F[4]> <Neg> <Nt2g> -18.093 2.000 12.000 14.471 -0.999 -0.119 -0.147 -1.020 -0.878 2.002 5.998 -18.093 2.000 12.000 14.471 -0.000 -0.000 -0.147 -1.020 -0.878 2.002 5.998 -18.093 2.000 12.000 14.471 0.999 0.119 -0.147 -1.020 -0.878 2.002 5.998 Mathematica 8.0 for Mac OS X x86 (64-bit) Copyright 1988-2011 Wolfram Research, Inc. Loaded the Quanty : Plot Tools Package - version 2016.4.13 Written by Maurits W. Haverkort