def test_get_phi0_and_get_phi1(): p = Parameters_double_dot_spinless() system = qmeq.Builder(p.nsingle, p.hsingle, p.coulomb, p.nleads, p.tleads, p.mulst, p.tlst, p.dlst2, kerntype='1vN', itype=0) system.solve() assert norm(abs(system.get_phi0(1, 2)) - 0.00284121629354) < EPS assert norm(system.get_phi0(1, 2).conjugate() - system.get_phi0(2, 1)) < EPS assert norm(abs(get_phi0(system, 1, 2)) - 0.00284121629354) < EPS assert norm(get_phi0(system, 1, 2).conjugate() - get_phi0(system, 2, 1)) < EPS # assert norm( abs(system.get_phi1(0, 1, 0)) - 2.6173227979053406) < EPS assert norm(system.get_phi1(0, 1, 0).conjugate() - system.get_phi1(0, 0, 1)) < EPS assert norm( abs(get_phi1(system, 0, 1, 0)) - 2.6173227979053406) < EPS assert norm(get_phi1(system, 0, 1, 0).conjugate() - get_phi1(system, 0, 0, 1)) < EPS # system = qmeq.Builder(p.nsingle, p.hsingle, p.coulomb, p.nleads, p.tleads, p.mulst, p.tlst, p.dlst, kerntype='2vN', kpnt=p.kpnt) system.solve(niter=5) assert norm(abs(system.get_phi0(1, 2)) - 0.0028388555051) < EPS assert norm(system.get_phi0(1, 2).conjugate() - system.get_phi0(2, 1)) < EPS assert norm(abs(get_phi0(system, 1, 2)) - 0.0028388555051) < EPS assert norm(get_phi0(system, 1, 2).conjugate() - get_phi0(system, 2, 1)) < EPS # assert norm( abs(system.get_phi1(0, 1, 0)) - 2.4806366680863543) < EPS assert norm(system.get_phi1(0, 1, 0).conjugate() - system.get_phi1(0, 0, 1)) < EPS assert norm( abs(get_phi1(system, 0, 1, 0)) - 2.4806366680863543) < EPS assert norm(get_phi1(system, 0, 1, 0).conjugate() - get_phi1(system, 0, 0, 1)) < EPS
def test_Approach2vN_kpnt(): system = qmeq.Builder(nleads=1, dband={0: 1000}, kpnt=5, kerntype='2vN') appr = Approach2vN(system) appr.make_Ek_grid() assert appr.Ek_grid.tolist() == [-1000, -500, 0, 500, 1000] appr.funcp.kpnt = 6 appr.make_Ek_grid() assert appr.Ek_grid.tolist() == [-1000, -600, -200, 200, 600, 1000] # system = qmeq.Builder(1, {}, {}, 1, {}, {}, {}, {0: 1000}, kpnt=5, kerntype='2vN') system.appr.make_Ek_grid() assert system.appr.Ek_grid.tolist() == [-1000, -500, 0, 500, 1000] system.kpnt = 6 system.appr.make_Ek_grid() assert system.appr.Ek_grid.tolist() == [-1000, -600, -200, 200, 600, 1000]
def test_Approach2vN_make_Ek_grid(): system = qmeq.Builder(nleads=2, dband={0: [-1000, 1000], 1: [-1000, 1000]}, kpnt=5, kerntype='2vN') appr = Approach2vN(system) appr.make_Ek_grid() assert appr.Ek_grid.tolist() == [-1000, -500, 0, 500, 1000] appr.leads.change(dlst={0: [-1400, 1000], 1: [-1000, 1000]}) appr.make_Ek_grid() assert appr.Ek_grid.tolist() == [-1400.0, -800.0, -200.0, 400.0, 1000.0]
def test_construct_Ea_extended(): data = {'Lin': [[0.0, -31.024984394500787, -31.024984394500787, -14.182934011942466, 9.024984394500784, 8.0, 8.0, 86.9750156054992, 9.024984394500784, 8.0, 57.87579144142183, 86.9750156054992, 80.30714257052065, 127.02498439450079, 127.02498439450079, 236.0], [0.0, 1.0, 1.0, 2.0, 1.0, 2.0, 2.0, 3.0, 1.0, 2.0, 2.0, 3.0, 2.0, 3.0, 3.0, 4.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0]], 'charge': [[0.0, -31.024984394500787, -31.024984394500787, 9.024984394500784, 9.024984394500784, -14.182934011942466, 8.0, 8.0, 8.0, 57.87579144142183, 80.30714257052065, 86.9750156054992, 86.9750156054992, 127.02498439450079, 127.02498439450079, 236.0], [0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0]], 'sz': [[0.0, -31.024984394500787, 9.024984394500784, -31.024984394500787, 9.024984394500784, 8.0, -14.182934011942466, 8.0, 57.87579144142183, 80.30714257052065, 8.0, 86.9750156054992, 127.02498439450079, 86.9750156054992, 127.02498439450079, 236.0], [0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0], [0.0, -1.0, -1.0, 1.0, 1.0, -2.0, 0.0, 0.0, 0.0, 0.0, 2.0, -1.0, -1.0, 1.0, 1.0, 0.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0]], 'ssq': [[0.0, -31.024984394500787, 9.024984394500784, -31.024984394500787, 9.024984394500784, 8.0, -14.182934011942473, 57.875791441421825, 80.30714257052063, 8.0, 8.0, 86.9750156054992, 127.02498439450079, 86.9750156054992, 127.02498439450079, 236.0], [0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0], [0.0, -1.0, -1.0, 1.0, 1.0, -2.0, 0.0, 0.0, 0.0, 0.0, 2.0, -1.0, -1.0, 1.0, 1.0, 0.0], [0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 0.0, 0.0, 0.0, 2.0, 2.0, 1.0, 1.0, 1.0, 1.0, 0.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0]]} p = Parameters_double_dot_spinful() for indexing in ['Lin', 'charge', 'sz', 'ssq']: system = qmeq.Builder(p.nsingle, p.hsingle, p.coulomb, p.nleads, p.tleads, p.mulst, p.tlst, p.dlst, indexing=indexing) system.solve(masterq=False) assert norm(construct_Ea_extended(system)- data[indexing]) < EPS
def test_remove_states(): p = Parameters_double_dot_spinful() system = qmeq.Builder(p.nsingle, p.hsingle, p.coulomb, p.nleads, p.tleads, p.mulst, p.tlst, p.dlst) system.solve() # system.remove_states(50.0) assert system.si.statesdm == [[0], [1, 2, 3, 4], [5, 6, 7, 8], [], [], []] system.use_all_states() assert system.si.statesdm == [[0], [1, 2, 3, 4], [5, 6, 7, 8, 9, 10], [11, 12, 13, 14], [15], []] # remove_states(system, 50.0) assert system.si.statesdm == [[0], [1, 2, 3, 4], [5, 6, 7, 8], [], [], []] use_all_states(system) assert system.si.statesdm == [[0], [1, 2, 3, 4], [5, 6, 7, 8, 9, 10], [11, 12, 13, 14], [15], []]
def test_sort_eigenstates(): p = Parameters_double_dot_spinful() system = qmeq.Builder(p.nsingle, p.hsingle, p.coulomb, p.nleads, p.tleads, p.mulst, p.tlst, p.dlst, indexing='ssq') system.solve(masterq=False) # Sort by energy system.sort_eigenstates([0,1,2,3]) inds = system.si.states_order.tolist() assert inds == [1, 3, 6, 0, 5, 9, 10, 2, 4, 7, 8, 11, 13, 12, 14, 15] assert system.Ea[inds].tolist() == np.sort(system.Ea).tolist() # Sort by charge sort_eigenstates(system, [1,2,3,0]) inds = system.si.states_order.tolist() assert inds == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] assert system.Ea[inds].tolist() == system.Ea.tolist()
(0, 0): t0, # L, up <-- up (1, 0): t0, # R, up <-- up (2, 1): t0, # L, down <-- down (3, 1): t0 } # R, down <-- down # lead label, lead spin <-- level spin nleads = 4 # L,up R,up L,down R,down mulst = {0: vbias / 2, 1: -vbias / 2, 2: vbias / 2, 3: -vbias / 2} tlst = {0: temp, 1: temp, 2: temp, 3: temp} kpnt = np.power(2, 12) system2vN = qmeq.Builder(nsingle, hsingle, coulomb, nleads, tleads, mulst, tlst, dband, kerntype='2vN', kpnt=kpnt) vpnt, vgpnt = 201, 201 vlst = np.linspace(-2 * U, 2 * U, vpnt) vglst = np.linspace(-2.5 * U, 1.5 * U, vgpnt) stab_b_2vN, stab_cond_b_2vN = stab_calc(system2vN, 7.5, vlst, vglst) stab_plot(stab_cond_b_2vN, vlst, vglst, U, gam, '2vN, $B=0.375U$', 'stab2vN.pdf')
# lead label, lead spin <-- level spin nleads = 2 # L,up R,up L,down R,down mulst = {0: vbias/2, 1: -vbias/2} tlst = {0: temp, 1: temp} system = qmeq.Builder(nsingle, hsingle, coulomb, nleads, tleads, mulst, tlst, dband, kerntype='Pauli') system.solve() print('Pauli current:') print(system.current) print(system.energy_current) # The four entries correspond to current in $L\uparrow$, $R\uparrow$, $L\downarrow$, $R\downarrow$ lead channels. We see that the current through left lead and right lead channels is conserved up to numerical errors: # In[12]:
def test_get_charge(): system = qmeq.Builder(4, {}, {}, 0, {}, {}, {}, {}) assert get_charge(system, 10) == 2
# Augment the Hamiltonian to have spin up and down hsingle = np.kron(np.eye(2), hsingle0) #--------------------------------------------------- # Coulomb matrix elements usc = -0.2 coulomb = {(0,2,3,1):usc, (0,3,2,1):usc, (0,7,8,1):usc, (0,8,7,1):usc, (1,2,3,0):usc, (1,3,2,0):usc, (1,7,8,0):usc, (1,8,7,0):usc, (2,5,6,3):usc, (2,6,5,3):usc, (3,5,6,2):usc, (3,6,5,2):usc, (5,7,8,6):usc, (5,8,7,6):usc, (6,7,8,5):usc, (6,8,7,5):usc} #--------------------------------------------------- system = qmeq.Builder(nsingle, hsingle, coulomb, nleads, tleads, mulst, tlst, dband, indexing='ssq', kerntype='Pauli', itype=2) def trace_e3(system, e3lst, removeq=False, dE=150.0): print(system.kerntype) e3pnt = e3lst.shape[0] trace = np.zeros(e3pnt) system.use_all_states() for j1 in range(e3pnt): system.change({(3, 3): e3lst[j1], (8, 8): e3lst[j1]}) system.solve(masterq=False) if removeq: system.remove_states(dE) system.solve(qdq=False) trace[j1] = sum(system.current[np.ix_([0,2])])
def serial_triple_dot_coulomb_symmetry_spin(): # Coulomb matrix elements # Intradot terms: u, uex # Interdot terms: un, udc, usc u, uex, un, udc, usc = 10., 2., 3., -0.5, -0.2 #----------- Spinless ----------- nsingle = 5 dotindex = [0, 0, 1, 1, 2] # m, n, k, l coulomb = [] for m, n, k, l in itertools.product(range(nsingle), repeat=4): if m == n == k == l: coulomb.append([m, m, m, m, u / 2]) # Direct if dotindex[m] == dotindex[k]: if m == n and k == l and m != k: coulomb.append([m, m, k, k, uex / 2]) # Exchange if m != n and k != l: # Intradot if dotindex[m] == dotindex[n]: if m == l and n == k: coulomb.append([m, n, n, m, u / 2]) # Direct if m == k and n == l: coulomb.append([m, n, m, n, uex / 2]) # Exchange # Interdot # Note that the pairs (n,k) and (m,l) are located at different dots if (dotindex[m] == dotindex[l] and dotindex[n] == dotindex[k] and abs(dotindex[m] - dotindex[n]) == 1): if m == l and n == k: coulomb.append([m, n, n, m, un / 2]) # Direct if n == k and m != l: sgn = dotindex[m] - dotindex[n] coulomb.append([m, n, n, l, udc / 2 * sgn]) # Charge-dipole if n != k and m == l: sgn = dotindex[n] - dotindex[m] coulomb.append([m, n, k, m, udc / 2 * sgn]) # Charge-dipole if n != k and m != l: coulomb.append([m, n, k, l, usc / 2]) # Charge-quadrupole coulomb0 = coulomb coulomb1 = { (0, 0, 0, 0): u, (1, 1, 1, 1): u, (2, 2, 2, 2): u, (3, 3, 3, 3): u, (4, 4, 4, 4): u, (0, 1, 1, 0): u, (2, 3, 3, 2): u, # (0, 0, 1, 1): uex, (2, 2, 3, 3): uex, (0, 1, 0, 1): uex, (2, 3, 2, 3): uex, # (0, 2, 2, 0): un, (0, 3, 3, 0): un, (1, 2, 2, 1): un, (1, 3, 3, 1): un, (2, 4, 4, 2): un, (3, 4, 4, 3): un, # (0, 2, 2, 1): -udc, (0, 3, 3, 1): -udc, (2, 4, 4, 3): -udc, (0, 2, 3, 0): +udc, (1, 2, 3, 1): +udc, # (0, 2, 3, 1): usc, (0, 3, 2, 1): usc, # Conjugated terms (1, 1, 0, 0): uex, (3, 3, 2, 2): uex, # (1, 2, 2, 0): -udc, (1, 3, 3, 0): -udc, (3, 4, 4, 2): -udc, (0, 3, 2, 0): +udc, (1, 3, 2, 1): +udc, # (1, 3, 2, 0): usc, (1, 2, 3, 0): usc } coulomb2 = { (0, 0, 0, 0): u, (1, 1, 1, 1): u, (2, 2, 2, 2): u, (3, 3, 3, 3): u, (4, 4, 4, 4): u, (0, 1, 1, 0): u, (2, 3, 3, 2): u, # (0, 0, 1, 1): uex, (2, 2, 3, 3): uex, (0, 1, 0, 1): uex, (2, 3, 2, 3): uex, # (0, 2, 2, 0): un, (0, 3, 3, 0): un, (1, 2, 2, 1): un, (1, 3, 3, 1): un, (2, 4, 4, 2): un, (3, 4, 4, 3): un, # (0, 2, 2, 1): -udc, (0, 3, 3, 1): -udc, (2, 4, 4, 3): -udc, (0, 2, 3, 0): +udc, (1, 2, 3, 1): +udc, # (0, 2, 3, 1): usc, (0, 3, 2, 1): usc } sys0_spinless = qmeq.Builder(nsingle=5, coulomb=coulomb0, symmetry='n', m_less_n=False, herm_c=False) sys0_spinless.solve(masterq=False) sys1_spinless = qmeq.Builder(nsingle=5, coulomb=coulomb1, symmetry='n', m_less_n=True, herm_c=False) sys1_spinless.solve(masterq=False) sys2_spinless = qmeq.Builder(nsingle=5, coulomb=coulomb2, symmetry='n', m_less_n=True, herm_c=True) sys2_spinless.solve(masterq=False) assert sum(abs(sys1_spinless.Ea - sys0_spinless.Ea)) < EPS assert sum(abs(sys2_spinless.Ea - sys0_spinless.Ea)) < EPS #----------- Spinful ----------- nsingle = 10 nssl = nsingle // 2 dotindex = [0, 0, 1, 1, 2, 0, 0, 1, 1, 2] # m, n, k, l coulomb = [] for m, n, k, l in itertools.product(range(nsingle), repeat=4): if m != n and k != l and m // nssl == l // nssl and n // nssl == k // nssl: # Intradot if dotindex[m] == dotindex[n]: if m == l and n == k: coulomb.append([m, n, n, m, u / 2]) # Direct if m == k and n == l: coulomb.append([m, n, m, n, uex / 2]) # Exchange if m + nssl < nsingle: coulomb.append([m, n + nssl, m + nssl, n, uex / 2]) coulomb.append([m + nssl, n, m, n + nssl, uex / 2]) coulomb.append([m, m + nssl, n + nssl, n, uex / 2]) coulomb.append([m + nssl, m, n, n + nssl, uex / 2]) # Interdot # Note that the pairs (n,k) and (m,l) are located at different dots if (dotindex[m] == dotindex[l] and dotindex[n] == dotindex[k] and abs(dotindex[m] - dotindex[n]) == 1): if m == l and n == k: coulomb.append([m, n, n, m, un / 2]) # Direct if n == k and m != l: sgn = dotindex[m] - dotindex[n] coulomb.append([m, n, n, l, udc / 2 * sgn]) # Charge-dipole if n != k and m == l: sgn = dotindex[n] - dotindex[m] coulomb.append([m, n, k, m, udc / 2 * sgn]) # Charge-dipole if n != k and m != l: coulomb.append([m, n, k, l, usc / 2]) # Charge-quadrupole indexing = 'ssq' sys_ref_spinful = qmeq.Builder(nsingle=10, coulomb=coulomb, indexing=indexing) sys_ref_spinful.solve(masterq=False) sys0_spinful = qmeq.Builder(nsingle=10, coulomb=coulomb0, symmetry='spin', m_less_n=False, indexing=indexing) sys0_spinful.solve(masterq=False) sys1_spinful = qmeq.Builder(nsingle=10, coulomb=coulomb1, symmetry='spin', m_less_n=True, herm_c=False, indexing=indexing) sys1_spinful.solve(masterq=False) sys2_spinful = qmeq.Builder(nsingle=10, coulomb=coulomb2, symmetry='spin', m_less_n=True, herm_c=True, indexing=indexing) sys2_spinful.solve(masterq=False) assert sum(abs(sys0_spinful.Ea - sys_ref_spinful.Ea)) < 10 * EPS assert sum(abs(sys1_spinful.Ea - sys_ref_spinful.Ea)) < 10 * EPS assert sum(abs(sys2_spinful.Ea - sys_ref_spinful.Ea)) < 10 * EPS
0: -vbiasL, 1: -vbiasR, 2: -vbiasL, 3: -vbiasR, 4: -vbiasL, 5: -vbiasR, 6: -vbiasL, 7: -vbiasR } tlst = {0: temp, 1: temp, 2: temp, 3: temp, 4: temp, 5: temp, 6: temp, 7: temp} system = qmeq.Builder(nsingle, hsingle, coulomb, nleads, tleads, mulst, tlst, dband, kerntype='Lindblad') # Here we have chosen to use **Pauli master equation** (*kerntype='Pauli'*) to describe the stationary state. Let's calculate the current through the system: # In[11]: #system.solve() #print('Current:') #print(system.current) #print(system.energy_current) # The four entries correspond to current in $L\uparrow$, $R\uparrow$, $L\downarrow$, $R\downarrow$ lead channels. We see that the current through left lead and right lead channels is conserved up to numerical errors:
hsingle = {(0,0): vgate, (1,1): vgate, (0,1): omega} coulomb = {(0,1,1,0): U} tleads = {(0,0): t0, # L <-- l (1,1): t0} # R <-- r nleads = 2 # L R mulst = {0: vbias/2, 1: -vbias/2} tlst = {0: temp, 1: temp} system = qmeq.Builder(nsingle, hsingle, coulomb, nleads, tleads, mulst, tlst, dband) #--------------------------------------------------- def omega_vg(system, olst, vglst): opnt, vgpnt = olst.shape[0], vglst.shape[0] mtr = np.zeros((opnt, vgpnt), dtype=float) for j1 in range(opnt): system.change(hsingle={(0,1):olst[j1]}) for j2 in range(vgpnt): system.change(hsingle={(0,0):vglst[j2], (1,1):vglst[j2]}) system.solve() mtr[j1, j2] = system.current[0] return mtr