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 _read_from_H(self, path, band_structure, eigenstate_map=None): """ This entry point just generates a band structure from the path and then the band_structure entry point takes it from there. (it seems stupid now, but this is because of how things were at the beggining) Therefore it should be removed. Only one of "path" or "band_structure" inputs should exist. And then it should be always parsed into a sisl.BandStructure. """ #Get the requested path self.path = path if not self.path and band_structure: return self._read_from_band_structure(eigenstate_map=eigenstate_map) if self.path and len(self.path) > 1: self.path = [point for point in path if point.get("active", True)] else: raise ValueError(f"You need to provide at least 2 points of the path to draw the bands. Please update the 'path' setting. The current path is: {self.path}") band_struct = sisl.BandStructure( None, # The band structure entry_point will take care of this point=np.array([[ point.get("x", None) or 0, point.get("y", None) or 0, point.get("z", None) or 0 ] for point in self.path], dtype=float), division=np.array([point["divisions"] for point in self.path[1:]], dtype=int), name=np.array([point.get("tick", '') for point in self.path]) ) self._read_from_band_structure(band_structure=band_struct, eigenstate_map=eigenstate_map)
def parse(self, val): if not isinstance(val, sisl.BandStructure) and val is not None: # Then let's parse the list of points into a band structure object. # Use only those points that are active. val = [point for point in val if point.get("active", True)] points = [] divisions = [] names = [] # Loop over all points and construct the inputs for BandStructure for i_point, point in enumerate(val): if point.get("jump") is True: # This is a discontinuity points.append(None) if i_point > 0: divisions.append(1) else: # This is an actual point in the band structure. points.append( [point.get("x", None) or 0, point.get("y", None) or 0, point.get("z", None) or 0] ) names.append(point.get("name", "")) if i_point > 0: divisions.append(int(point["divisions"])) print(points, divisions, names) val = sisl.BandStructure(None, points=points, divisions=divisions, names=names) return val
def add_bands(self, HH, bz=[([0., 0., 0.], r'$\Gamma$'), ([0.5, 0., 0.], r'X')], projection=None, scale=1, c='r', spin=0): if isinstance(bz, sisl.BandStructure): band = bz else: path, labels = map(list, zip(*bz)) band = sisl.BandStructure(HH.H, path, 101, labels) lk = band.lineark() xticks, xticks_labels = band.lineartick() if not isinstance(spin, (list, tuple, np.ndarray)): spin = [spin] if not isinstance(c, (list, tuple)): c = [c] if len(spin) > 1 and len(c) == 1: if isinstance(c, list): c = c + ['g.'] elif isinstance(c, tuple): c = c + ('g.', ) ev = np.empty([len(spin), len(lk), HH.sites]) # Set energy reference to the Fermi level for i, s in enumerate(spin): ev[i] = band.apply.array.eigh(spin=s) # Add spin-up component to plot (top layer) self.axes.plot(lk, ev[i], c[i]) # Loop over k if projection != None: pdos = np.empty([len(spin), len(lk), HH.sites]) for ispin in spin: for ik, k in enumerate(band.k): _, evec = HH.eigh(k, eigvals_only=False, spin=ispin) v = evec[tuple(projection), :] pdos[ispin, ik] = np.diagonal(np.dot(np.conjugate(v).T, v).real) # Fat bands? if projection != None: for i in range(HH.sites): self.axes.errorbar(lk, ev[0, :, i], yerr=scale * pdos[0, :, i], alpha=.4, color='Grey') # Figure aspects self.axes.xaxis.set_ticks(xticks) self.axes.set_xticklabels(xticks_labels) # Adjust borders self.fig.subplots_adjust(left=0.2, top=.95, bottom=0.1, right=0.95)
def parse(self, val): if not isinstance(val, sisl.BandStructure) and val is not None: # Then let's parse the list of points into a band structure object. # Use only those points that are active. val = [point for point in val if point.get("active", True)] val = sisl.BandStructure( None, point=[[ point.get("x", None) or 0, point.get("y", None) or 0, point.get("z", None) or 0 ] for point in val], division=[int(point["divisions"]) for point in val[1:]], name=[point.get("name", '') for point in val]) return val
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
def NC_init_func(sisl_files, **kwargs): TSHS_path = osp.join(_dir, "fe_clust_noncollinear.TSHS") H = sisl.get_sile(sisl_files(TSHS_path)).read_hamiltonian() bz = sisl.BandStructure(H, [[0, 0, 0], [0.5, 0, 0]], 3, ["Gamma", "X"]) return bz.plot.fatbands(**kwargs)
plot.split_groups(group_by) err_message = f'Not correctly grouping by {group_by}' assert len(plot.data) - traces_before, err_message # ------------------------------------------------------------ # Test the fatbands plot reading from a sisl Hamiltonian # ------------------------------------------------------------ fatbands_plots = {} gr = sisl.geom.graphene() H = sisl.Hamiltonian(gr) H.construct([(0.1, 1.44), (0, -2.7)]) bz = sisl.BandStructure(H, [[0, 0, 0], [2 / 3, 1 / 3, 0], [1 / 2, 0, 0]], 9, ["Gamma", "M", "K"]) fatbands_plots["sisl_H"] = { "init_func": bz.plot.fatbands, "bands_shape": (9, 1, 2), "weights_shape": (1, 9, 2, 2), "gap": 0, "ticklabels": ["Gamma", "M", "K"], "tickvals": [0., 1.70309799, 2.55464699], } def NC_init_func(sisl_files, **kwargs): TSHS_path = osp.join(_dir, "fe_clust_noncollinear.TSHS") H = sisl.get_sile(sisl_files(TSHS_path)).read_hamiltonian() bz = sisl.BandStructure(H, [[0, 0, 0], [0.5, 0, 0]], 3, ["Gamma", "X"])
# Input TSHS file H_dft = si.get_sile('../../single_point15_51/RUN.fdf').read_hamiltonian() print(H_dft) # Atoms whose orbitals will be extracted from DFT C_list = (H_dft.atoms.Z == 6).nonzero()[0] O_list = (H_dft.atoms.Z == 8).nonzero()[0] # Here we consider both C and O atoms C_O_list = np.concatenate((C_list, O_list)) ; #C_O_list = np.sort(C_O_list) #print(C_list) #print(O_list) #print(C_O_list) ######################################### # Plot bandstructure from DFT band_dft = si.BandStructure(H_dft, [[0.5, 0, 0], [0, 0, 0], [0, 0.5, 0]], 100, [r'$X$', r'$\Gamma$', r'$Y$']) lk, kt, kl = band_dft.lineark(True) if(os.path.isfile('old_eigh.dat')): tbl = si.io.table.tableSile('old_eigh.dat', 'r') bs_dft = tbl.read_data() else: # Calculate all eigenvalues bs_dft = band_dft.eigh(spin=0, eta=True) tbl = si.io.table.tableSile('old_eigh.dat', 'w') tbl.write_data(bs_dft) for bk in bs_dft.T: plt.plot(lk, bk, 'r', label=r'SZP') plt.legend(loc=0, frameon=False, fontsize=11)
def NC_init_func(sisl_files, **kwargs): H = sisl.get_sile( sisl_files("fe_clust_noncollinear.TSHS")).read_hamiltonian() bz = sisl.BandStructure(H, [[0, 0, 0], [0.5, 0, 0]], 3, ["Gamma", "X"]) return bz.plot(**kwargs)
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
return parser.parse_args() if __name__ == '__main__': args = parse_args() sile = sisl.get_sile(args.infile) geom = sile.read_geometry() H = sile.read_hamiltonian(geometry=geom) assert H is not None, "Could not read Hamiltonian." if len(args.division) == 1: args.division = args.division[0] kpath = sisl.BandStructure( H, point=args.kpoints, division=args.division, name=args.klabels, ) def wrap(es, parent, k, weight): return np.concatenate( (es.eig.reshape(-1, 1), es.spin_moment()), axis=-1, ) data = kpath.asarray().eigenstate(wrap=wrap, eta=True) if args.hsx: Ef = sile.read_fermi_level() data[:, :, 0] -= Ef nk, nbands, _ = data.shape
print(gr) # Create the tight-binding Hamiltonian H = sisl.Hamiltonian(gr) R = [0.1 * bond, bond + 0.01] for ia in gr: idx_a = gr.close(ia, R) # On-site H[ia, idx_a[0]] = 0. # Nearest neighbour hopping H[ia, idx_a[1]] = -2.7 # Calculate eigenvalues at K-point band = sisl.BandStructure( H, [[0, 0, 0], [0, 0.5, 0], [1 / 3, 2 / 3, 0], [0, 0, 0]], 400, [r'$\Gamma$', r'$M$', r'$K$', r'$\Gamma$']) bs = band.asarray().eigh() lk, kt, kl = band.lineark(True) plt.xticks(kt, kl) plt.xlim(0, lk[-1]) plt.ylim([-3, 3]) plt.ylabel('$E-E_F$ [eV]') for bk in bs.T: plt.plot(lk, bk) plt.show()