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
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)
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
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
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
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
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
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)
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)
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
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)
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)
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)
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)
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
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
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 **'
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
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)
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
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)
#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
""" 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()
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
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
#!/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)
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.]))