def _read_siesta_output(self, bands_file, path, band_structure): """ Reads the bands information from a SIESTA bands file. """ #Get the info from the bands file self.path = path if self.path and self.path != getattr(self, "siesta_path", None) or band_structure: raise ValueError("A path was provided, therefore we can not use the .bands file even if there is one") self.bands = self.get_sile(bands_file or "bands_file").read_data(as_dataarray=True) # Inform of the path that it's being used if we can # THIS IS ONLY WORKING PROPERLY FOR FRACTIONAL UNITS OF THE BAND POINTS RN if hasattr(self, "fdf_sile") and self.fdf_sile.get("BandLines"): try: self.siesta_path = [] points = self.fdf_sile.get("BandLines") for i, point in enumerate(points): divisions, x, y, z, *others = point.split() divisions = int(divisions) - int(points[i-1].split()[0]) if i > 0 else None tick = others[0] if len(others) > 0 else None self.siesta_path.append({"active": True, "x": float(x), "y": float(y), "z": float(z), "divisions": divisions, "tick": tick}) self.update_settings(path=self.siesta_path, run_updates=False, no_log=True) except Exception as e: print(f"Could not correctly read the bands path from siesta.\n Error {e}") # Define the spin class of the results we have retrieved if len(self.bands.spin.values) == 2: self.spin = sisl.Spin("p")
def test_nc_H_non_colinear(sisl_tmp): H1 = Hamiltonian(sisl.geom.graphene(), spin=sisl.Spin('NC')) H1.construct(([0.1, 1.44], [0.1, 0.2, 0.3, 0.4])) f1 = sisl_tmp('H1.nc', _dir) f2 = sisl_tmp('H2.nc', _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 _read_siesta_output(self, bands_file, band_structure): """ Reads the bands information from a SIESTA bands file. """ if band_structure: raise ValueError( "A path was provided, therefore we can not use the .bands file even if there is one" ) self.bands_data = self.get_sile( bands_file or "bands_file").read_data(as_dataarray=True) # Define the spin class of the results we have retrieved if len(self.bands_data.spin.values) == 2: self.spin = sisl.Spin("p")
def test_nc_EDM_non_colinear(sisl_tmp): EDM1 = EnergyDensityMatrix(sisl.geom.graphene(), spin=sisl.Spin('NC')) EDM1.construct(([0.1, 1.44], [0.1, 0.2, 0.3, 0.4])) f1 = sisl_tmp('EDM1.nc', _dir) f2 = sisl_tmp('EDM2.nc', _dir) EDM1.write(f1) EDM1.finalize() EDM2 = sisl.get_sile(f1).read_energy_density_matrix() EDM2.write(f2) EDM3 = sisl.get_sile(f2).read_energy_density_matrix() assert EDM1._csr.spsame(EDM2._csr) assert np.allclose(EDM1._csr._D, EDM2._csr._D) assert EDM1._csr.spsame(EDM3._csr) assert np.allclose(EDM1._csr._D, EDM3._csr._D)
def test_nc_DM_non_colinear(sisl_tmp): DM1 = DensityMatrix(sisl.geom.graphene(), spin=sisl.Spin('NC')) DM1.construct(([0.1, 1.44], [[0.1, 0.2, 0.3, 0.4], [0.2, 0.3, 0.4, 0.5]])) f1 = sisl_tmp('DM1.nc', _dir) f2 = sisl_tmp('DM2.nc', _dir) DM1.write(f1) DM1.finalize() DM2 = sisl.get_sile(f1).read_density_matrix() DM2.write(f2) DM3 = sisl.get_sile(f2).read_density_matrix() assert DM1._csr.spsame(DM2._csr) assert np.allclose(DM1._csr._D, DM2._csr._D) assert DM1._csr.spsame(DM3._csr) assert np.allclose(DM1._csr._D, DM3._csr._D)
def test_nc_H_spin_orbit_nc2tshs2nc(sisl_tmp): H1 = 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('H1.nc', _dir) f2 = sisl_tmp('H2.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_nc_DM_spin_orbit_nc2dm2nc(sisl_tmp): DM1 = DensityMatrix(sisl.geom.graphene(), orthogonal=False, spin=sisl.Spin('SO')) DM1.construct(([0.1, 1.44], [[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.], [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.]])) f1 = sisl_tmp('DM1.nc', _dir) f2 = sisl_tmp('DM2.DM', _dir) DM1.finalize() DM1.write(f1) DM2 = sisl.get_sile(f1).read_density_matrix() DM2.write(f2) DM3 = sisl.get_sile(f2).read_density_matrix() assert DM1._csr.spsame(DM2._csr) assert np.allclose(DM1._csr._D, DM2._csr._D) assert DM1._csr.spsame(DM3._csr) assert np.allclose(DM1._csr._D, DM3._csr._D)
def test_nc_EDM_non_colinear(sisl_tmp): EDM1 = EnergyDensityMatrix(sisl.geom.graphene(), spin=sisl.Spin('NC')) EDM1.construct(([0.1, 1.44], [[0.1, 0.2, 0.3, 0.4], [0.2, 0.3, 0.4, 0.5]])) f1 = sisl_tmp('EDM1.nc', _dir) f2 = sisl_tmp('EDM2.nc', _dir) EDM1.write(f1, sort=False) EDM1.finalize() EDM2 = sisl.get_sile(f1).read_energy_density_matrix(sort=False) EDM2.write(f2, sort=False) EDM3 = sisl.get_sile(f2).read_energy_density_matrix(sort=False) assert EDM1._csr.spsame(EDM2._csr) assert EDM1._csr.spsame(EDM3._csr) # EDM1 is finalized, but EDM2 is not finalized assert not np.allclose(EDM1._csr._D, EDM2._csr._D) # EDM2 and EDM3 are the same assert np.allclose(EDM2._csr._D, EDM3._csr._D) EDM2.finalize() assert np.allclose(EDM1._csr._D, EDM2._csr._D)
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 _after_read(self, geometry): """ Creates the PDOS dataarray and updates the "requests" input field. """ from xarray import DataArray # Check if the PDOS contains spin resolution (there should be three dimensions, # and the first one should be the spin components) self.spin = sisl.Spin.UNPOLARIZED if self.PDOS.squeeze().ndim == 3: self.spin = { 2: sisl.Spin.POLARIZED, 4: sisl.Spin.NONCOLINEAR }[self.PDOS.shape[0]] self.spin = sisl.Spin(self.spin) # Normalize the PDOS array so that we ensure a first dimension for spin even if # there is no spin resolution if self.PDOS.ndim == 2: self.PDOS = np.expand_dims(self.PDOS, axis=0) # Set the geometry. if geometry is not None: if geometry.no != self.PDOS.shape[1]: raise ValueError( f"The geometry provided contains {geometry.no} orbitals, while we have PDOS information of {self.PDOS.shape[1]}." ) self.geometry = geometry self.get_param('requests').update_options(self.geometry, self.spin) self.PDOS = DataArray( self.PDOS, coords={ 'spin': self.get_param('requests').get_options("spin"), 'orb': range(self.PDOS.shape[1]), 'E': self.E }, dims=('spin', 'orb', 'E'))
def _after_read(self, geometry): """ Creates the PDOS dataarray and updates the "requests" input field. """ from xarray import DataArray # Check if the PDOS contains spin resolution (there should be three dimensions, # and the first one should be the spin components) self.spin = sisl.Spin.UNPOLARIZED if self.PDOS.squeeze().ndim == 3: self.spin = { 2: sisl.Spin.POLARIZED, 4: sisl.Spin.NONCOLINEAR }[self.PDOS.shape[0]] self.spin = sisl.Spin(self.spin) # Set the geometry. if geometry is not None: if geometry.no != self.PDOS.shape[1]: raise ValueError( f"The geometry provided contains {geometry.no} orbitals, while we have PDOS information of {self.PDOS.shape[1]}." ) self.geometry = geometry self.get_param('requests').update_options(self.geometry, self.spin) # If there's one dimension for spin but the calculation is spin unpolarized, # remove the spurious spin dimension if self.spin.is_unpolarized and self.PDOS.ndim == 3: self.PDOS = self.PDOS[0] coords = {'E': self.E} dims = ('orb', 'E') if not self.spin.is_unpolarized: coords['spin'] = self.get_param('requests').get_options("spin") dims = ('spin', 'orb', 'E') self.PDOS = DataArray(self.PDOS, coords=coords, dims=dims)
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 _after_init(self): self.spin = sisl.Spin("") self.add_shortcut("g", "Toggle gap", self.toggle_gap)
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