Esempio n. 1
0
    def init_func_and_attrs(self, request, siesta_test_files):
        name = request.param

        if name.startswith("siesta_PDOS_file"):

            spin_type = name.split("_")[-1]

            n_spin, filename = {
                "unpolarized": (1, "SrTiO3.PDOS"),
                "polarized": (2, "SrTiO3_polarized.PDOS"),
                "noncollinear": (4, "SrTiO3_noncollinear.PDOS")
            }[spin_type]

            init_func = sisl.get_sile(siesta_test_files(filename)).plot
            attrs = {
                "na": 5,
                "no": 72,
                "n_spin": n_spin,
                "species": ('Sr', 'Ti', 'O')
            }
        elif name.startswith("sisl_H"):
            gr = sisl.geom.graphene()
            H = sisl.Hamiltonian(gr)
            H.construct([(0.1, 1.44), (0, -2.7)])

            spin_type = name.split("_")[-1]

            n_spin, H = {
                "unpolarized": (1, H),
                "polarized": (2, H.transform(spin=sisl.Spin.POLARIZED)),
                "noncolinear": (4, H.transform(spin=sisl.Spin.NONCOLINEAR)),
                "spinorbit": (4, H.transform(spin=sisl.Spin.SPINORBIT))
            }[spin_type]

            init_func = partial(H.plot.pdos, Erange=[-5, 5])
            attrs = {"na": 2, "no": 2, "n_spin": n_spin, "species": ('C', )}
        elif name == "wfsx_file":
            # From a siesta .WFSX file
            # Since there is no hamiltonian for bi2se3_3ql.fdf, we create a dummy one
            wfsx = sisl.get_sile(siesta_test_files("bi2se3_3ql.bands.WFSX"))

            geometry = sisl.get_sile(
                siesta_test_files("bi2se3_3ql.fdf")).read_geometry()
            geometry = sisl.Geometry(geometry.xyz, atoms=wfsx.read_basis())

            H = sisl.Hamiltonian(geometry, dim=4)

            init_func = partial(H.plot.pdos,
                                wfsx_file=wfsx,
                                entry_points_order=["wfsx file"])

            attrs = {"na": 15, "no": 195, "n_spin": 4, "species": ('Bi', 'Se')}

        return init_func, attrs
Esempio n. 2
0
def test_gf_write_read(sisl_tmp, sisl_system):
    tb = sisl.Hamiltonian(sisl_system.gtb)
    f = sisl_tmp('file.TSGF', _dir)

    bz = sisl.MonkhorstPack(tb, [3, 3, 1])
    E = np.linspace(-2, 2, 20) + 1j * 1e-4
    S = np.eye(len(tb), dtype=np.complex128)

    gf = sisl.io.get_sile(f)

    gf.write_header(E, bz, tb)
    for i, (write_hs, k, e) in enumerate(gf):
        Hk = tb.Hk(k, format='array')
        if write_hs and i % 2 == 0:
            gf.write_hamiltonian(Hk)
        elif write_hs:
            gf.write_hamiltonian(Hk, S)
        gf.write_self_energy(S * e - Hk)

    no_u, k, E_file = gf.read_header()
    assert np.allclose(E, E_file)
    assert np.allclose(k, bz.k)

    for i, (write_hs, k, e) in enumerate(gf):
        Hk = tb.Hk(k, format='array')
        if write_hs and i % 2 == 0:
            Hk_file, _ = gf.read_hamiltonian()
        elif write_hs:
            Hk_file, Sk_file = gf.read_hamiltonian()
            assert np.allclose(S, Sk_file)
        assert np.allclose(Hk, Hk_file)

        SE_file = gf.read_self_energy()
        assert np.allclose(SE_file, S * e - Hk)
Esempio n. 3
0
    def init_func_and_attrs(self, request, siesta_test_files):
        name = request.param

        if name.startswith("sisl_H"):
            gr = sisl.geom.graphene()
            H = sisl.Hamiltonian(gr)
            H.construct([(0.1, 1.44), (0, -2.7)])

            spin_type = name.split("_")[-1]
            n_spin, H = {
                "unpolarized": (1, H),
                "polarized": (2, H.transform(spin=sisl.Spin.POLARIZED)),
                "noncolinear": (1, H.transform(spin=sisl.Spin.NONCOLINEAR)),
                "spinorbit": (1, H.transform(spin=sisl.Spin.SPINORBIT))
            }.get(spin_type)

            n_states = 2
            if H.spin.is_spinorbit or H.spin.is_noncolinear:
                n_states *= 2

            # Directly creating a BandStructure object
            bz = sisl.BandStructure(H, [[0, 0, 0], [2/3, 1/3, 0], [1/2, 0, 0]], 6, ["Gamma", "M", "K"])
            init_func = bz.plot.fatbands

            attrs = {
                "bands_shape": (6, n_spin, n_states) if H.spin.is_polarized else (6, n_states),
                "weights_shape": (n_spin, 6, n_states, 2) if H.spin.is_polarized else (6, n_states, 2),
                "ticklabels": ["Gamma", "M", "K"],
                "tickvals": [0., 1.70309799, 2.55464699],
                "gap": 0,
                "spin_texture": not H.spin.is_diagonal,
                "spin": H.spin
            }

        return init_func, attrs
Esempio n. 4
0
    def dispatch(self,
                 t=(-2.414, -0.168),
                 beta=(-1.847, -3.077),
                 a=1.42,
                 orthogonal=False):
        distance = self._obj.distance
        da = 0.0005

        R = (distance(0, a) + da, distance(1, a) + da, distance(2, a) + da)

        def construct(H, ia, atoms, atoms_xyz=None):
            idx_t012, rij_t012 = H.geometry.close(ia,
                                                  R=R,
                                                  atoms=atoms,
                                                  atoms_xyz=atoms_xyz,
                                                  ret_rij=True)
            H[ia, idx_t012[0]] = 0.
            H[ia, idx_t012[1]] = t[0] * np.exp(beta[0] * (rij_t012[1] - R[1]))
            H[ia, idx_t012[2]] = t[1] * np.exp(beta[1] * (rij_t012[2] - R[2]))

        # Define the graphene lattice
        C = si.Atom(6, si.AtomicOrbital(n=2, l=1, m=0, R=R[-1]))
        graphene = si.geom.graphene(a, C, orthogonal=orthogonal)
        # Define the Hamiltonian
        H = si.Hamiltonian(graphene)
        H.construct(construct)
        return H
Esempio n. 5
0
 def dispatch(self, t=-2.7, a=1.42, orthogonal=False):
     # Define the graphene lattice
     da = 0.0005
     C = si.Atom(6, si.AtomicOrbital(n=2, l=1, m=0, R=a + da))
     graphene = si.geom.graphene(a, C, orthogonal=orthogonal)
     # Define the Hamiltonian
     H = si.Hamiltonian(graphene)
     H.construct([(da, a + da), (0, t)])
     return H
Esempio n. 6
0
    def dispatch(self, a=1.42, orthogonal=False):
        distance = self._obj.distance
        da = 0.0005

        R = (distance(0, a) + da, distance(1, a) + da, distance(2, a) + da,
             distance(3, a) + da)
        # Define the graphene lattice
        C = si.Atom(6, si.AtomicOrbital(n=2, l=1, m=0, R=R[-1]))
        graphene = si.geom.graphene(a, C, orthogonal=orthogonal)
        # Define the Hamiltonian
        H = si.Hamiltonian(graphene, orthogonal=False)
        t = [(-0.45, 1), (-2.78, 0.117), (-0.15, 0.004), (-0.095, 0.002)]
        H.construct([R, t])
        return H
Esempio n. 7
0
    def dispatch(self, set='A', a=1.42, orthogonal=False):
        distance = self._obj.distance
        da = 0.0005
        H_orthogonal = True
        #U = 2.0

        R = tuple(distance(i, a) + da for i in range(4))
        if set == 'A':
            # same as simple
            t = (0, -2.7)
            #U = 0.
        elif set == 'B':
            # same as simple
            t = (0, -2.7)
        elif set == 'C':
            t = (0, -2.7, -0.2)
        elif set == 'D':
            t = (0, -2.7, -0.2, -0.18)
        elif set == 'E':
            # same as D, but specific for GNR
            t = (0, -2.7, -0.2, -0.18)
        elif set == 'F':
            # same as D, but specific for GNR
            t = [(0, 1), (-2.7, 0.11), (-0.09, 0.045), (-0.27, 0.065)]
            H_orthogonal = False
        elif set == 'G':
            # same as D, but specific for GNR
            t = [(0, 1), (-2.97, 0.073), (-0.073, 0.018), (-0.33, 0.026)]
            #U = 0.
            H_orthogonal = False
        else:
            raise ValueError(
                f"Set specification for {self.doi} does not exist, should be one of [A-G]"
            )

        # Reduce size of R
        R = R[:len(t)]

        # Currently we do not carry over U, since it is not specified for the
        # sisl objects....

        # Define the graphene lattice
        C = si.Atom(6, si.AtomicOrbital(n=2, l=1, m=0, R=R[-1]))
        graphene = si.geom.graphene(a, C, orthogonal=orthogonal)
        graphene.optimize_nsc([0, 1])
        # Define the Hamiltonian
        H = si.Hamiltonian(graphene, orthogonal=H_orthogonal)
        H.construct([R, t])
        return H
Esempio n. 8
0
def test_tshs_spin_orbit(sisl_tmp):
    H1 = sisl.Hamiltonian(sisl.geom.graphene(), spin=sisl.Spin('SO'))
    H1.construct(([0.1, 1.44], [[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8],
                                [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]]))

    f1 = sisl_tmp('tmp1.TSHS', _dir)
    f2 = sisl_tmp('tmp2.TSHS', _dir)
    H1.write(f1)
    H1.finalize()
    H2 = sisl.get_sile(f1).read_hamiltonian()
    H2.write(f2)
    H3 = sisl.get_sile(f2).read_hamiltonian()
    assert H1._csr.spsame(H2._csr)
    assert np.allclose(H1._csr._D, H2._csr._D)
    assert H1._csr.spsame(H3._csr)
    assert np.allclose(H1._csr._D, H3._csr._D)
Esempio n. 9
0
def test_gf_write(sisl_tmp, sisl_system):
    tb = sisl.Hamiltonian(sisl_system.gtb)
    f = sisl_tmp('file.TSGF', _dir)
    gf = sisl.io.get_sile(f)
    bz = sisl.MonkhorstPack(tb, [3, 3, 1])
    E = np.linspace(-2, 2, 20) + 1j * 1e-4
    S = np.eye(len(tb), dtype=np.complex128)

    gf.write_header(E, bz, tb)
    for i, (write_hs, k, e) in enumerate(gf):
        Hk = tb.Hk(k, format='array')
        if write_hs and i % 2 == 0:
            gf.write_hamiltonian(Hk)
        elif write_hs:
            gf.write_hamiltonian(Hk, S)
        gf.write_self_energy(S * e - Hk)
Esempio n. 10
0
    def get_bond_order(self, format='csr', midgap=0.):
        """ Compute Huckel bond order

        Parameters
        ----------
        format: {'csr', 'array', 'dense', 'coo', ...}
           the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`,
           however if one always requires operations on dense matrices, one can always
           return in `numpy.ndarray` (`'array'`) or `numpy.matrix` (`'dense'`).
        midgap: float, optional
           energy value that separates filled states (lower energy) from empty states (higher energy) 

        Returns
        -------
        the Huckel bond-order matrix object
        """
        g = self.geometry
        BO = sisl.Hamiltonian(g)
        R = [0.1, 1.6]
        for w, k in zip(self.mp.weight, self.mp.k):
            # spin-up first
            ev, evec = self.eigh(k=k, eigvals_only=False, spin=0)
            ev -= midgap
            idx = np.where(ev < 0.)[0]
            bo = np.dot(np.conj(evec[:, idx]), evec[:, idx].T)
            # add spin-down
            ev, evec = self.eigh(k=k, eigvals_only=False, spin=1)
            ev -= midgap
            idx = np.where(ev < 0.)[0]
            bo += np.dot(np.conj(evec[:, idx]), evec[:, idx].T)
            for ix in (-1, 0, 1):
                for iy in (-1, 0, 1):
                    for iz in (-1, 0, 1):
                        r = (ix, iy, iz)
                        phase = np.exp(-2.j * np.pi * np.dot(k, r))
                        for ia in g:
                            for ja in g.close_sc(ia, R=R, isc=r)[1]:
                                bor = bo[ia, ja] * phase
                                BO[ia, ja] += w * bor.real
        # Add sigma bond at the end
        for ia in g:
            idx = g.close(ia, R=R)
            BO[ia, idx[1]] += 1.
        return BO.Hk(format=format)  # Fold to Gamma
Esempio n. 11
0
def test_tshs_missing_diagonal(sisl_tmp):
    H1 = sisl.Hamiltonian(sisl.geom.graphene())
    H1.construct(([0.1, 1.44], [0., -2.7]))
    # remove diagonal component here
    del H1[0, 0]

    f1 = sisl_tmp('tmp1.TSHS', _dir)
    H1.write(f1)

    f2 = sisl_tmp('tmp2.TSHS', _dir)
    H2 = sisl.get_sile(f1).read_hamiltonian()
    H2.write(f2)
    H3 = sisl.get_sile(f2).read_hamiltonian()

    H1.finalize()
    assert not H1._csr.spsame(H2._csr)
    assert H2._csr.spsame(H3._csr)
    assert np.allclose(H2._csr._D, H3._csr._D)
    H1[0, 0] = 0.
    H1.finalize()
    assert H1._csr.spsame(H2._csr)
Esempio n. 12
0
def test_lspgeom_sislconvert():
    Hs = si.Hamiltonian(si.geom.graphene(),
                        orthogonal=True,
                        spin=si.Spin.POLARIZED)
    dim = Hs.dim
    assert dim == 2
    Hs.set_nsc((7, 7, 1))
    Hs.construct([[0.1, 1.5, 3, 5, 9], [-2, 1, 0.1, 0.01, 0.001]])
    Hs = Hs.tile(4, 0).tile(4, 1)
    Hs.finalize()
    LHs = LSpGeom(Hs)

    Hs2 = LHs.tosisl()
    assert all(_allclose_csr(Hs.tocsr(i), Hs2.tocsr(i)) for i in range(dim))
    assert Hs.geometry.equal(Hs2.geometry)

    LHs += LHs * 0.3
    Hs += Hs * 0.3
    Hs2 = LHs.tosisl()
    assert all(_allclose_csr(Hs.tocsr(i), Hs2.tocsr(i)) for i in range(dim))
    assert Hs.geometry.equal(Hs2.geometry)
Esempio n. 13
0
def test_gf_write_read_spin(sisl_tmp, sisl_system):
    f = sisl_tmp('file.TSGF', _dir)

    tb = sisl.Hamiltonian(sisl_system.gtb, spin=sisl.Spin('P'))
    tb.construct([(0.1, 1.5), ([0.1, -0.1], [2.7, 1.6])])

    bz = sisl.MonkhorstPack(tb, [3, 3, 1])
    E = np.linspace(-2, 2, 3) + 1j * 1e-4
    S = np.eye(len(tb), dtype=np.complex128)

    gf = sisl.io.get_sile(f)

    gf.write_header(bz, E)
    for i, (ispin, write_hs, k, e) in enumerate(gf):
        Hk = tb.Hk(k, spin=ispin, format='array')
        if write_hs and i % 2 == 0:
            gf.write_hamiltonian(Hk)
        elif write_hs:
            gf.write_hamiltonian(Hk, S)
        gf.write_self_energy(S * e - Hk)

    # Check it isn't opened
    assert not gf._fortran_is_open()

    nspin, no_u, k, E_file = gf.read_header()
    assert nspin == 2
    assert np.allclose(E, E_file)
    assert np.allclose(k, bz.k)

    for i, (ispin, write_hs, k, e) in enumerate(gf):
        Hk = tb.Hk(k, spin=ispin, format='array')
        if write_hs and i % 2 == 0:
            Hk_file, _ = gf.read_hamiltonian()
        elif write_hs:
            Hk_file, Sk_file = gf.read_hamiltonian()
            assert np.allclose(S, Sk_file)
        assert np.allclose(Hk, Hk_file)

        SE_file = gf.read_self_energy()
        assert np.allclose(SE_file, S * e - Hk)
Esempio n. 14
0
def test_tshs_spin_orbit_tshs2nc2tshs(sisl_tmp):
    H1 = sisl.Hamiltonian(sisl.geom.graphene(), spin=sisl.Spin('SO'))
    H1.construct(([0.1, 1.44], [[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8],
                                [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]]))

    fdf_file = sisl_tmp('RUN.fdf', _dir)
    f1 = sisl_tmp('tmp1.TSHS', _dir)
    f2 = sisl_tmp('tmp1.nc', _dir)
    H1.write(f1)
    H1.finalize()
    H2 = sisl.get_sile(f1).read_hamiltonian()
    H2.write(f2)
    H3 = sisl.get_sile(f2).read_hamiltonian()
    open(fdf_file, 'w').writelines(["SystemLabel tmp1"])
    fdf = sisl.get_sile(fdf_file)
    assert np.allclose(
        fdf.read_supercell(order='nc').cell,
        fdf.read_supercell(order='TSHS').cell)
    assert H1._csr.spsame(H2._csr)
    assert np.allclose(H1._csr._D, H2._csr._D)
    assert H1._csr.spsame(H3._csr)
    assert np.allclose(H1._csr._D, H3._csr._D)
Esempio n. 15
0
    def dispatch(self, t=-2.7, a=1.42, orthogonal=False):
        distance = self._obj.distance
        da = 0.0005

        R = (distance(0, a) + da, distance(1, a) + da)

        def construct(H, ia, atoms, atoms_xyz=None):
            idx_t01, rij_t01 = H.geometry.close(ia,
                                                R=R,
                                                atoms=atoms,
                                                atoms_xyz=atoms_xyz,
                                                ret_rij=True)
            H[ia, idx_t01[0]] = 0.
            H[ia, idx_t01[1]] = t * (a / rij_t01[1])**2

        # Define the graphene lattice
        C = si.Atom(6, si.AtomicOrbital(n=2, l=1, m=0, R=R[-1]))
        graphene = si.geom.graphene(a, C, orthogonal=orthogonal)
        # Define the Hamiltonian
        H = si.Hamiltonian(graphene)
        H.construct(construct)
        return H
Esempio n. 16
0
    def init_func_and_attrs(self, request, siesta_test_files):
        name = request.param

        if name.startswith("siesta_PDOS_file"):

            spin_type = name.split("_")[-1]

            n_spin, filename = {
                "unpolarized": (1, "SrTiO3.PDOS"),
                "polarized": (2, "SrTiO3_polarized.PDOS"),
                "noncollinear": (4, "SrTiO3_noncollinear.PDOS")
            }[spin_type]

            init_func = sisl.get_sile(siesta_test_files(filename)).plot
            attrs = {
                "na": 5,
                "no": 72,
                "n_spin": n_spin,
                "species": ('Sr', 'Ti', 'O')
            }
        elif name.startswith("sisl_H"):
            gr = sisl.geom.graphene()
            H = sisl.Hamiltonian(gr)
            H.construct([(0.1, 1.44), (0, -2.7)])

            spin_type = name.split("_")[-1]

            n_spin, H = {
                "unpolarized": (1, H),
                "polarized": (2, H.transform(spin=sisl.Spin.POLARIZED)),
                "noncolinear": (4, H.transform(spin=sisl.Spin.NONCOLINEAR)),
                "spinorbit": (4, H.transform(spin=sisl.Spin.SPINORBIT))
            }[spin_type]

            init_func = partial(H.plot.pdos, Erange=[-5, 5])
            attrs = {"na": 2, "no": 2, "n_spin": n_spin, "species": ('C', )}

        return init_func, attrs
Esempio n. 17
0
def test_lspgeom_sameassisl():
    Hs = si.Hamiltonian(si.geom.graphene(),
                        orthogonal=True,
                        spin=si.Spin.POLARIZED)
    dim = Hs.dim
    assert dim == 2
    Hs.set_nsc((7, 7, 1))
    Hs.construct([[0.1, 1.5, 3, 5, 9], [-2, 1, 0.1, 0.01, 0.001]])
    Hs = Hs.tile(4, 0).tile(4, 1)
    Hs.finalize()
    LHs = LSpGeom(Hs)

    HS2 = Hs + Hs
    LHs2 = LHs + LHs
    assert all(_allclose_csr(HS2.tocsr(i), LHs2[i]) for i in range(dim))

    Hzero = Hs - Hs
    LHszero = LHs - LHs
    assert all(_allclose_csr(Hzero.tocsr(i), LHszero[i]) for i in range(dim))
    Hzero.eliminate_zeros(atol=1e-3)
    LHszero.eliminate_zeros(atol=1e-3)
    assert all(_allclose_csr(Hzero.tocsr(i), LHszero[i]) for i in range(dim))

    Hnz = Hs - 0.5 * Hs
    Hnz2 = Hnz.copy()
    LHsnz = LHs - 0.5 * LHs
    LHsnz2 = LHsnz.copy()
    assert all(_allclose_csr(Hnz.tocsr(i), LHsnz[i]) for i in range(dim))
    Hnz.eliminate_zeros(atol=1e-2)
    LHsnz.eliminate_zeros(atol=1e-2)
    assert all(_allclose_csr(Hnz.tocsr(i), LHsnz[i]) for i in range(dim))
    diff1 = Hnz2 - Hnz
    diff2 = LHsnz2 - LHsnz
    assert all(
        _allclose_csr(diff1.tocsr(i), diff2[i], rtol=1e-10)
        for i in range(dim))
g = geom.zgnr(W, atoms=C)

# Add another atom to have heterogeneous number of orbitals per atoms
C2 = sisl.Atom(6, orbitals=[pz])
G_C2 = sisl.Geometry(g.xyz[0], atoms=C2)
g = g.replace(0, G_C2)

# Identify index for atoms
idx = g.a2o(range(len(g)))

# Build U for each orbital in each atom
#U = np.zeros(g.no)
#U[idx] = 3.

# Build TB Hamiltonian, zeroes for non-pz orbitals
TBham = sisl.Hamiltonian(g, spin='polarized')
for ia in g:
    ib = g.close(ia, R=[0, 1.42 + 0.1])
    io_a = g.a2o(ia, all=True)
    for iib in ib[1]:
        io_b = g.a2o(iib, all=True)
        TBham[io_a[0], io_b[0]] = -2.7

# HubbardHamiltonian object and converge
HH = HubbardHamiltonian(TBham, U=None, nkpt=[100, 1, 1])
HH.set_polarization([0], dn=[g.a2o(13)])
HH.converge(density.calc_n, print_info=True, tol=1e-10, steps=3)

# Print spin-densities difference compared to sing-orbital case
print(
    '\n   ** Difference between spin densities for single and multi-orbital cases **'
Esempio n. 19
0
def sp2(ext_geom,
        t1=2.7,
        t2=0.2,
        t3=0.18,
        eB=3.,
        eN=-3.,
        s0=1.0,
        s1=0,
        s2=0,
        s3=0,
        dq=0,
        dim=2):
    """ Function to create a Tight Binding Hamiltoninan for sp2 Carbon systems

    It takes advantage of the `sisl` class for building sparse Hamiltonian matrices,
    `sisl.physics.Hamiltonian`

    It obtains the Hamiltonian for ``ext_geom`` (which must be a `sisl.Geometry` instance)
    with the parameters for first, second and third nearest neighbors (``t1``, ``t2``, ``t3``).

    One can also use a non-orthogonal basis of atomic orbitals by passing the parameters for the
    overlap matrix between first, second and third nearest neighbors (``s1``, ``s2``, ``s3``).

    The function will also take into account the possible presence of Boron or Nitrogen atoms,
    for which one would need to specify the on-site energy for those atoms (``eB`` and ``eN``)

    Returns
    -------
    H: sisl.physics.Hamiltonian
        tight-binding Hamiltonian for the sp2 structure of ``dim=2`` (for the two spin channels)
    """

    # Determine pz sites
    aux = []
    sp3 = []
    for ia, atom in enumerate(ext_geom.atoms.iter()):
        # Append non C-type atoms in aux list
        if atom.Z not in [5, 6, 7]:
            aux.append(ia)
        idx = ext_geom.close(ia, R=[0.1, 1.6])
        if len(idx[1]) == 4:  # Search for atoms with 4 neighbors
            if atom.Z == 6:
                sp3.append(ia)

    # Remove all sites not carbon-type
    pi_geom = ext_geom.remove(aux + sp3)
    pi_geom.reduce()

    # Iterate over atomic species to set initial charge
    maxR = 20
    r = np.linspace(0, maxR, 700)
    # In Slater-type orbitals (Hydrogen-like atom solution), the radial function is ~exp(-Zr/2a)
    # where a=0.529 \AA is the Bohr radius and Z is the atomic number.
    # We use the effective nuclear charge instead, which for Carbon atoms is approximately Zeff~3.
    func = np.exp(-3 * r)
    for atom, _ in pi_geom.atoms.iter(True):
        pz = sisl.AtomicOrbital('pz', (r, func), R=maxR, q0=atom.Z - 5 + dq)
        atom.orbitals[0] = pz

    # Construct Hamiltonian
    if s1 != 0:
        orthogonal = False
    else:
        orthogonal = True
    H = sisl.Hamiltonian(pi_geom, orthogonal=orthogonal, dim=dim)

    # Radii defining 1st, 2nd, and 3rd neighbors
    R = [0.1, 1.6, 2.6, 3.1]
    # Build hamiltonian for backbone

    for ia in pi_geom:
        idx = pi_geom.close(ia, R=R)
        # NB: I found that ':' is necessary in the following lines, but I don't understand why...
        if pi_geom.atoms[ia].Z == 5:
            H[ia, ia, :] = eB  # set onsite for B sites
        elif pi_geom.atoms[ia].Z == 7:
            H[ia, ia, :] = eN  # set onsite for N sites
        # set hoppings
        H[ia, idx[1], :] = -t1
        if t2 != 0:
            H[ia, idx[2], :] = -t2
        if t3 != 0:
            H[ia, idx[3], :] = -t3
        if not H.orthogonal:
            H.S[ia, ia] = s0
            H.S[ia, idx[1]] = s1
            H.S[ia, idx[2]] = s2
            H.S[ia, idx[3]] = s3

    return H
Esempio n. 20
0
def test_gf_write_read_direct(sisl_tmp, sisl_system):
    f = sisl_tmp('file.TSGF', _dir)

    tb = sisl.Hamiltonian(sisl_system.gtb, spin=sisl.Spin('P'))
    tb.construct([(0.1, 1.5), ([0.1, -0.1], [2.7, 1.6])])

    bz = sisl.MonkhorstPack(tb, [3, 3, 1])
    E = np.linspace(-2, 2, 3) + 1j * 1e-4
    S = np.eye(len(tb), dtype=np.complex128)

    gf = sisl.io.get_sile(f)

    gf.write_header(bz, E)
    for i, (ispin, write_hs, k, e) in enumerate(gf):
        Hk = tb.Hk(k, spin=ispin, format='array')
        if write_hs and i % 2 == 0:
            gf.write_hamiltonian(Hk)
        elif write_hs:
            gf.write_hamiltonian(Hk, S)
        gf.write_self_energy(S * e - Hk)

    # ensure it is not opened
    assert not gf._fortran_is_open()

    # First try from beginning
    for e in [0, 1, E[1], 0, E[0]]:
        ie = gf.Eindex(e)
        SE1 = gf.self_energy(e, bz.k[2, :])
        assert gf._state == 1
        assert gf._ik == 2
        assert gf._iE == ie
        assert gf._ispin == 0
        assert gf._is_read == 1

        SE2 = gf.self_energy(e, bz.k[2, :], spin=1)
        assert gf._state == 1
        assert gf._ik == 2
        assert gf._iE == ie
        assert gf._ispin == 1
        assert gf._is_read == 1

        assert not np.allclose(SE1, SE2)

        # In the middle we read some hamiltonians
        H1, S1 = gf.HkSk(bz.k[2, :], spin=0)
        assert gf._state == 0
        assert gf._ik == 2
        assert gf._iE == 0
        assert gf._ispin == 0
        assert gf._is_read == 1
        assert np.allclose(S, S1)

        H2, S1 = gf.HkSk(bz.k[2, :], spin=1)
        assert gf._state == 0
        assert gf._ik == 2
        assert gf._iE == 0
        assert gf._ispin == 1
        assert gf._is_read == 1
        assert np.allclose(S, S1)
        assert not np.allclose(H1, H2)
        assert not np.allclose(H1, SE1)

        H2, S1 = gf.HkSk(bz.k[2, :], spin=0)
        assert gf._state == 0
        assert gf._ik == 2
        assert gf._iE == 0
        assert gf._ispin == 0
        assert gf._is_read == 1
        assert np.allclose(S, S1)
        assert np.allclose(H1, H2)

        # Now read self-energy
        SE2 = gf.self_energy(e, bz.k[2, :], spin=0)
        assert gf._state == 1
        assert gf._ik == 2
        assert gf._iE == ie
        assert gf._ispin == 0
        assert gf._is_read == 1

        assert np.allclose(SE1, SE2)
Esempio n. 21
0
    def init_func_and_attrs(self, request, siesta_test_files):
        name = request.param

        if name.startswith("sisl_H"):
            gr = sisl.geom.graphene()
            H = sisl.Hamiltonian(gr)
            H.construct([(0.1, 1.44), (0, -2.7)])

            spin_type = name.split("_")[2]
            n_spin, H = {
                "unpolarized": (1, H),
                "polarized": (2, H.transform(spin=sisl.Spin.POLARIZED)),
                "noncolinear": (1, H.transform(spin=sisl.Spin.NONCOLINEAR)),
                "spinorbit": (1, H.transform(spin=sisl.Spin.SPINORBIT))
            }.get(spin_type)

            n_states = 2
            if H.spin.is_spinorbit or H.spin.is_noncolinear:
                n_states *= 2

            # Directly creating a BandStructure object
            if name.endswith("jump"):
                names = ["Gamma", "M", "M", "K"]
                bz = sisl.BandStructure(H, [[0, 0, 0], [2 / 3, 1 / 3, 0], None,
                                            [2 / 3, 1 / 3, 0], [1 / 2, 0, 0]],
                                        6, names)
                nk = 7
                tickvals = [0., 1.70309799, 1.83083034, 2.68237934]
            else:
                names = ["Gamma", "M", "K"]
                bz = sisl.BandStructure(
                    H, [[0, 0, 0], [2 / 3, 1 / 3, 0], [1 / 2, 0, 0]], 6, names)
                nk = 6
                tickvals = [0., 1.70309799, 2.55464699]
            init_func = bz.plot.fatbands

            attrs = {
                "bands_shape":
                (nk, n_spin, n_states) if H.spin.is_polarized else
                (nk, n_states),
                "weights_shape":
                (n_spin, nk, n_states, 2) if H.spin.is_polarized else
                (nk, n_states, 2),
                "ticklabels":
                names,
                "tickvals":
                tickvals,
                "gap":
                0,
                "spin_texture":
                not H.spin.is_diagonal,
                "spin":
                H.spin
            }
        elif name == "wfsx file":
            # From a siesta bands.WFSX file
            # Since there is no hamiltonian for bi2se3_3ql.fdf, we create a dummy one
            wfsx = sisl.get_sile(siesta_test_files("bi2se3_3ql.bands.WFSX"))

            geometry = sisl.get_sile(
                siesta_test_files("bi2se3_3ql.fdf")).read_geometry()
            geometry = sisl.Geometry(geometry.xyz, atoms=wfsx.read_basis())

            H = sisl.Hamiltonian(geometry, dim=4)

            init_func = partial(H.plot.fatbands,
                                wfsx_file=wfsx,
                                E0=-51.68,
                                entry_points_order=["wfsx file"])
            attrs = {
                "bands_shape": (16, 8),
                "weights_shape": (16, 8, 195),
                "ticklabels": None,
                "tickvals": None,
                "gap": 0.0575,
                "spin_texture": False,
                "spin": sisl.Spin("nc")
            }

        return init_func, attrs
Esempio n. 22
0
import plotly.graph_objs as go
import numpy as np

import sisl

r = np.linspace(0, 3.5, 50)
f = np.exp(-r)

orb = sisl.AtomicOrbital('2pzZ', (r, f))
geom = sisl.geom.graphene(orthogonal=True, atoms=sisl.Atom(6, orb))
geom = geom.move([0, 0, 5])
H = sisl.Hamiltonian(geom)
H.construct([(0.1, 1.44), (0, -2.7)], )


def test_eigenstate_wf():

    plot = H.eigenstate()[0].plot.wavefunction(geometry=H.geometry)

    assert len(plot.data) > 0
    assert isinstance(plot.data[0], go.Isosurface)


def test_hamiltonian_wf():

    # Check if it works for 3D plots
    plot = H.plot.wavefunction(2)
    assert isinstance(plot.data[0], go.Isosurface)

    # Check that setting plot geom to True adds data traces
    plot.update_settings(plot_geom=False)
Esempio n. 23
0
#final_H_pertb = sisl.Hamiltonian(fdf.read_geometry(), dtype = np.complex128)
##print(np.shape(H_perturbation[:,0,0].reshape((5022,1))))
##final_H_pertb = sparse.csr_matrix((H_perturbation[:,:,0].reshape(5022*5022*9,1), (H_perturbation[:,0,0].reshape((5022,1)),H_perturbation[0,:,0].reshape((5022*9,1)))), shape=(5022,5022*9))
#print(np.shape(final_H_pertb))
#final_H_pertb = final_H_pertb.fromsp(fdf.read_geometry(),test_csr)
#print(final_H_pertb)
#dH.write_delta(final_H_pertb, E = energies)#, K=[0,0,0])

# Let's jsut assume the general case in which there are no enegy and K dipendency.
multiE = ''  # 'multiE'
multiK = ''  # 'multiK'

dH = sisl.get_sile(
    '{}/photocurrent/deltaH{}{}_{}.dH.nc'.format(path_wd, multiE, multiK,
                                                 bias), 'w')
final_H_pertb = sisl.Hamiltonian(fdf.read_geometry(), dtype=np.complex128)
#print(np.shape(H_perturbation[:,0,0].reshape((5022,1))))
#final_H_pertb = sparse.csr_matrix((H_perturbation[:,:,0].reshape(5022*5022*9,1), (H_perturbation[:,0,0].reshape((5022,1)),H_perturbation[0,:,0].reshape((5022*9,1)))), shape=(5022,5022*9))
print(np.shape(final_H_pertb))
print(fdf.read_geometry())
final_H_pertb = final_H_pertb.fromsp(fdf.read_geometry(), test_csr)
print(final_H_pertb)

## Energy and kpoint dependent perturbation Hamiltonian
#for energies in np.linspace(-0.1, photon_energy+0.1, 301):
##print('*********************'+str(energies)+'*********************')
#for kpoints in np.linspace(0, 0.5, 5):
##print('*********************'+str(kpoints)+'*********************')
#dH.write_delta(final_H_pertb, E = energies, k = [kpoints,0,0])

# Energy dependent perturbation Hamiltonian
Esempio n. 24
0
    """
    y0: center of channel
    y: coordinates to apply the potential too
    y_length: y0 - y_length / 2 -- y0 + y_length / 2 is the channel position
    """
    tanhL = np.tanh((y - y0 - y_length * 0.5) / relax)
    tanhR = np.tanh(-(y - y0 + y_length * 0.5) / relax)

    return 0.5 * (tanhL + tanhR)


def potential(H, ia, idxs, idxs_xyz=None):
    # Retrieve all atoms close to ia
    idx = H.geometry.close(ia, R=[0.1, 1.44], idx=idxs, idx_xyz=idxs_xyz)

    H[ia, idx[0]] = onsite_y(
        H.geometry.center(what='cell')[1], H.geometry.xyz[idx[0], 1], 50, 5)
    H[ia, idx[1]] = -2.7


graphene = si.geom.graphene(orthogonal=True).tile(200, 1)
H = si.Hamiltonian(graphene)
H.construct(potential)

# Extract the diagonal (on-site terms of the Hamiltonian)
diag = H.Hk().diagonal()
plt.plot(H.geometry.xyz[:, 1], diag)
plt.xlabel('y [Ang]')
plt.ylabel('Onsite [eV]')
plt.show()
Esempio n. 25
0
def CAP(geometry, side, dz_CAP=30, write_xyz=True, zaxis=2):
    # Determine orientation
    if zaxis == 2:
        xaxis, yaxis = 0, 1
    elif zaxis == 0:
        xaxis, yaxis = 1, 2
    elif zaxis == 1:
        xaxis, yaxis = 0, 2
    # Natural units (see "http://superstringtheory.com/unitsa.html")
    hbar = 1
    m = 0.511e6  # eV
    c = 2.62
    print('\nSetting up CAP regions: {}'.format(side))
    print('Width of absorbing walls = {} Angstrom'.format(dz_CAP))
    Wmax = 100
    dH_CAP = si.Hamiltonian(geometry, dtype='complex128')
    CAP_list = []
    ### EDGES
    if 'right' in side:
        print('Setting at right')
        z, y = geometry.xyz[:, xaxis], geometry.xyz[:, yaxis]
        z2 = np.max(geometry.xyz[:, xaxis]) + 1.
        z1 = z2 - dz_CAP
        idx = np.where(np.logical_and(z1 <= z, z < z2))[0]
        fz = (4 / (c**2)) * ((dz_CAP / (z2 - 2 * z1 + z[idx]))**2 +
                             (dz_CAP / (z2 - z[idx]))**2 - 2)
        Wz = ((hbar**2) / (2 * m)) * (2 * np.pi / (dz_CAP / 2000))**2 * fz
        orbs = dH_CAP.geom.a2o(
            idx)  # if you have just 1 orb per atom, then orb = ia
        for orb, wz in zip(orbs, Wz):
            dH_CAP[orb, orb] = complex(0, -wz)
        CAP_list.append(idx)
        #print(list2range_TBTblock(idx))

    if 'left' in side:
        print('Setting at left')
        z, y = geometry.xyz[:, xaxis], geometry.xyz[:, yaxis]
        z2 = np.min(geometry.xyz[:, xaxis]) - 1.
        z1 = z2 + dz_CAP
        idx = np.where(np.logical_and(z2 < z, z <= z1))[0]
        fz = (4 / (c**2)) * ((dz_CAP / (z2 - 2 * z1 + z[idx]))**2 +
                             (dz_CAP / (z2 - z[idx]))**2 - 2)
        Wz = ((hbar**2) / (2 * m)) * (2 * np.pi / (dz_CAP / 2000))**2 * fz
        orbs = dH_CAP.geom.a2o(
            idx)  # if you have just 1 orb per atom, then orb = ia
        for orb, wz in zip(orbs, Wz):
            dH_CAP[orb, orb] = complex(0, -wz)
        CAP_list.append(idx)
        #print(list2range_TBTblock(idx))

    if 'top' in side:
        print('Setting at top')
        z, y = geometry.xyz[:, xaxis], geometry.xyz[:, yaxis]
        y2 = np.max(geometry.xyz[:, yaxis]) + 1.
        y1 = y2 - dz_CAP
        idx = np.where(np.logical_and(y1 <= y, y < y2))[0]
        fz = (4 / (c**2)) * ((dz_CAP / (y2 - 2 * y1 + y[idx]))**2 +
                             (dz_CAP / (y2 - y[idx]))**2 - 2)
        Wz = ((hbar**2) / (2 * m)) * (2 * np.pi / (dz_CAP / 2000))**2 * fz
        orbs = dH_CAP.geom.a2o(
            idx)  # if you have just 1 orb per atom, then orb = ia
        for orb, wz in zip(orbs, Wz):
            dH_CAP[orb, orb] = complex(0, -wz)
        CAP_list.append(idx)
        #print(list2range_TBTblock(idx))

    if 'bottom' in side:
        print('Setting at bottom')
        z, y = geometry.xyz[:, xaxis], geometry.xyz[:, yaxis]
        y2 = np.min(geometry.xyz[:, yaxis]) - 1.
        y1 = y2 + dz_CAP
        idx = np.where(np.logical_and(y2 < y, y <= y1))[0]
        fz = (4 / (c**2)) * ((dz_CAP / (y2 - 2 * y1 + y[idx]))**2 +
                             (dz_CAP / (y2 - y[idx]))**2 - 2)
        Wz = ((hbar**2) / (2 * m)) * (2 * np.pi / (dz_CAP / 2000))**2 * fz
        orbs = dH_CAP.geom.a2o(
            idx)  # if you have just 1 orb per atom, then orb = ia
        for orb, wz in zip(orbs, Wz):
            dH_CAP[orb, orb] = complex(0, -wz)
        CAP_list.append(idx)
        #print(list2range_TBTblock(idx))

    CAP_list = np.concatenate(CAP_list).ravel().tolist()
    if write_xyz:
        # visualize CAP regions
        visualize = geometry.copy()
        visualize.atom[CAP_list] = si.Atom(8, R=[1.44])
        visualize.write('CAP.xyz')

    return dH_CAP
Esempio n. 26
0
    def init_func_and_attrs(self, request, siesta_test_files):
        name = request.param

        if name == "siesta_output":
            # From a siesta .bands file
            init_func = sisl.get_sile(siesta_test_files("SrTiO3.bands")).plot
            attrs = {
                "bands_shape": (150, 72),
                "ticklabels": ('Gamma', 'X', 'M', 'Gamma', 'R', 'X'),
                "tickvals":
                [0.0, 0.429132, 0.858265, 1.465149, 2.208428, 2.815313],
                "gap": 1.677,
                "spin_texture": False,
                "spin": sisl.Spin("")
            }
        elif name.startswith("sisl_H"):
            gr = sisl.geom.graphene()
            H = sisl.Hamiltonian(gr)
            H.construct([(0.1, 1.44), (0, -2.7)])

            spin_type = name.split("_")[-1]
            n_spin, H = {
                "unpolarized": (0, H),
                "polarized": (2, H.transform(spin=sisl.Spin.POLARIZED)),
                "noncolinear": (0, H.transform(spin=sisl.Spin.NONCOLINEAR)),
                "spinorbit": (0, H.transform(spin=sisl.Spin.SPINORBIT))
            }.get(spin_type)

            n_states = 2
            if not H.spin.is_diagonal:
                n_states *= 2

            # Let's create the same graphene bands plot using the hamiltonian
            # from two different prespectives
            if name.startswith("sisl_H_path"):
                # Passing a list of points (as if we were interacting from a GUI)
                path = [{
                    "active": True,
                    "x": x,
                    "y": y,
                    "z": z,
                    "divisions": 3,
                    "name": tick
                } for tick, (x, y, z) in zip(
                    ["Gamma", "M", "K"], [[0, 0, 0], [2 / 3, 1 /
                                                      3, 0], [1 / 2, 0, 0]])]

                init_func = partial(H.plot.bands, band_structure=path)
            else:
                # Directly creating a BandStructure object
                bz = sisl.BandStructure(
                    H, [[0, 0, 0], [2 / 3, 1 / 3, 0], [1 / 2, 0, 0]], 6,
                    ["Gamma", "M", "K"])
                init_func = bz.plot

            attrs = {
                "bands_shape": (6, n_spin, n_states) if n_spin != 0 else
                (6, n_states),
                "ticklabels": ["Gamma", "M", "K"],
                "tickvals": [0., 1.70309799, 2.55464699],
                "gap":
                0,
                "spin_texture":
                not H.spin.is_diagonal,
                "spin":
                H.spin
            }

        return init_func, attrs
Esempio n. 27
0
#!/usr/bin/env python

# This benchmark creates a very large graphene flake and uses construct
# to create it.

# This benchmark may be called using:
#
#  python -m cProfile -o $0.profile $0
#
# and it may be post-processed using
#
#  python stats.py $0.profile
#

import sys
import sisl
import numpy as np

if len(sys.argv) > 1:
    N = int(sys.argv[1])
else:
    N = 200
print("N = {}".format(N))

gr = sisl.geom.graphene(orthogonal=True).tile(N, 0).tile(N, 1)
H = sisl.Hamiltonian(gr)
H.construct([(0.1, 1.44), (0., -2.7)], method='cube', eta=True)
Esempio n. 28
0
import sisl

graphene = sisl.geom.graphene()

H = sisl.Hamiltonian(graphene)
for ia, io in H:
    idx = H.geometry.close(ia, R=[0.1, 1.43])
    H[io, idx[0]] = 0.
    H[io, idx[1]] = -2.7

print(H.eigh(k=[0., 0.5, 0.]))