def __init__(self, Hlist,dospin=False,tag=''): ## Check dimensionality LG.info('Creating Hamiltonian: %s (spin:%s)'%(tag,dospin)) dims = [x.mat.shape[0] for x in Hlist] if len(set(dims)) == 1 and not dospin: pass # same dimension for every term elif len(set(dims)) == 2 or dospin: LG.info('Spin doubling') md, Md = min(dims), max(max(dims),2*min(dims)) for i in range(len(Hlist)): x = Hlist[i] if x.mat.shape[0] == md: LG.info('spin doubling term: %s'%(x.name)) x.mat = alg.m2spin(x.mat) if x.mat.shape[0] != Md: LG.critical('Error doubling spin in term %s'%(x.name)) else: LG.critical('Different dimensions not coherent with spin') exit() ## Old stuff self.lista = Hlist try: self.dim = int(list(set([x.mat.shape[0] for x in Hlist]))[0]) except TypeError: LG.critical('Different dimensions not coherent with spin') exit() self.tag = tag
def layer(base): """ This function returns a matrix with the layer of each element in the diagonal """ aux = [[None for _ in base] for _ in base] for E in base: N = len(E.onsite) aux[E.place][E.place] = E.layer * np.identity(N) if base.DOspin: return alg.m2spin(bmat(aux)) else: return bmat(aux)
def position(base,coor=2): """ Returns a matrix with the given coordinate of each atom in the diagonal """ aux = [[None for _ in base] for _ in base] for E in base: r = E.position N = len(E.onsite) aux[E.place][E.place] = r[coor] * np.identity(N) if base.DOspin: return alg.m2spin(bmat(aux)) else: return bmat(aux)
def dist(base,r0=np.array([0.,0.,0.])): """ Returns a matrix with the distance of each atom to a given point in the diagonal """ aux = [[None for _ in base] for _ in base] for E in base: r = np.linalg.norm( E.position - r0 ) N = len(E.onsite) aux[E.place][E.place] = r * np.identity(N) if base.DOspin: return alg.m2spin(bmat(aux)) else: return bmat(aux)
def atom(base,Ats=[1]): """ This function returns a matrix with identity matrices in the places of the provided atoms (provided by order in the basis) """ if isinstance(Ats,int): Ats = [Ats] elif isinstance(Ats,list): pass else: LG.error('Wrong input in atom operator') aux = [[None for _ in base] for _ in base] for E in base: dim = len(E.onsite) if E.place in Ats: aux[E.place][E.place] = np.identity(dim,dtype=int) else: aux[E.place][E.place] = np.zeros((dim,dim),dtype=int) if base.DOspin: return alg.m2spin(bmat(aux)) else: return bmat(aux)
def orbital(base,Orbs=['pz']): """ This function returns a matrix with 1's in the place of the provided orbitals """ if isinstance(Orbs,str): Orbs = [Orbs] elif isinstance(Orbs,list): pass else: LG.error('Wrong input in orbital operator') diag_name = [] for E in base: for o in E.orbitals: diag_name.append(o) diag = [0 for _ in diag_name] for i in range(len(diag_name)): if diag_name[i] in Orbs: diag[i] = 1 if base.DOspin: return alg.m2spin(coo_matrix(np.diag(diag))) else: return coo_matrix(np.diag(diag))
def green_function(e, v, h, delta=0.01, path_selfes='.', force=False, l=1.0): """ Returns the Green's function of a given hamiltonian (v) with self-energy (s) and broadening (delta) ** Note that v is a matrix (on-site) but h is a hamiltonian class """ e = round(e, 8) LG = logging.getLogger('mygreen_tools') emat = np.matrix(np.identity(v.shape[0]), dtype=complex) * (e + delta * 1j) if l == 0.: LG.debug('Self-Energy coupling = 0') #print('Self-Energy coupling = 0') return (emat - v).I else: sname = path_selfes + 'self%s.npy' % (e) try: if force: raise FileNotFoundError s = np.load(sname) if v.shape != s.shape: s = alg.m2spin(s) LG.info('loaded from file ' + sname) #print('loaded from file '+sname) except FileNotFoundError: LG.debug('Calculating for E=%s' % (e)) print('Calculating for E=%s' % (e)) #_,s = calc_selfe(e,h,delta=delta,path=path_selfes) _,s = mygreen.bloch_selfenergy(h,energy=e,delta=delta,\ nk=100,error=10**(-5),\ #mode="full") #mode="renormalization") mode="adaptative") if path_selfes != None: sname = path_selfes + 'self%s.npy' % (e) np.save(sname, s) LG.debug('Saved: %s' % (sname)) return (emat - v - l * s).I
def dospin(self): LG.info('Modifying basis for spin') self.LAYS = alg.m2spin(self.LAYS) self.ORBS = alg.m2spin(self.ORBS, Delt='') self.SUBS = alg.m2spin(self.SUBS) self.ATS = alg.m2spin(self.ATS) self.AUX_INDS = alg.m2spin(self.AUX_INDS) self.INDS = alg.m2spin(self.INDS) self.SPIN = np.array([(-1)**i for i in range(len(self.ORBS))]) if len(self.LAYS) != len(self.ORBS) != len(self.SUBS) !=\ len(self.ATS) != len(self.AUX_INDS) != len(self.INDS): LG.critical('Problem Spin-doubling') print('Layers:', len(self.LAYS)) print('Orbitals:', len(self.ORBS)) print('Sublattice:', len(self.SUBS)) print('Atoms:', len(self.ATS)) print('Indices', len(self.INDS)) print('Aux Indices:', len(self.AUX_INDS)) exit() self.ndim = len(self.ATS) # Hamiltonian dimension LG.info('New basis dimension: %s' % (self.ndim))