def test_unequal_orbital_number(): model = tbmodels.Model(pos=[[0., 0.], [0.5, 0.5], [0.5, 0.5]], on_site=[1, 0.7, -1.2]) t1 = 0.1 t2 = 0.15 t3 = 0.4 for phase, R in zip([1, -1j, 1j, -1], itertools.product([0, -1], [0, -1])): model.add_hop(t1 * phase, 0, 1, R) model.add_hop(t3 * phase, 1, 2, R) for R in ((r[0], r[1]) for r in itertools.permutations([0, 1])): model.add_hop(t2, 0, 0, R) model.add_hop(-t2, 1, 1, R) model.add_hop(-t2, 2, 2, R) latt = model.to_kwant_lattice() sym = kwant.TranslationalSymmetry(latt.vec((1, 0)), latt.vec((0, 1))) sys = kwant.Builder(sym) sys[latt.shape(lambda p: True, (0, 0))] = 0 model.add_hoppings_kwant(sys) sys = wraparound.wraparound(sys).finalized() for k in KPT: k = k[:2] k_kwant = tuple(np.array(k) * 2 * np.pi) np.testing.assert_allclose(model.eigenval(k), la.eigvalsh( sys.hamiltonian_submatrix(k_kwant)), atol=1e-8)
def make_system(): sys = kwant.Builder(kwant.TranslationalSymmetry(graphene.vec((-Y/2,Y)))) sys[graphene.shape(disk,(0, 0))] = onsite sys[graphene.neighbors(1)] = hopping1 sys[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings]] = nnn_hopping sys = wraparound.wraparound(sys) #kwant.plot(sys, fig_size=(10, 5)) lead = kwant.Builder(kwant.TranslationalSymmetry((1, 0), graphene.vec((-Y/2,Y)))) lead[graphene.shape(disk,(0, 0))] = onsite_clean lead[graphene.neighbors(1)] = hopping1 lead[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings]] = nnn_hopping lead = wraparound.wraparound(lead, keep=0) sys.attach_lead(lead) sys.attach_lead(lead.reversed()) return sys.finalized()
def make_system(length, salt): def onsite(site): return (uniform(repr(site), salt) - 0.5) * 2.5 sys = kwant.Builder( kwant.TranslationalSymmetry( *graphene.prim_vecs * length)) #kwant.TranslationalSymmetry(*graphene.prim_vecs*20) sys[graphene.shape((lambda pos: True), (0, 0))] = onsite sys[graphene.neighbors(1)] = -1 sys[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings]] = .1j sys = wraparound(sys).finalized() return sys
def test_simple(t, get_model): model = get_model(*t) latt = model.to_kwant_lattice() sym = kwant.TranslationalSymmetry(latt.vec((1, 0, 0)), latt.vec((0, 1, 0)), latt.vec((0, 0, 1))) sys = kwant.Builder(sym) sys[latt.shape(lambda p: True, (0, 0, 0))] = 0 model.add_hoppings_kwant(sys) sys = wraparound.wraparound(sys).finalized() # the Hamiltonian doesn't match because the sites might be re-ordered -> test eigenval instead for k in KPT: k_kwant = tuple(np.array(k) * 2 * np.pi) np.testing.assert_allclose(model.eigenval(k), la.eigvalsh( sys.hamiltonian_submatrix(k_kwant)), atol=1e-8)
def test_realistic(compare_data, hr_name): hr_file = join(SAMPLES_DIR, hr_name) model = tbmodels.Model.from_hr_file(hr_file, occ=28) latt = model.to_kwant_lattice() sym = kwant.TranslationalSymmetry( latt.vec((1, 0, 0)), latt.vec((0, 1, 0)), latt.vec((0, 0, 1)) ) sys = kwant.Builder(sym) sys[latt.shape(lambda p: True, (0, 0, 0))] = 0 model.add_hoppings_kwant(sys) sys = wraparound.wraparound(sys).finalized() # don't split into separate tests because it takes too long # since there is only one 'site' we can also test the Hamiltonian for k in KPT: k_kwant = tuple(np.array(k) * 2 * np.pi) np.testing.assert_allclose(model.eigenval(k), la.eigvalsh(sys.hamiltonian_submatrix(k_kwant)), atol=1e-8) np.testing.assert_allclose(model.hamilton(k), sys.hamiltonian_submatrix(k_kwant), atol=1e-8)
fig = pyplot.figure() axes = fig.add_subplot(1, 1, 1, projection='3d') for band in range(energies.shape[-1]): axes.plot_surface(kx, ky, energies[:, :, band], cstride=2, rstride=2, cmap=matplotlib.cm.RdBu_r, vmin=emin, vmax=emax, linewidth=0.1) l = 1 lat = kwant.lattice.square() bulk_graphene = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs)) bulk_graphene[lat.shape((lambda pos: True), (0, 0))] = 4 bulk_graphene[lat.neighbors()] = -1 #bulk_graphene[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings]] = -0j #kwant.plot(bulk_graphene) dispersion_2D(wraparound(bulk_graphene).finalized()) #zigzag_haldane = kwant.Builder(kwant.TranslationalSymmetry([l, 0])) #zigzag_haldane[graphene.shape((lambda pos: abs(pos[1]) < 20), (0, 0))] = onsite #zigzag_haldane[graphene.neighbors(1)] = 1 #zigzag_haldane[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings]] = 0.5j # #kwant.plotter.bands(zigzag_haldane.finalized())
def hamiltonian_array(sys, p=None, k_x=0, k_y=0, k_z=0, return_grid=False): """Evaluate the Hamiltonian of a system over a grid of parameters. Parameters: ----------- sys : kwant.Builder object The un-finalized kwant system whose Hamiltonian is calculated. p : SimpleNamespace object A container of Hamiltonian parameters. The parameters that are sequences are used to loop over. k_x, k_y, k_z : floats or sequences of floats Momenta at which the Hamiltonian has to be evaluated. If the system only has 1 translation symmetry, only `k_x` is used, and interpreted as lattice momentum. Otherwise the momenta are in reciprocal space. return_grid : bool Whether to also return the names of the variables used for expansion, and their values. Returns: -------- hamiltonians : numpy.ndarray An array with the Hamiltonians. The first n-2 dimensions correspond to the expanded variables. parameters : list of tuples Names and ranges of values that were used in evaluation of the Hamiltonians. Examples: --------- >>> hamiltonian_array(sys, SimpleNamespace(t=1, mu=np.linspace(-2, 2)), ... k_x=np.linspace(-np.pi, np.pi)) >>> hamiltonian_array(sys_2d, p, np.linspace(-np.pi, np.pi), ... np.linspace(-np.pi, np.pi)) """ if p is None: p = SimpleNamespace() try: space_dimensionality = sys.symmetry.periods.shape[-1] except AttributeError: space_dimensionality = 0 dimensionality = sys.symmetry.num_directions pars = copy(p) if dimensionality == 0: sys = sys.finalized() def momentum_to_lattice(k): return [] else: if len(sys.symmetry.periods) == 1: def momentum_to_lattice(k): if any(k[dimensionality:]): raise ValueError( "Dispersion is 1D, but more momenta are provided.") return [k[0]] else: B = np.array(sys.symmetry.periods).T A = B.dot(np.linalg.inv(B.T.dot(B))) def momentum_to_lattice(k): k, residuals = np.linalg.lstsq(A, k[:space_dimensionality])[:2] if np.any(abs(residuals) > 1e-7): raise RuntimeError("Requested momentum doesn't correspond" " to any lattice momentum.") return list(k) sys = wraparound(sys).finalized() changing = dict() for key, value in pars.__dict__.items(): if isinstance(value, collections.Iterable): changing[key] = value for key, value in [('k_x', k_x), ('k_y', k_y), ('k_z', k_z)]: if key in changing: raise RuntimeError('One of the system parameters is {}, ' 'which is reserved for momentum. ' 'Please rename it.'.format(key)) if isinstance(value, collections.Iterable): changing[key] = value if not changing: hamiltonians = sys.hamiltonian_submatrix( [pars] + momentum_to_lattice([k_x, k_y, k_z]), sparse=False)[None, ...] if return_grid: return hamiltonians, [] else: return hamiltonians def hamiltonian(**values): pars.__dict__.update(values) k = [ values.get('k_x', k_x), values.get('k_y', k_y), values.get('k_z', k_z) ] k = momentum_to_lattice(k) return sys.hamiltonian_submatrix(args=([pars] + k), sparse=False) names, values = zip(*sorted(changing.items())) hamiltonians = [ hamiltonian(**dict(zip(names, value))) for value in itertools.product(*values) ] size = list(hamiltonians[0].shape) hamiltonians = np.array(hamiltonians).reshape( [len(value) for value in values] + size) if return_grid: return hamiltonians, list(zip(names, values)) else: return hamiltonians
B = np.array(graphene.prim_vecs).T A = B.dot(np.linalg.inv(B.T.dot(B))) return np.linalg.solve(A, k) def onsite(site): return (uniform(repr(site), salt) - 0.5) * 2 sys = kwant.Builder(kwant.TranslationalSymmetry( *graphene.prim_vecs * length)) #kwant.TranslationalSymmetry(*graphene.prim_vecs*20) sys[graphene.shape((lambda pos: True), (0, 0))] = onsite sys[graphene.neighbors(1)] = -1 sys[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings]] = .2j sys = wraparound(sys).finalized() #kwant.plot(sys, fig_size=(10, 5)) lattice_k = momentum_to_lattice([0, 0]) ham_mat = sys.hamiltonian_submatrix(args=(list(lattice_k))) ##vals,evecs= sla.eigsh(ham_mat, k=1,sigma=None,return_eigenvectors=True) #,evecs vals, evecs = LA.eigh(ham_mat) #kwant.plotter.map(sys, np.abs(evecs[:, 100])**2,colorbar=False, oversampling=1) #vals,evecs=scipy.sparse.linalg.eigs(ham_mat, k=length**2, M=None, which='SR') p = [] for i in range(2 * length**2): p.append(sys.pos(i)) p = np.array(p)
a = 0.03 V0 = 0.0 W = 20 L = 50 t = hbar**2 / (2 * me * a**2) # units: eV lat = kwant.lattice.square(a) # Infinite potential plane in y direction sys = kwant.Builder(kwant.TranslationalSymmetry(lat.vec((0, W)))) sys[(lat(i, j) for i in range(L) for j in range(W))] = lambda p: 4 * t sys[lat.neighbors(1)] = -t sys = wraparound.wraparound(sys) lead = kwant.Builder(kwant.TranslationalSymmetry((-a, 0), lat.vec((0, W)))) lead[(lat(0, j) for j in range(W))] = 4 * t lead[lat.neighbors(1)] = -t lead = wraparound.wraparound(lead, keep=0) sys.attach_lead(lead) sys.attach_lead(lead.reversed()) kwant.plot(sys) sys = sys.finalized() # -------------------------------------------------------
def hamiltonian_array(sys, p=None, k_x=0, k_y=0, k_z=0, return_grid=False): """Evaluate the Hamiltonian of a system over a grid of parameters. Parameters: ----------- sys : kwant.Builder object The un-finalized kwant system whose Hamiltonian is calculated. p : SimpleNamespace object A container of Hamiltonian parameters. The parameters that are sequences are used to loop over. k_x, k_y, k_z : floats or sequences of floats Momenta at which the Hamiltonian has to be evaluated. If the system only has 1 translation symmetry, only `k_x` is used, and interpreted as lattice momentum. Otherwise the momenta are in reciprocal space. return_grid : bool Whether to also return the names of the variables used for expansion, and their values. Returns: -------- hamiltonians : numpy.ndarray An array with the Hamiltonians. The first n-2 dimensions correspond to the expanded variables. parameters : list of tuples Names and ranges of values that were used in evaluation of the Hamiltonians. Examples: --------- >>> hamiltonian_array(sys, SimpleNamespace(t=1, mu=np.linspace(-2, 2)), ... k_x=np.linspace(-np.pi, np.pi)) >>> hamiltonian_array(sys_2d, p, np.linspace(-np.pi, np.pi), ... np.linspace(-np.pi, np.pi)) """ if p is None: p = SimpleNamespace() try: space_dimensionality = sys.symmetry.periods.shape[-1] except AttributeError: space_dimensionality = 0 dimensionality = sys.symmetry.num_directions pars = copy(p) if dimensionality == 0: sys = sys.finalized() def momentum_to_lattice(k): return [] else: if len(sys.symmetry.periods) == 1: def momentum_to_lattice(k): if any(k[dimensionality:]): raise ValueError("Dispersion is 1D, but more momenta are provided.") return [k[0]] else: B = np.array(sys.symmetry.periods).T A = B.dot(np.linalg.inv(B.T.dot(B))) def momentum_to_lattice(k): k, residuals = np.linalg.lstsq(A, k[:space_dimensionality])[:2] if np.any(abs(residuals) > 1e-7): raise RuntimeError("Requested momentum doesn't correspond" " to any lattice momentum.") return list(k) sys = wraparound(sys).finalized() changing = dict() for key, value in pars.__dict__.items(): if isinstance(value, collections.Iterable): changing[key] = value for key, value in [('k_x', k_x), ('k_y', k_y), ('k_z', k_z)]: if key in changing: raise RuntimeError('One of the system parameters is {}, ' 'which is reserved for momentum. ' 'Please rename it.'.format(key)) if isinstance(value, collections.Iterable): changing[key] = value if not changing: hamiltonians = sys.hamiltonian_submatrix([pars] + momentum_to_lattice([k_x, k_y, k_z]), sparse=False)[None, ...] if return_grid: return hamiltonians, [] else: return hamiltonians def hamiltonian(**values): pars.__dict__.update(values) k = [values.get('k_x', k_x), values.get('k_y', k_y), values.get('k_z', k_z)] k = momentum_to_lattice(k) return sys.hamiltonian_submatrix(args=([pars] + k), sparse=False) names, values = zip(*sorted(changing.items())) hamiltonians = [hamiltonian(**dict(zip(names, value))) for value in itertools.product(*values)] size = list(hamiltonians[0].shape) hamiltonians = np.array(hamiltonians).reshape([len(value) for value in values] + size) if return_grid: return hamiltonians, list(zip(names, values)) else: return hamiltonians