def test_Er_LaF3(): """ Tests that we give the same results as Carnall 1989 for Pr:LaF3 """ #energy levels from Carnall's paper carnall_levels = [-22, 27, 92, 176, 193, 289, 375, 420, 6612, 6637, 6686, 6699, 6732, 6771, 6830, 10300, 10314, 10336, 10351, 10365, 10405] carnall_levels = np.array(carnall_levels) carnall_levels = carnall_levels -np.min(carnall_levels) nf = 11 # 11 f-electrons means we're dealing with Er Er = dieke.RareEarthIon(nf) cfparams = dieke.readLaF3params(nf) # Number of levels and states numLSJ = Er.numlevels() numLSJmJ = Er.numstates() # Make a free-ion Hamiltonian H0 = np.zeros([numLSJmJ, numLSJmJ]) for k in cfparams.keys(): if k in Er.FreeIonMatrix: H0 = H0+cfparams[k]*Er.FreeIonMatrix[k] # Add in the crystal field terms H = H0 for k in [2, 4, 6]: for q in range(0, k+1): if 'B%d%d' % (k, q) in cfparams: if q == 0: H = H+cfparams['B%d%d' % (k, q)]*Er.Cmatrix(k, q) else: Bkq = cfparams['B%d%d' % (k, q)] Bkmq = (-1)**q*np.conj(Bkq) # B_{k,-q} Ckq = Er.Cmatrix(k, q) Ckmq = Er.Cmatrix(k, -q) # See page 44, eq 3.1 of the crystal field handbook H = H + Bkq*Ckq + Bkmq*Ckmq # Diagonalise the result (evals, evects) = np.linalg.eig(H) E0 = np.min(evals) calc_nrg_levels = np.sort(evals-E0) calc_nrg_levels = calc_nrg_levels[::2] print(' Jevon Carnall Difference') for k in range(len(carnall_levels)): print("%9.1f %9.1f %6.1f"%(np.real(calc_nrg_levels[k]),carnall_levels[k],np.real(calc_nrg_levels[k]) - carnall_levels[k])) # Assert that they all agree within 1.1 wave number assert(np.max(np.abs( calc_nrg_levels[0:len(carnall_levels)]-carnall_levels)) < 1.1 )
def test_Pr_LaF3(): """ Tests that we give the same results as Carnall 1989 for Pr:LaF3 """ #energy levels from Carnall's paper carnall_levels = [0.2, 71, 95, 138, 183, 221, 333, 444, 463, 2126, 2158, 2191, 2284, 2290, 2295, 2318, 2399, 2412,2438, 2540, 4179,4200, 4283, 4321, 4384, 4467, 4478, 4496] carnall_levels = np.array(carnall_levels) nf = 2 # 2 f-electrons means we're dealing with Pr Pr = dieke.RareEarthIon(nf) cfparams = dieke.readLaF3params(nf) # Number of levels and states numLSJ = Pr.numlevels() numLSJmJ = Pr.numstates() # Make a free-ion Hamiltonian H0 = np.zeros([numLSJmJ, numLSJmJ]) for k in cfparams.keys(): if k in Pr.FreeIonMatrix: H0 = H0+cfparams[k]*Pr.FreeIonMatrix[k] # Add in the crystal field terms H = H0 for k in [2, 4, 6]: for q in range(0, k+1): if 'B%d%d' % (k, q) in cfparams: if q == 0: H = H+cfparams['B%d%d' % (k, q)]*Pr.Cmatrix(k, q) else: Bkq = cfparams['B%d%d' % (k, q)] Bkmq = (-1)**q*np.conj(Bkq) # B_{k,-q} Ckq = Pr.Cmatrix(k, q) Ckmq = Pr.Cmatrix(k, -q) # See page 44, eq 3.1 of the crystal field handbook H = H + Bkq*Ckq + Bkmq*Ckmq # Diagonalise the result (evals, evects) = np.linalg.eig(H) E0 = np.min(evals) calc_nrg_levels = np.sort(evals-E0) # Assert that they all agree within one wave number assert(np.max(np.abs( calc_nrg_levels[0:len(carnall_levels)]-carnall_levels)) < 1.0 )
# Testing Hermitian stuff ckeys = [ 'C20', 'C21', 'C22', 'C40', 'C41', 'C42', 'C43', 'C44', 'C60', 'C61', 'C62', 'C63', 'C64', 'C65', 'C66' ] for ckey in ckeys: mike_test = np.matrix(mikemats[ckey]) if np.linalg.norm(herm_test - herm_test.H) < EPS: print("Mikes %s is Hermitian" % ckey) else: print("Mikes %s is not Hermitian" % ckey) # Read in a a set of crystal field parameters from Er:LaF3 # dieke reads these from (incomplete) carnall89params.xls cfparams = dieke.readLaF3params(nf) #change most of the parameters to those in eryso_cf paper #leave some from carnall89 cfparams['E0'] = 35503.5 #this is ignored cfparams['ZETA'] = 2362.9 cfparams['F2'] = 96029.6 cfparams['F4'] = 67670.6 cfparams['F6'] = 53167.1 cfparams['B20'] = -149.8 cfparams['B21'] = 420.6 + 396.0j cfparams['B22'] = -228.5 + 27.6j cfparams['B40'] = 1131.2 cfparams['B41'] = 985.7 + 34.2j
def test_ErYSO(): """ Tests that we give the same as Sebastians calcs for ErYSO (arXiv:1809.01058) """ #energy levels from Paper seb_levels = [15, 47, 75, 130, 199, 388, 462, 508, 6522, 6560, 6583, 6640, 6777, 6833, 6867, 10206, 10236, 10267, 10339, 10381, 10398] seb_levels = np.array(seb_levels) nf = 11 # 11 f-electrons means we're dealing with Er Er = dieke.RareEarthIon(nf) # Number of levels and states numLSJ = Er.numlevels() numLSJmJ = Er.numstates() cfparams = dieke.readLaF3params(nf) cfparams['E0'] = 35503.5 #this is ignored cfparams['ZETA'] = 2362.9 cfparams['F2'] = 96029.6 cfparams['F4'] = 67670.6 cfparams['F6'] = 53167.1 cfparams['B20'] = -149.8 cfparams['B21'] = 420.6+396.0j cfparams['B22'] = -228.5+27.6j cfparams['B40'] = 1131.2 cfparams['B41'] = 985.7+34.2j cfparams['B42'] = 296.8+145.0j cfparams['B43'] = -402.3-381.7j cfparams['B44'] = -282.3+1114.3j cfparams['B60'] = -263.2 cfparams['B61'] = 111.9+222.9j cfparams['B62'] = 124.7+195.9j cfparams['B63'] = -97.9+139.7j cfparams['B64'] = -93.7-145.0j cfparams['B65'] = 13.9+109.5j cfparams['B66'] = 3.0-108.6j cfparams['A'] = 0.005466 #this is ignored cfparams['Q'] = 0.0716 #this is ignored # Make a free-ion Hamiltonian H0 = np.zeros([numLSJmJ, numLSJmJ]) for k in sorted(cfparams.keys()): if k in Er.FreeIonMatrix: print("Adding free ion parameter \'%s\' = %g" % (k, cfparams[k])) H0 = H0+cfparams[k]*Er.FreeIonMatrix[k] # Add in the crystal field terms and diagonalise the result H = H0 for k in [2, 4, 6]: for q in range(0, k+1): if 'B%d%d' % (k, q) in cfparams: if q == 0: H = H+cfparams['B%d%d' % (k, q)]*Er.Cmatrix(k, q) else: Bkq = cfparams['B%d%d' % (k, q)] Bkmq = (-1)**q*np.conj(Bkq) Ckq = Er.Cmatrix(k, q) Ckmq = Er.Cmatrix(k, -q) #See page 44, eq 3.1 of the crystal field handbook H = H + Bkq*Ckq + Bkmq*Ckmq (evals, evects) = np.linalg.eig(H) E0 = np.min(evals) calc_nrg_levels = np.sort(evals-E0) calc_nrg_levels = calc_nrg_levels[::2] # ignore every second element E0seb = np.min(seb_levels) seb_levels = seb_levels-E0seb print(' Jevon Sebastian Difference') for k in range(len(seb_levels)): print("%9.1f %9.1f %6.1f"%(np.real(calc_nrg_levels[k]),seb_levels[k],np.real(calc_nrg_levels[k]) - seb_levels[k])) # This isn't much of a test at the moment because there seems to be # an issue with the free ion parameters assert(np.max(np.abs( calc_nrg_levels[0:len(seb_levels)]-seb_levels)) < 26.0 ) # This is more of a test because it it only looks at the ground multiplet assert(np.max(np.abs( calc_nrg_levels[0:8]-seb_levels[0:8])) < 0.6 )