Ejemplo n.º 1
0
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()
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
    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())
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
    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()

# -------------------------------------------------------
Ejemplo n.º 10
0
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