def read_es(self, **kwargs): """ Returns the electronic structure from the siesta.TSHS file """ # First read the geometry geom = self.read_geom() # Now read the sizes used... sizes = _siesta.read_tshs_sizes(self.file) spin = sizes[0] no = sizes[2] nnz = sizes[4] ncol, col, dH, dS = _siesta.read_tshs_es(self.file, spin, no, nnz) # Create the Hamiltonian container H = Hamiltonian(geom, nnzpr=1, orthogonal=False, spin=spin) # Create the new sparse matrix H._data.ncol = np.array(ncol, np.int32) ptr = np.cumsum(ncol) ptr = np.insert(ptr, 0, 0) H._data.ptr = np.array(ptr, np.int32) # Correct fortran indices H._data.col = np.array(col, np.int32) - 1 H._data._nnz = len(col) H._data._D = np.empty([nnz, spin + 1], np.float64) for i in range(spin): # this is because of the F-ordering H._data._D[:, i] = dH[:, i] H._data._D[:, spin] = dS[:] return H
def read_es(self, hermitian=True, dtype=np.float64, **kwargs): """ Reads a Hamiltonian (including the geometry) Reads the Hamiltonian model """ # Read the geometry in this file geom = self.read_geom() # Rewind to ensure we can read the entire matrix structure self.fh.seek(0) # With the geometry in place we can read in the entire matrix # Create a new sparse matrix from scipy.sparse import lil_matrix H = lil_matrix((geom.no, geom.no_s), dtype=dtype) S = lil_matrix((geom.no, geom.no_s), dtype=dtype) def i2o(geom, i): try: # pure orbital return int(i) except: # ia[o] # atom ia and the orbital o j = i.replace('[', ' ').replace(']', ' ').split() return geom.a2o(int(j[0])) + int(j[1]) # Start reading in the supercell while True: found, l = self.step_to('matrix') if not found: break # Get supercell ls = l.split() try: isc = np.array([int(ls[i]) for i in range(2, 5)], np.int32) except: isc = np.array([0, 0, 0], np.int32) off1 = geom.sc_index(isc) * geom.no off2 = geom.sc_index(-isc) * geom.no l = self.readline() while not l.startswith('end'): ls = l.split() jo = i2o(geom, ls[0]) io = i2o(geom, ls[1]) h = float(ls[2]) try: s = float(ls[3]) except: s = 0. H[jo, io + off1] = h S[jo, io + off1] = s if hermitian: S[io, jo + off2] = s H[io, jo + off2] = h l = self.readline() return Hamiltonian.sp2HS(geom, H, S)
def read_es(self, **kwargs): """ Returns a tight-binding model from the underlying NetCDF file """ # Get the default spin channel ispin = kwargs.get('ispin', -1) spin = 1 if ispin == -1: spin = len(self._dimension('spin')) # First read the geometry geom = self.read_geom() # Populate the things sp = self._crt_grp(self, 'SPARSE') v = sp.variables['isc_off'] # pre-allocate the super-cells geom.sc.set_nsc(np.amax(v[:, :], axis=0) * 2 + 1) geom.sc.sc_off[:, :] = v[:, :] # Now create the tight-binding stuff (we re-create the # array, hence just allocate the smallest amount possible) ham = Hamiltonian(geom, nnzpr=1, orthogonal=False, spin=spin) # Use Ef to move H to Ef = 0 Ef = float(self._value('Ef')[0]) * Ry2eV**ham._E_order S = np.array(sp.variables['S'][:], np.float64) ncol = np.array(sp.variables['n_col'][:], np.int32) # Update maximum number of connections (in case future stuff happens) ptr = np.append(np.array(0, np.int32), np.cumsum(ncol)).flatten() col = np.array(sp.variables['list_col'][:], np.int32) - 1 # Copy information over ham._data.ncol = ncol ham._data.ptr = ptr ham._data.col = col ham._nnz = len(col) # Create new container H = np.array(sp.variables['H'][ispin, :], np.float64) * Ry2eV**ham._E_order # Correct for the Fermi-level, Ef == 0 H -= Ef * S[:] ham._data._D = np.empty([ham._data.ptr[-1], spin + 1], np.float64) if ispin == -1: for i in range(spin): # Create new container H = np.array(sp.variables['H'][i, :], np.float64) * Ry2eV**ham._E_order # Correct for the Fermi-level, Ef == 0 H -= Ef * S[:] ham._data._D[:, i] = H[:] else: # Create new container H = np.array(sp.variables['H'][ispin, :], np.float64) * Ry2eV**ham._E_order # Correct for the Fermi-level, Ef == 0 H -= Ef * S[:] ham._data._D[:, 0] = H[:] ham._data._D[:, ham.S_idx] = S[:] return ham
def read_es(self, **kwargs): """ Returns a tight-binding model from the underlying NetCDF file """ # Get the default spin channel ispin = kwargs.get('ispin', -1) spin = 1 if ispin == -1: spin = len(self._dimension('spin')) # First read the geometry geom = self.read_geom() # Populate the things sp = self._crt_grp(self, 'SPARSE') v = sp.variables['isc_off'] # pre-allocate the super-cells geom.sc.set_nsc(np.amax(v[:, :], axis=0) * 2 + 1) geom.sc.sc_off[:, :] = v[:, :] # Now create the tight-binding stuff (we re-create the # array, hence just allocate the smallest amount possible) ham = Hamiltonian(geom, nnzpr=1, orthogonal=False, spin=spin) # Use Ef to move H to Ef = 0 Ef = float(self._value('Ef')[0]) * Ry2eV ** ham._E_order S = np.array(sp.variables['S'][:], np.float64) ncol = np.array(sp.variables['n_col'][:], np.int32) # Update maximum number of connections (in case future stuff happens) ptr = np.append(np.array(0, np.int32), np.cumsum(ncol)).flatten() col = np.array(sp.variables['list_col'][:], np.int32) - 1 # Copy information over ham._data.ncol = ncol ham._data.ptr = ptr ham._data.col = col ham._nnz = len(col) # Create new container H = np.array(sp.variables['H'][ispin, :], np.float64) * Ry2eV ** ham._E_order # Correct for the Fermi-level, Ef == 0 H -= Ef * S[:] ham._data._D = np.empty([ham._data.ptr[-1], spin+1], np.float64) if ispin == -1: for i in range(spin): # Create new container H = np.array(sp.variables['H'][i, :], np.float64) * Ry2eV ** ham._E_order # Correct for the Fermi-level, Ef == 0 H -= Ef * S[:] ham._data._D[:, i] = H[:] else: # Create new container H = np.array(sp.variables['H'][ispin, :], np.float64) * Ry2eV ** ham._E_order # Correct for the Fermi-level, Ef == 0 H -= Ef * S[:] ham._data._D[:, 0] = H[:] ham._data._D[:, ham.S_idx] = S[:] return ham
def _read_es(self, geom, dtype=np.complex128, **kwargs): """ Reads a Hamiltonian Reads the Hamiltonian model """ cutoff = kwargs.get('cutoff', 0.00001) # Rewind to ensure we can read the entire matrix structure self.fh.seek(0) # Time of creation self.readline() # Retrieve # of wannier functions no = int(self.readline()) nrpts = int(self.readline()) # First read across the Wigner-Seitz degeneracy # This is formatted with 15 per-line. if nrpts % 15 == 0: nlines = nrpts else: nlines = nrpts + 15 - nrpts % 15 ws = [] wextend = ws.extend for i in range(nlines // 15): wextend(map(int, self.readline().split())) # Convert to numpy array nws = np.array(ws, np.int32).flatten() del ws, wextend # Figure out the number of supercells nsc = [0, 0, 0] while True: l = self.readline() if l == '': break isc = [int(x) for x in l.split(None, 4)[:3]] nsc[0] = max(nsc[0], abs(isc[0])) nsc[1] = max(nsc[1], abs(isc[1])) nsc[2] = max(nsc[2], abs(isc[2])) geom.set_nsc(np.array(nsc, np.int32)*2+1) # With the geometry in place we can read in the entire matrix # Create a new sparse matrix from scipy.sparse import lil_matrix Hr = lil_matrix((geom.no, geom.no_s), dtype=dtype) Hi = lil_matrix((geom.no, geom.no_s), dtype=dtype) self.fh.seek(0) # Skip lines with wx for i in range(nlines // 15 + 3): self.readline() while True: l = self.readline() if l == '': break ls = l.split() # Get supercell and wannier functions # isc = idx[:3] # Hij = idx[3:5] idx = map(int, ls[:5]) i = idx[3] - 1 hr = float(ls[5]) hi = float(ls[6]) # Get the offset off = geom.sc_index(idx[:3]) * geom.no j = idx[4] - 1 + off if abs(hr) > cutoff: Hr[i, j] = hr if abs(hi) > cutoff: Hi[i, j] = hi if np.dtype(dtype).kind == 'c': Hr = Hr.tocsr() Hi = Hi.tocsr() Hr = Hr + 1j*Hi return Hamiltonian.sp2HS(geom, Hr)
def _read_es(self, geom, dtype=np.complex128, **kwargs): """ Reads a Hamiltonian Reads the Hamiltonian model """ cutoff = kwargs.get('cutoff', 0.00001) # Rewind to ensure we can read the entire matrix structure self.fh.seek(0) # Time of creation self.readline() # Retrieve # of wannier functions (or size of Hamiltonian) no = int(self.readline()) # Number of Wigner-Seitz degeneracy points nrpts = int(self.readline()) # First read across the Wigner-Seitz degeneracy # This is formatted with 15 per-line. if nrpts % 15 == 0: nlines = nrpts else: nlines = nrpts + 15 - nrpts % 15 ws = [] for i in range(nlines // 15): ws.extend(map(int, self.readline().split())) # Convert to numpy array and invert (for weights) ws = 1. / np.array(ws, np.float64).flatten() # Figure out the number of supercells # and maintain the Hamiltonian in the ham list nsc = [0, 0, 0] # List for holding the Hamiltonian ham = [] iws = -1 while True: l = self.readline() if l == '': break # Split here... l = l.split() # Get super-cell, row and column iA, iB, iC, r, c = map(int, l[:5]) nsc[0] = max(nsc[0], abs(iA)) nsc[1] = max(nsc[1], abs(iB)) nsc[2] = max(nsc[2], abs(iC)) # Update index for degeneracy, if required if r + c == 2: iws += 1 # Get degeneracy of this element f = ws[iws] # Store in the Hamiltonian array: # isc # row # column # Hr # Hi ham.append(([iA, iB, iC], r - 1, c - 1, float(l[5]) * f, float(l[6]) * f)) # Update number of super-cells geom.set_nsc([i * 2 + 1 for i in nsc]) # With the geometry in place we can read in the entire matrix # Create a new sparse matrix from scipy.sparse import lil_matrix Hr = lil_matrix((geom.no, geom.no_s), dtype=dtype) Hi = lil_matrix((geom.no, geom.no_s), dtype=dtype) # populate the Hamiltonian by examining the cutoff value for isc, r, c, hr, hi in ham: # Calculate the column corresponding to the # correct super-cell c = c + geom.sc_index(isc) * geom.no if abs(hr) > cutoff: Hr[r, c] = hr if abs(hi) > cutoff: Hi[r, c] = hi del ham if np.dtype(dtype).kind == 'c': Hr = Hr.tocsr() Hi = Hi.tocsr() Hr = Hr + 1j * Hi return Hamiltonian.sp2HS(geom, Hr)
def _read_es(self, geom, dtype=np.float64, **kwargs): """ Reads a Hamiltonian Reads the Hamiltonian model """ cutoff = kwargs.get('cutoff', 0.00001) # Rewind to ensure we can read the entire matrix structure self.fh.seek(0) # Time of creation self.readline() # Retrieve # of wannier functions no = int(self.readline()) nrpts = int(self.readline()) # First read across the Wigner-Seitz degeneracy # This is formatted with 15 per-line. if nrpts % 15 == 0: nlines = nrpts else: nlines = nrpts + 15 - nrpts % 15 ws = [] for i in range(nlines // 15): ws.extend([int(x) for x in self.readline().split()]) # Convert to numpy array nws = np.array(ws, np.int32).flatten() del ws # Figure out the number of supercells nsc = [0, 0, 0] while True: l = self.readline() if l == '': break isc = [int(x) for x in l.split()[:3]] nsc[0] = max(nsc[0], abs(isc[0])) nsc[1] = max(nsc[1], abs(isc[1])) nsc[2] = max(nsc[2], abs(isc[2])) geom.set_nsc(np.array(nsc, np.int32)*2+1) # With the geometry in place we can read in the entire matrix # Create a new sparse matrix from scipy.sparse import lil_matrix Hr = lil_matrix((geom.no, geom.no_s), dtype=dtype) Hi = lil_matrix((geom.no, geom.no_s), dtype=dtype) self.fh.seek(0) for i in range(nlines // 15 + 3): self.readline() while True: l = self.readline() if l == '': break ls = l.split() # Get supercell and wannier functions # isc = idx[:3] # Hij = idx[3:5] idx = [int(x) for x in ls[:5]] hr = float(ls[5]) hi = float(ls[6]) # Get the offset off = geom.sc_index(idx[:3]) * geom.no if abs(hr) > cutoff: Hr[idx[3]-1, idx[4]-1 + off] = hr if abs(hi) > cutoff: Hi[idx[3]-1, idx[4]-1 + off] = hi if np.dtype(dtype).kind == 'c': Hr.data[:] = Hr.data[:] + 1j*Hi.data[:] return Hamiltonian.sp2HS(geom, Hr)