Differences
This shows you the differences between two versions of the page.
documentation:tutorials:small_programs_a_quick_start:energy_level_diagram [2016/10/07 20:00] – created Maurits W. Haverkort | documentation:tutorials:small_programs_a_quick_start:energy_level_diagram [2016/10/10 09:41] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | {{indexmenu_n> | ||
+ | ====== Energy level diagram ====== | ||
+ | ### | ||
+ | Example four shows the calculation of an energy level diagram of Ni$^{2+}$ as a function of the cubic crystal field parameter. Temperature leads to an occupation of excited states according to Bolzman statistics. It then becomes important to know the excited states. Here we calculate a graph showing these states as a function of the crystal-filed parameters. Although crystal field theory is often a highly oversimplified theory not accurate enough to describe a system well, degeneracies are given by symmetry and the here obtained energy level diagram will mostly change quantitative, | ||
+ | ### | ||
+ | |||
+ | ### | ||
+ | The text output written to screen does not show much interesting information. | ||
+ | <file Quanty_Output Energy_Level_Diagram.out> | ||
+ | --> In this example we shall plot the energy-level diagram (so-called ' | ||
+ | --> Energy levels will be printed a function of 10Dq parameter, representing the crystal field strength | ||
+ | --> Setting up the d-shell | ||
+ | --> d8 (2 holes) | ||
+ | |||
+ | |||
+ | --> Initial Hamiltonian: | ||
+ | --> H0 = F0dd*OppF0 + F2dd*OppF2 + F4dd*OppF4 + zeta_3d*Oppldots + Bz*(2*OppSz + OppLz); | ||
+ | |||
+ | ================================= | ||
+ | --> List of parameters: | ||
+ | --> F2dd = 11.142 | ||
+ | --> F4dd = 6.874 | ||
+ | --> F0dd = U+(F2dd+F4dd)*2/ | ||
+ | --> zeta_3d = 0.081 | ||
+ | --> Bz = 0.000001 | ||
+ | ================================= | ||
+ | |||
+ | --> Diagonalising... | ||
+ | |||
+ | --> Adding the Crystal field as a perturbation: | ||
+ | --> start increasing x ... | ||
+ | 10Dq = 0.000 0.010 0.020 0.030 0.040 0.050 0.060 0.070 0.080 0.090 0.100 0.110 0.120 0.130 0.140 0.150 0.160 0.170 0.180 0.190 0.200 0.210 0.220 0.230 0.240 0.250 0.260 0.270 0.280 0.290 0.300 0.310 0.320 0.330 0.340 0.350 0.360 0.370 0.380 0.390 0.400 0.410 0.420 0.430 0.440 0.450 0.460 0.470 0.480 0.490 0.500 0.510 0.520 0.530 0.540 0.550 0.560 0.570 0.580 0.590 0.600 0.610 0.620 0.630 0.640 0.650 0.660 0.670 0.680 0.690 0.700 0.710 0.720 0.730 0.740 0.750 0.760 0.770 0.780 0.790 0.800 0.810 0.820 0.830 0.840 0.850 0.860 0.870 0.880 0.890 0.900 0.910 0.920 0.930 0.940 0.950 0.960 0.970 0.980 0.990 1.000 1.010 1.020 1.030 1.040 1.050 1.060 1.070 1.080 1.090 1.100 1.110 1.120 1.130 1.140 1.150 1.160 1.170 1.180 1.190 1.200 1.210 1.220 1.230 1.240 1.250 1.260 1.270 1.280 1.290 1.300 1.310 1.320 1.330 1.340 1.350 1.360 1.370 1.380 1.390 1.400 1.410 1.420 1.430 1.440 1.450 1.460 1.470 1.480 1.490 1.500 1.510 1.520 1.530 1.540 1.550 1.560 1.570 1.580 1.590 1.600 1.610 1.620 1.630 1.640 1.650 1.660 1.670 1.680 1.690 1.700 1.710 1.720 1.730 1.740 1.750 1.760 1.770 1.780 1.790 1.800 1.810 1.820 1.830 1.840 1.850 1.860 1.870 1.880 1.890 1.900 1.910 1.920 1.930 1.940 1.950 1.960 1.970 1.980 1.990 2.000 2.010 2.020 2.030 2.040 2.050 2.060 2.070 2.080 2.090 2.100 2.110 2.120 2.130 2.140 2.150 2.160 2.170 2.180 2.190 2.200 2.210 2.220 2.230 2.240 2.250 2.260 2.270 2.280 2.290 2.300 2.310 2.320 2.330 2.340 2.350 2.360 2.370 2.380 2.390 2.400 2.410 2.420 2.430 2.440 2.450 2.460 2.470 2.480 2.490 2.500 2.510 2.520 2.530 2.540 2.550 2.560 2.570 2.580 2.590 2.600 2.610 2.620 2.630 2.640 2.650 2.660 2.670 2.680 2.690 2.700 2.710 2.720 2.730 2.740 2.750 2.760 2.770 2.780 2.790 2.800 2.810 2.820 2.830 2.840 2.850 2.860 2.870 2.880 2.890 2.900 2.910 2.920 2.930 2.940 2.950 2.960 2.970 2.980 2.990 3.000 | ||
+ | </ | ||
+ | ### | ||
+ | |||
+ | ### | ||
+ | {{: | ||
+ | |||
+ | The energy level diagram of Ni$^{2+}$. i.e. the energy of the 45 eigen-states of 8 electrons in a $d$-shell as a function of the crystal-field splitting. | ||
+ | ### | ||
+ | |||
+ | ### | ||
+ | But the pdf created (see above) shows the energy level diagram. For $10Dq=0$ one has spherical symmetry and retrieves the atomic energy levels. We plotted the term symbols next to the level energies. Increasing the crystal field leads to a splitting of these levels and at some point to a mixing. | ||
+ | ### | ||
+ | |||
+ | ### | ||
+ | For completeness, | ||
+ | <code Quanty Energy_Level_Diagram.Quanty> | ||
+ | -- Minimize the output of the program, i.e. for longer calculations | ||
+ | -- the program tells the user what it is doing. For these short | ||
+ | -- examples the result is instant. | ||
+ | Verbosity(0) | ||
+ | |||
+ | print(" | ||
+ | print(" | ||
+ | print(" | ||
+ | |||
+ | -- number of available fermionic spin-orbitals (d-shell in the present case) | ||
+ | NFermion=10; | ||
+ | -- number of bosonic states (phonons, etc...) | ||
+ | NBoson=0; | ||
+ | -- indices for the " | ||
+ | IndexDn_3d={0, | ||
+ | -- indices for the " | ||
+ | IndexUp_3d={1, | ||
+ | |||
+ | -- function to print Term symbols | ||
+ | function LSJ2term (S2,L2,J2) | ||
+ | L = math.floor(0.5 * (math.sqrt(math.abs(L2) * 4 +1) - 1) + 0.5) | ||
+ | if L == 0 then str1=" | ||
+ | elseif L == 1 then str1=" | ||
+ | elseif L == 2 then str1=" | ||
+ | elseif L == 3 then str1=" | ||
+ | elseif L == 4 then str1=" | ||
+ | elseif L == 5 then str1=" | ||
+ | elseif L == 6 then str1=" | ||
+ | elseif L == 7 then str1=" | ||
+ | elseif L == 8 then str1=" | ||
+ | elseif L == 9 then str1=" | ||
+ | elseif L == 10 then str1=" | ||
+ | elseif L == 11 then str1=" | ||
+ | elseif L == 12 then str1=" | ||
+ | elseif L == 13 then str1=" | ||
+ | elseif L == 14 then str1=" | ||
+ | elseif L == 15 then str1=" | ||
+ | elseif L == 16 then str1=" | ||
+ | elseif L == 17 then str1=" | ||
+ | elseif L == 18 then str1=" | ||
+ | elseif L == 19 then str1=" | ||
+ | elseif L == 20 then str1=" | ||
+ | else | ||
+ | str1="?" | ||
+ | end | ||
+ | mult = math.floor(math.sqrt(S2 * 4 +1)+0.5) | ||
+ | twoJ = math.floor((math.sqrt(math.abs(J2) * 4 +1) - 1) + 0.5) | ||
+ | if( 2*math.floor((twoJ+0.5)/ | ||
+ | return " | ||
+ | else | ||
+ | return " | ||
+ | end | ||
+ | end | ||
+ | |||
+ | -- Here we define the operators in the space of chosen orbitals | ||
+ | |||
+ | OppSx | ||
+ | OppSy | ||
+ | OppSz | ||
+ | OppSsqr =NewOperator(" | ||
+ | OppSplus=NewOperator(" | ||
+ | OppSmin =NewOperator(" | ||
+ | |||
+ | OppLx | ||
+ | OppLy | ||
+ | OppLz | ||
+ | OppLsqr =NewOperator(" | ||
+ | OppLplus=NewOperator(" | ||
+ | OppLmin =NewOperator(" | ||
+ | |||
+ | OppJx | ||
+ | OppJy | ||
+ | OppJz | ||
+ | OppJsqr =NewOperator(" | ||
+ | OppJplus=NewOperator(" | ||
+ | OppJmin =NewOperator(" | ||
+ | |||
+ | -- Spin-orbit coupling | ||
+ | Oppldots=NewOperator(" | ||
+ | |||
+ | -- e-e Coulomb repulsion | ||
+ | OppF0 =NewOperator(" | ||
+ | OppF2 =NewOperator(" | ||
+ | OppF4 =NewOperator(" | ||
+ | |||
+ | -- Expansion of the effective electron-ion potential in the certain symmetry (" | ||
+ | -- This operator splits the states: it lowers one manifold on 0.4 [e.u.] and lifts the other on 0.6 [e.u.] | ||
+ | -- in the limit of very strong CF we can call these manifolds as T2g and Eg | ||
+ | Akm = PotentialExpandedOnClm(" | ||
+ | OpptenDq = NewOperator(" | ||
+ | |||
+ | -- We can define the operator which will count the number of particles in each manifold | ||
+ | Akm = PotentialExpandedOnClm(" | ||
+ | OppNeg = NewOperator(" | ||
+ | Akm = PotentialExpandedOnClm(" | ||
+ | OppNt2g = NewOperator(" | ||
+ | |||
+ | print(" | ||
+ | print("" | ||
+ | -- Here we set up the parameters for the operators, defined above. | ||
+ | Npsi=45; | ||
+ | U | ||
+ | F2dd = 11.142 | ||
+ | F4dd = 6.874 | ||
+ | F0dd = U+(F2dd+F4dd)*2/ | ||
+ | zeta_3d = 0.081 | ||
+ | Bz = 0.000001 | ||
+ | |||
+ | print("" | ||
+ | print(" | ||
+ | print(" | ||
+ | print("" | ||
+ | print(" | ||
+ | print(" | ||
+ | print(" | ||
+ | print(" | ||
+ | print(" | ||
+ | print(" | ||
+ | print(" | ||
+ | print(" | ||
+ | print("" | ||
+ | |||
+ | -- Setting up the initial Hamiltonian in the 2nd quantised form | ||
+ | -- Note: here we do not have the CF | ||
+ | Hamiltonian0 = F0dd*OppF0 + F2dd*OppF2 + F4dd*OppF4 + zeta_3d*Oppldots + Bz*(2*OppSz + OppLz); | ||
+ | -- We shall now diagonalise the Hamiltonian, | ||
+ | StartRestrictions = {NFermion, NBoson, | ||
+ | |||
+ | print(" | ||
+ | -- Diagonalisation of the initial Hamiltonian (no CF) | ||
+ | psiList = Eigensystem(Hamiltonian0, | ||
+ | |||
+ | TermSymbol={} ; TermSymbol[0]=""; | ||
+ | for i =1,Npsi do | ||
+ | S2=psiList[i] * OppSsqr * psiList[i] | ||
+ | L2=psiList[i] * OppLsqr * psiList[i] | ||
+ | J2=psiList[i] * OppJsqr * psiList[i] | ||
+ | E0[i]=psiList[i] * Hamiltonian0 * psiList[i] | ||
+ | TermSymbol[i]=LSJ2term(S2, | ||
+ | end | ||
+ | |||
+ | -- Open up the file, where the data will be stored | ||
+ | file = assert(io.open(" | ||
+ | |||
+ | print("" | ||
+ | print(" | ||
+ | print(" | ||
+ | io.write(" | ||
+ | -- We add the CF to the Hamiltonian and start varying its strength. Each time we update the H, we re-diagonalise it. | ||
+ | for i=0, 300 do | ||
+ | tenDq = 0.01*i | ||
+ | file: | ||
+ | io.write(string.format(" | ||
+ | io.flush() | ||
+ | Hamiltonian=Hamiltonian0 + tenDq * OpptenDq | ||
+ | Eigensystem(Hamiltonian, | ||
+ | for key,value in pairs(psiList) do | ||
+ | energy = value * Hamiltonian * value | ||
+ | file: | ||
+ | end | ||
+ | file: | ||
+ | end | ||
+ | file: | ||
+ | io.write(" | ||
+ | |||
+ | -- The output will be supplied to the gnuplot for consequent visualisation | ||
+ | -- Starting the preparation of the gnuplot-input file | ||
+ | |||
+ | gnuplotInput = [[ | ||
+ | set terminal postscript portrait enhanced color " | ||
+ | set autoscale | ||
+ | set xtic auto # set xtics automatically | ||
+ | set ytic auto # set ytics automatically | ||
+ | set style line 1 lt 1 lw 1 lc rgb "# | ||
+ | |||
+ | set xlabel "10Dq (eV)" font " | ||
+ | set ylabel " | ||
+ | |||
+ | set out ' | ||
+ | set size 1.0, 0.625 | ||
+ | ]] | ||
+ | |||
+ | -- write the gnuplot script to a file | ||
+ | file = io.open(" | ||
+ | file: | ||
+ | |||
+ | for i=1,Npsi do | ||
+ | if (abs(E0[i]-E0[i-1]) > 0.1 and TermSymbol[i] ~= TermSymbol[i-1]) then | ||
+ | file: | ||
+ | end | ||
+ | end | ||
+ | |||
+ | gnuplotInput=[[ | ||
+ | plot for [i=2:46] " | ||
+ | ]] | ||
+ | |||
+ | file: | ||
+ | file: | ||
+ | |||
+ | -- call gnuplot to execute the script | ||
+ | os.execute(" | ||
+ | </ | ||
+ | ### | ||
+ | |||
+ | |||
+ | ===== Table of contents ===== | ||
+ | {{indexmenu> |