def read_hamiltonian(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_geometry() # 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', reread=False) 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.fromsp(geom, H, S)
def _read_hamiltonian(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() # Number of orbitals no = int(self.readline()) if no != geom.no: raise ValueError( self.__class__.__name__ + '.read_hamiltonian has found inconsistent number ' 'of orbitals in _hr.dat vs the geometry. Remember to re-run Wannier90?' ) # 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 _ in range(nlines // 15): ws.extend(list(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 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.fromsp(geom, Hr)