def test_CouplingModel(): for bc in ['open', 'periodic']: M = model.CouplingModel(spin_half_lat, bc) M.add_coupling(1.2, 0, 'Sz', 0, 'Sz', 1) M.test_sanity() M = model.CouplingModel(fermion_lat, bc) M.add_coupling(1.2, 0, 'Cd', 0, 'C', 1, 'JW') M.test_sanity()
def test_ext_flux(): Lx, Ly = 3, 4 lat = lattice.Square(Lx, Ly, fermion_site, bc=['periodic', 'periodic'], bc_MPS='infinite') M = model.CouplingModel(lat) strength = 1.23 strength_array = np.ones((Lx, Ly)) * strength for phi in [0, 2 * np.pi]: # flux shouldn't do anything print("phi = ", phi) for dx in [1, 0], [0, 1], [0, 2], [1, -1], [-2, 2]: print("dx = ", dx) strength_flux = M.coupling_strength_add_ext_flux(strength, [1, 0], [0, phi]) npt.assert_array_almost_equal_nulp(strength_flux, strength_array, 10) for phi in [np.pi / 2, 0.123]: print("phi = ", phi) strength_hop_x = M.coupling_strength_add_ext_flux(strength, [1, 0], [0, phi]) npt.assert_array_almost_equal_nulp(strength_hop_x, strength_array, 10) expect_y_1 = np.array(strength_array, dtype=np.complex128) expect_y_1[:, -1:] = strength * np.exp(1.j * phi) for dx in [[0, 1], [0, -1], [1, -1], [1, 1]]: print("dx = ", dx) strength_hop_y_1 = M.coupling_strength_add_ext_flux(strength, dx, [0, phi]) if dx[1] < 0: npt.assert_array_almost_equal_nulp(strength_hop_y_1, expect_y_1, 10) else: npt.assert_array_almost_equal_nulp(strength_hop_y_1, np.conj(expect_y_1), 10) expect_y_2 = np.array(strength_array, dtype=np.complex128) expect_y_2[:, -2:] = strength * np.exp(1.j * phi) for dx in [[0, 2], [0, -2], [1, 2], [3, 2]]: print("dx = ", dx) strength_hop_y_2 = M.coupling_strength_add_ext_flux(strength, dx, [0, phi]) if dx[1] < 0: npt.assert_array_almost_equal_nulp(strength_hop_y_2, expect_y_2, 10) else: npt.assert_array_almost_equal_nulp(strength_hop_y_2, np.conj(expect_y_2), 10)
def test_CouplingModel_multi_couplings_explicit(use_plus_hc, JW): fermion_lat_cyl = lattice.Square(1, 2, fermion_site, bc='periodic', bc_MPS='infinite') M = model.CouplingModel(fermion_lat_cyl) # create a wired fermionic model with 3-body interactions M.add_onsite(0.125, 0, 'N') M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1), plus_hc=use_plus_hc) M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), JW, plus_hc=use_plus_hc) if not use_plus_hc: M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), JW) M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), JW) # multi_coupling with a full unit cell inbetween the operators! M.add_multi_coupling(4., [('N', (0, 0), 0), ('N', (-2, -1), 0)]) # some wired mediated hopping along the diagonal M.add_multi_coupling(1.125, [('N', (0, 0), 0), ('Cd', (0, 1), 0), ('C', (1, 0), 0)]) H_mpo = M.calc_H_MPO() W0_new = H_mpo.get_W(0) W1_new = H_mpo.get_W(1) Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N Cd, C = fermion_site.Cd, fermion_site.C CdJW = Cd.matvec(JW) # = Cd CJW = C.matvec(JW) # = -C NJW = N.matvec(JW) # print(M.H_MPO_graph._build_grids()) # yapf: disable W0_ex = [[Id, CJW, CdJW, None, N, None, None, None, None, None, N*0.125], [None, None, None, None, None, None, None, None, None, None, Cd*-1.5], [None, None, None, None, None, None, None, None, None, None, C*1.5], [None, None, None, JW, None, None, None, None, None, None, None], [None, None, None, None, None, Id, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None, C*1.125], [None, None, None, None, None, None, Id, None, None, None, None], [None, None, None, None, None, None, None, JW, None, None, None], [None, None, None, None, None, None, None, None, JW, None, None], [None, None, None, None, None, None, None, None, None, Id, None], [None, None, None, None, None, None, None, None, None, None, N*4.0], [None, None, None, None, None, None, None, None, None, None, Id]] W1_ex = [[Id, None, None, None, None, None, None, CJW, CdJW, N, None, N*0.125], [None, JW, None, None, None, None, None, None, None, None, None, Cd*-0.5], [None, None, JW, NJW, None, None, None, None, None, None, None, C*0.5], [None, None, None, None, None, None, None, None, None, None, None, C*1.125], [None, None, None, None, Id, CdJW, None, None, None, None, None, None], [None, None, None, None, None, None, Id, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None, None, N*4.0], [None, None, None, None, None, None, None, None, None, None, None, Cd*-1.5], [None, None, None, None, None, None, None, None, None, None, None, C*1.5], [None, None, None, None, None, None, None, None, None, None, Id, None], [None, None, None, None, None, None, None, None, None, None, None, Id]] # yapf: enable W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2]) W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2]) assert npc.norm(W0_new - W0_ex) == 0. # coupling constants: no rounding errors assert npc.norm(W1_new - W1_ex) == 0. # coupling constants: no rounding errors
def test_CouplingModel_fermions(): for bc, bc_MPS in zip(['open', 'periodic'], ['finite', 'infinite']): fermion_lat = lattice.Chain(5, fermion_site, bc=bc, bc_MPS=bc_MPS) M = model.CouplingModel(fermion_lat) M.add_coupling(1.2, 0, 'Cd', 0, 'C', 1, 'JW') M.add_coupling(1.2, 0, 'Cd', 0, 'C', -1, 'JW') M.test_sanity() M.calc_H_MPO() M.calc_H_bond()
def test_CouplingModel(): for bc in ['open', 'periodic']: spin_half_lat = lattice.Chain(5, spin_half_site, bc=bc, bc_MPS='finite') M = model.CouplingModel(spin_half_lat) M.add_coupling(1.2, 0, 'Sz', 0, 'Sz', 1) M.test_sanity() M.calc_H_MPO() if bc == 'periodic': with pytest.raises(ValueError, match="nearest neighbor"): M.calc_H_bond() # should raise a ValueError # periodic bc but finite bc_MPS leads to a long-range coupling else: M.calc_H_bond()
def test_CouplingModel(): spin_half_lat = lattice.Chain(5, spin_half_site, bc_MPS='finite') for bc in ['open', 'periodic']: M = model.CouplingModel(spin_half_lat, bc) M.add_coupling(1.2, 0, 'Sz', 0, 'Sz', 1) M.test_sanity() M.calc_H_MPO() if bc == 'periodic': with nose.tools.assert_raises(ValueError): M.calc_H_bond() # should raise a ValueError # periodic bc but finite bc_MPS leads to a long-range coupling else: M.calc_H_bond()
def test_CouplingModel_explicit(): fermion_lat_cyl = lattice.Square(1, 2, fermion_site, bc='periodic', bc_MPS='infinite') M = model.CouplingModel(fermion_lat_cyl) M.add_onsite(0.125, 0, 'N') M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1), None) # auto-determine JW-string! M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), None) M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), None) M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), None) M.add_coupling(4., 0, 'N', 0, 'N', (-2, -1), None) # a full unit cell inbetween! H_mpo = M.calc_H_MPO() W0_new = H_mpo.get_W(0) W1_new = H_mpo.get_W(1) Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N Cd, C = fermion_site.Cd, fermion_site.C CdJW = Cd.matvec(JW) # = Cd CJW = C.matvec(JW) # = -C # yapf: disable W0_ex = [[Id, CJW, CdJW, N, None, None, None, None, None, N*0.125], [None, None, None, None, None, None, None, None, None, Cd*-1.5], [None, None, None, None, None, None, None, None, None, C*1.5], [None, None, None, None, Id, None, None, None, None, None], [None, None, None, None, None, Id, None, None, None, None], [None, None, None, None, None, None, JW, None, None, None], [None, None, None, None, None, None, None, JW, None, None], [None, None, None, None, None, None, None, None, Id, None], [None, None, None, None, None, None, None, None, None, N*4.0], [None, None, None, None, None, None, None, None, None, Id]] W1_ex = [[Id, None, None, None, None, CJW, CdJW, N, None, N*0.125], [None, JW, None, None, None, None, None, None, None, Cd*-0.5], [None, None, JW, None, None, None, None, None, None, C*0.5], [None, None, None, Id, None, None, None, None, None, None], [None, None, None, None, Id, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, N*4.0], [None, None, None, None, None, None, None, None, None, Cd*-1.5], [None, None, None, None, None, None, None, None, None, C*1.5], [None, None, None, None, None, None, None, None, Id, None], [None, None, None, None, None, None, None, None, None, Id]] # yapf: enable W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2]) W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2]) assert npc.norm(W0_new - W0_ex) == 0. # coupling constants: no rounding errors assert npc.norm(W1_new - W1_ex) == 0. # coupling constants: no rounding errors
def test_CouplingModel_explicit(): fermion_lat_cyl = lattice.SquareLattice(1, 2, fermion_site, bc_MPS='infinite') M = model.CouplingModel(fermion_lat_cyl, 'periodic') M.add_onsite(0.125, 0, 'N') M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1), 'JW') M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), 'JW') M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), 'JW') M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), 'JW') M.add_coupling(4., 0, 'N', 0, 'N', (2, 1), 'Id') # a full unit cell inbetween! H_mpo = M.calc_H_MPO() # MPO should be translation invariant! W0_new = H_mpo.get_W(0) W1_new = H_mpo.get_W(1) Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N Cd, C = fermion_site.Cd, fermion_site.C CdJW = Cd.matvec(JW) JWC = JW.matvec(C) # yapf: disable W0_ex = [[Id, None, None, CdJW, JWC, N, None, None, None, N*0.125], [None, None, Id, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, N*4.0], [None, None, None, None, None, None, None, None, None, C*1.5], [None, None, None, None, None, None, None, None, None, Cd*1.5], [None, Id, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, JW, None, None, None], [None, None, None, None, None, None, None, JW, None, None], [None, None, None, None, None, None, None, None, Id, None], [None, None, None, None, None, None, None, None, None, Id]] W1_ex = [[Id, None, None, None, None, None, CdJW, JWC, N, N*0.125], [None, Id, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, N*4.0], [None, None, None, JW, None, None, None, None, None, C*0.5], [None, None, None, None, JW, None, None, None, None, Cd*0.5], [None, None, None, None, None, Id, None, None, None, None], [None, None, None, None, None, None, None, None, None, C*1.5], [None, None, None, None, None, None, None, None, None, Cd*1.5], [None, None, Id, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, Id]] # yapf: enable W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2]) W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2]) assert npc.norm(W0_new - W0_ex) == 0. # coupling constants: no rounding errors assert npc.norm(W1_new - W1_ex) == 0. # coupling constants: no rounding errors
def test_CouplingModel_shift(Lx=3, Ly=3, shift=1): bc = ['periodic', shift] spin_half_square = lattice.Square(Lx, Ly, spin_half_site, bc=bc, bc_MPS='infinite') M = model.CouplingModel(spin_half_square) M.add_coupling(1.2, 0, 'Sz', 0, 'Sz', [1, 0]) M.add_multi_coupling(0.8, [('Sz', [0, 0], 0), ('Sz', [0, 1], 0), ('Sz', [1, 0], 0)]) M.test_sanity() H = M.calc_H_MPO() dims = [W.shape[0] for W in H._W] # check translation invariance of the MPO: at least the dimensions should fit # (the states are differently ordered, so the matrices differ!) for i in range(1, Lx): assert dims[:Lx] == dims[i * Lx:(i + 1) * Lx]
def test_CouplingModel_multi_couplings_explicit(use_plus_hc, JW): fermion_lat_cyl = lattice.Square(1, 2, fermion_site, bc='periodic', bc_MPS='infinite') M = model.CouplingModel(fermion_lat_cyl) # create a weird fermionic model with 3-body interactions M.add_onsite(0.125, 0, 'N') M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1), plus_hc=use_plus_hc) M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), JW, plus_hc=use_plus_hc) if not use_plus_hc: M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), JW) M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), JW) # multi_coupling with a full unit cell inbetween the operators! M.add_multi_coupling(4., [('N', (0, 0), 0), ('N', (-2, -1), 0)]) # some weird mediated hopping along the diagonal M.add_multi_coupling(1.125, [('N', (0, 0), 0), ('Cd', (0, 1), 0), ('C', (1, 0), 0)]) H_mpo = M.calc_H_MPO() W0_new = H_mpo.get_W(0) W1_new = H_mpo.get_W(1) Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N Cd, C = fermion_site.Cd, fermion_site.C CdJW = Cd.matvec(JW) # = Cd JWC = JW.matvec(C) # = C NJW = N.matvec(JW) # yapf: disable H_MPO_graph = tenpy.networks.mpo.MPOGraph.from_terms((M.all_onsite_terms(), M.all_coupling_terms(), M.exp_decaying_terms), M.lat.mps_sites(), M.lat.bc_MPS) H_MPO_graph._set_ordered_states() from pprint import pprint pprint(H_MPO_graph._ordered_states) pprint(H_MPO_graph._build_grids()) print(M.all_coupling_terms().to_TermList()) # 0.50000 * Cd JW_0 C_1 + # 1.50000 * Cd JW_0 C_2 + # 0.50000 * JW C_0 Cd_1 + # 1.50000 * JW C_0 Cd_2 + # 1.50000 * Cd JW_1 C_3 + # 1.50000 * JW C_1 Cd_3 + # 4.00000 * N_0 N_5 + # 4.00000 * N_1 N_4 + # 1.12500 * N_0 Cd JW_1 C_2 + # 1.12500 * Cd JW_0 N JW_1 C_3 W0_ex = [[Id, CdJW, JWC, N, None, None, None, None, None, N*0.125], [None, None, None, None, None, Id, None, None, None, None], [None, None, None, None, None, None, JW*1.5, None, None, None], [None, None, None, None, None, None, None, JW*1.5, None, None], [None, None, None, None, Id, None, None, None, None, None], [None, None, None, None, None, None, JW*1.125, None, None, None], [None, None, None, None, None, None, None, None, None, C], [None, None, None, None, None, None, None, None, None, Cd], [None, None, None, None, None, None, None, None, None, N], [None, None, None, None, None, None, None, None, Id, None], [None, None, None, None, None, None, None, None, None, Id]] W1_ex = [[Id, None, CdJW, JWC, N, None, None, None, None, None, N*0.125], [None, None, None, None, None, NJW, JW*1.5, None, None, None, C*0.5], [None, None, None, None, None, None, None, JW*1.5, None, None, Cd*0.5], [None, Id, None, None, None, None, CdJW*1.125, None, None, None, None], [None, None, None, None, None, None, None, None, Id*4., None, None], [None, None, None, None, None, None, None, None, None, Id*4., None], [None, None, None, None, None, None, None, None, None, None, C], [None, None, None, None, None, None, None, None, None, None, Cd], [None, None, None, None, None, None, None, None, None, None, N], [None, None, None, None, None, None, None, None, None, None, Id]] # yapf: enable W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2]) assert npc.norm(W0_new - W0_ex) == 0. # coupling constants: no rounding errors W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2]) assert npc.norm(W1_new - W1_ex) == 0. # coupling constants: no rounding errors
def test_CouplingModel_explicit(): fermion_lat_cyl = lattice.Square(1, 2, fermion_site, bc='periodic', bc_MPS='infinite') M = model.CouplingModel(fermion_lat_cyl) M.add_onsite(0.125, 0, 'N') M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1), None) # auto-determine JW-string! M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), None) M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), None) M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), None) M.add_coupling(4., 0, 'N', 0, 'N', (-2, -1), None) # a full unit cell inbetween! H_mpo = M.calc_H_MPO() W0_new = H_mpo.get_W(0) W1_new = H_mpo.get_W(1) Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N Cd, C = fermion_site.Cd, fermion_site.C CdJW = Cd.matvec(JW) # = Cd JWC = JW.matvec(C) # = C # H_MPO_graph = tenpy.networks.mpo.MPOGraph.from_terms((M.all_onsite_terms(), # M.all_coupling_terms(), # M.exp_decaying_terms), # M.lat.mps_sites(), # M.lat.bc_MPS) # H_MPO_graph._set_ordered_states() # from pprint import pprint # pprint(H_MPO_graph._ordered_states) # print(M.all_coupling_terms().to_TermList()) # [{'IdL': 0, # ('left', 0, 'Cd JW', 'JW'): 1, # ('left', 0, 'JW C', 'JW'): 2, # ('left', 0, 'N', 'Id'): 3, # ('left', 1, 'Cd JW', 'JW'): 4, # ('left', 1, 'JW C', 'JW'): 5, # ('left', 1, 'N', 'Id'): 6, # ('left', 0, 'N', 'Id', 2, 'Id', 'Id'): 7, # ('left', 1, 'N', 'Id', 3, 'Id', 'Id'): 8}, # 'IdR': 9, # {'IdL': 0, # ('left', 0, 'Cd JW', 'JW'): 1, # ('left', 0, 'JW C', 'JW'): 2, # ('left', 0, 'N', 'Id'): 3, # ('left', 1, 'Cd JW', 'JW'): 4, # ('left', 1, 'JW C', 'JW'): 5, # ('left', 1, 'N', 'Id'): 6}, # ('left', 0, 'N', 'Id', 2, 'Id', 'Id'): 7, # ('left', 0, 'N', 'Id', 2, 'Id', 'Id', 4, 'Id', 'Id'): 8, # 'IdR': 9, # 0.50000 * Cd JW_0 C_1 + # 1.50000 * Cd JW_0 C_2 + # 0.50000 * JW C_0 Cd_1 + # 1.50000 * JW C_0 Cd_2 + # 4.00000 * N_0 N_5 + # 1.50000 * Cd JW_1 C_3 + # 1.50000 * JW C_1 Cd_3 + # 4.00000 * N_1 N_4 # yapf: disable W0_ex = [[Id, CdJW, JWC, N, None, None, None, None, None, N*0.125], [None, None, None, None, None, None, None, None, None, C*1.5], [None, None, None, None, None, None, None, None, None, Cd*1.5], [None, None, None, None, None, None, None, Id, None, None], [None, None, None, None, JW, None, None, None, None, None], [None, None, None, None, None, JW, None, None, None, None], [None, None, None, None, None, None, Id, None, None, None], [None, None, None, None, None, None, None, None, Id, None], [None, None, None, None, None, None, None, None, None, N*4.0], [None, None, None, None, None, None, None, None, None, Id]] W1_ex = [[Id, None, None, None, CdJW, JWC, N, None, None, N*0.125], [None, JW, None, None, None, None, None, None, None, C*0.5], [None, None, JW, None, None, None, None, None, None, Cd*0.5], [None, None, None, Id, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, C*1.5], [None, None, None, None, None, None, None, None, None, Cd*1.5], [None, None, None, None, None, None, None, None, Id, None], [None, None, None, None, None, None, None, Id, None, None], [None, None, None, None, None, None, None, None, None, N*4.0], [None, None, None, None, None, None, None, None, None, Id]] # yapf: enable W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2]) W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2]) assert npc.norm(W0_new - W0_ex)**2 == 0. # coupling constants: no rounding errors assert npc.norm(W1_new - W1_ex)**2 == 0. # coupling constants: no rounding errors