Source code for eigTB

import numpy as np
import scipy.sparse as sparse
import scipy.linalg as LA
import numpy.random as rand
import sys


[docs]class eigTB(): ''' Solve the Tight-Binding eigenvalue problem of a lattice defined using the class **latticeTB**. :param lat: **latticeTB** class instance. ''' def __init__(self, lat): if not lat.coor.size: raise Exception('\n\nRun method get_lattice() of latticeTB first.\n') self.tags = lat.tags self.sites = lat.sites # sites could be changed self.coor = np.copy(lat.coor) # coor could be changed self.nx, self.ny = lat.nx, lat.ny self.on = np.array([], 'c16') # Sublattice onsite energies self.hop = np.array([], {'names': ['i', 'j', 't'], 'formats': ['u4', 'u4', 'c16']}) # Hoppings self.onsite = np.zeros(self.sites, 'c16') # Onsites energies self.ham = sparse.csr_matrix(([],([],[])), shape=(self.sites, self.sites)) # Hamiltonian self.en = np.array([], 'c16') # Eigenenergies self.vn = np.array([], 'c16') # Eigenvectors self.intensity = np.array([], 'f8') # Intensities (|vn|**2) self.pola = np.array([], 'f8') # sublattices polarisation (|vn^{(S)}|**2) self.alpha = 0. # hopping disorder strength self.alpha_on = 0. # onsite disorder strength self.params = {}
[docs] def set_onsite(self, on): ''' Set onsite energies. :param on: Array. Sublattice onsite energies. ''' self.on = on for o, t in zip(on, self.tags): self.onsite[self.coor['tag'] == t] = o
[docs] def set_hop(self, ho): ''' Set the lattice hoppings. :param ho: Array (size :math:`n`). nth first hopping values. ''' dif_x = self.coor['x'] - self.coor['x'].reshape(self.sites, 1) dif_y = self.coor['y'] - self.coor['y'].reshape(self.sites, 1) dis = np.sqrt(dif_x **2 + dif_y **2) dis_u = np.unique(dis.round(decimals=4)) self.hop = np.array([], {'names': ['i', 'j', 't'], 'formats': ['u4', 'u4', 'c16']}) for i, t in enumerate(ho): ind = np.argwhere((dis > dis_u[i+1]-.01) & (dis < dis_u[i+1]+.01)) hop = np.zeros(len(ind[:, 0]), {'names': ['i', 'j', 't'], 'formats': ['u4', 'u4', 'c16']}) hop['i'] = ind[:, 0] hop['j'] = ind[:, 1] hop['t'] = t self.hop = np.concatenate([self.hop, hop])
[docs] def set_onsite_def(self, ind, on_def): ''' Set specific onsite energies. :param ind: Array. Site indices. :param on_def: Array. Onsite energy values. ''' ind = np.array([ind]) on_def = np.array([on_def]) for i, o in zip(ind, on_def): self.onsite[i] = o
[docs] def set_hop_def(self, ind, hop_def): ''' Set specific hoppings. :param ind: Array. Hopping Indices, size :math:`(2 \times N_{def})`. :param on_def: Array. Onsite energy values. ''' if not self.hop.size: raise Exception('\n\nRun method set_hop() first.\n') for i, t in zip(ind, hop_def): cond = (self.hop['i'] == i[0]) & (self.hop['j'] == i[1]) self.hop['t'][cond] = t cond = (self.hop['j'] == i[0]) & (self.hop['i'] == i[1]) self.hop['t'][cond] = t
[docs] def set_disorder(self, alpha): ''' Set a generic hopping disorder. :param alpha: Stength of the disorder. ''' if not self.hop.size: raise Exception('\n\nRun method set_hop() first.\n') self.hop['t'] *= 1+ alpha * rand.uniform(-0.5, 0.5, len(self.hop['tag'])) self.alpha = alpha
[docs] def set_disorder_on(self, alpha): ''' Set a generic disorder. :param alpha: Stength of the disorder. ''' self.onsite *= 1+ alpha * rand.uniform(-0.5, 0.5, len(self.sites)) self.alpha_on = alpha
[docs] def get_ham(self, compl_trans=False): ''' Get the Tight-Binding Hamiltonian. :param compl_trans: Default value False. Add complex transposed part to the Hamiltonian. ''' if not self.hop.size: raise Exception('\n\nRun method set_hop() first.\n') self.ham = sparse.csr_matrix((self.hop['t'], (self.hop['i'], self.hop['j'])), shape=(self.sites, self.sites)) \ + sparse.diags(self.onsite, 0) if compl_trans: self.ham += sparse.csr_matrix((self.hop['t'].conj(), (self.hop['j'], self.hop['i'])), shape=(self.sites, self.sites))
[docs] def get_eig(self, eigenvec=False): ''' Get the eigenergies, eigenvectors and polarisations of the Tight-Binding model for non-Hermitian Hamiltonians. :param eigenvec: Default value False. Get the eigenvectors. ''' if not self.ham.nnz: raise Exception('\n\nRun method get_ham() first.\n') if eigenvec: if (self.ham.H != self.ham).nnz: self.en, self.vn = LA.eig(self.ham.toarray()) else: self.en, self.vn = LA.eigh(self.ham.toarray()) ind = np.argsort(self.en.real) self.en = self.en[ind] self.vn = self.vn[:, ind] self.intensity = np.abs(self.vn) ** 2 self.pola = np.zeros((self.sites, len(self.tags))) for i, t in enumerate(self.tags): self.pola[:, i] = np.sum(np.abs(self.vn[self.coor['tag'] == t, :]) ** 2, axis=0) else: if (self.ham.H != self.ham).nnz: self.en = LA.eigvals(self.ham.toarray()) ind = np.argsort(self.en.real) self.en = self.en[ind] else: self.en = LA.eigvalsh(self.ham.toarray())
[docs] def get_state_pola(self, pola_tag): ''' Get the state with maximal polarization on one sublattice. :param tag: Sublattice tag. :returns: * **intensity** -- Intensity of max polarized state on *tag*. ''' if not self.pola.size: raise Exception('\n\nRun method get_eig() or get_eigh() first.\n') i_tag = self.tags == pola_tag ind = np.argmax(self.pola[:, i_tag]) print('State with polarization:', self.pola[ind, i_tag]) return self.intensity[:, ind]
[docs] def get_states_en(self, e_min, e_max): ''' Get, if any, the intensity of the sum of the states between *e_min* and *e_max*. :param e_min: Energy min. :param e_max: Energy max. :returns: * **intensity** -- Sum of the intensities between *e_min* and *e_max*. ''' if not self.en.size: raise Exception('\n\nRun method get_eig() or get_eigh() first.\n') ind = np.where((self.en > e_min) & (self.en < e_max)) ind = np.ravel(ind) print('{} states between {} and {}'.format(len(ind), e_min, e_max)) intensity = np.sum(np.abs(self.vn[:, ind]) ** 2, axis=1) return intensity