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:
-- 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:
<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