def get_A_ijR(self, G, R, iatom, jatom): """ calculate A from G for a energy slice (de). It take the .. math:: A^{uv} = p T^u p T^v dE / pi where u, v are I, x, y, z (index 0, 1,2,3). p(i) = self.get_P_iatom(iatom) T^u(ijR) (u=0,1,2,3) = pauli_block_all(G) :param G: Green's function for all R, i, j. :param iatom: i :param jatom: j :param de: energy step. used for integeration :returns: a matrix of A_ij(u, v), where u, v =(0)0, x(1), y(2), z(3) :rtype: 4*4 matrix """ GR = G[R] Gij = self.GR_atom(GR, iatom, jatom) Gij_Ixyz = pauli_block_all(Gij) # G(j, i, -R) Rm = tuple(-x for x in R) GRm = G[Rm] Gji = self.GR_atom(GRm, jatom, iatom) Gji_Ixyz = pauli_block_all(Gji) tmp = np.zeros((4, 4), dtype=complex) for a in range(4): pGp = self.get_P_iatom(iatom) @ Gij_Ixyz[a] @ self.get_P_iatom( jatom) for b in range(4): AijRab = np.matmul(pGp, Gji_Ixyz[b]) tmp[a, b] = np.trace(AijRab) return tmp / np.pi
def get_A_ijR(self, G, R, iatom, jatom): """ calculate A from G for a energy slice (de). It take the .. math:: A^{uv} = p T^u p T^v dE / pi where u, v are I, x, y, z (index 0, 1,2,3). p(i) = self.get_P_iatom(iatom) T^u(ijR) (u=0,1,2,3) = pauli_block_all(G) :param G: Green's function for all R, i, j. :param iatom: i :param jatom: j :param de: energy step. used for integeration :returns: a matrix of A_ij(u, v), where u, v =(0)0, x(1), y(2), z(3) :rtype: 4*4 matrix """ GR = G[R] Gij = self.GR_atom(GR, iatom, jatom) Gij_Ixyz = pauli_block_all(Gij) # G(j, i, -R) Rm = tuple(-x for x in R) GRm = G[Rm] Gji = self.GR_atom(GRm, jatom, iatom) Gji_Ixyz = pauli_block_all(Gji) ni = self.norb_reduced[iatom] nj = self.norb_reduced[jatom] tmp = np.zeros((4, 4), dtype=complex) if self.orb_decomposition: torb = np.zeros((4, 4, ni, nj), dtype=complex) # a, b in (0,x,y,z) for a in range(4): piGij = self.get_P_iatom(iatom) @ Gij_Ixyz[a] for b in range(4): pjGji = self.get_P_iatom(jatom) @ Gji_Ixyz[b] torb[a, b] = self.simplify_orbital_contributions( np.einsum('ij, ji -> ij', piGij, pjGji) / np.pi, iatom, jatom) tmp[a, b] = np.sum(torb[a, b]) else: for a in range(4): pGp = self.get_P_iatom(iatom) @ Gij_Ixyz[a] @ self.get_P_iatom( jatom) for b in range(4): AijRab = pGp @ Gji_Ixyz[b] tmp[a, b] = np.trace(AijRab) / np.pi torb = None return tmp, torb
def get_A_ijR(self, G, iatom, jatom, de): """ calculate A from G for a energy slice (de). It take the .. math:: A^{uv} = p T^u p T^v dE / pi where u, v are I, x, y, z (index 0, 1,2,3). p(i) = self.get_P_iatom(iatom) T^u(ijR) (u=0,1,2,3) = pauli_block_all(G) :param G: Green's function for all R, i, j. :param iatom: i :param jatom: j :param de: energy step. used for integeration :returns: a matrix of A_ij(u, v), where u, v =(0)0, x(1), y(2), z(3) :rtype: 4*4 matrix """ for R in self.R_ijatom_dict: # G[i, j, R] GR = G[R] if (iatom, jatom) in self.R_ijatom_dict[R]: Gij = self.GR_atom(GR, iatom, jatom) # GijR , I, x, y, z component. if self.tbmodel.is_siesta: Gij_Ixyz = pauli_block_all_wrongy(Gij) else: Gij_Ixyz = pauli_block_all(Gij) # G(j, i, -R) Rm = tuple(-x for x in R) GRm = G[Rm] Gji = self.GR_atom(GRm, jatom, iatom) if self.tbmodel.is_siesta: Gji_Ixyz = pauli_block_all_wrongy(Gji) else: Gji_Ixyz = pauli_block_all(Gji) tmp = np.zeros((4, 4), dtype=complex) for a in range(4): for b in range(4): AijRab = np.matmul( np.matmul(self.get_P_iatom(iatom), Gij_Ixyz[a]), np.matmul(self.get_P_iatom(jatom), Gji_Ixyz[b])) # trace over orb tmp[a, b] = np.trace(AijRab) # Note: the full complex, rather than Re or Im part is stored into A_ijR. self.A_ijR[(R, iatom, jatom)] += tmp * de / np.pi
def get_rho_atom(self): """ calculate charge and spin for each atom. """ rho = {} self.charges = np.zeros(len(self.atoms), dtype=float) self.spinat = np.zeros((len(self.atoms), 3), dtype=float) for iatom in self.orb_dict: iorb = self.iorb(iatom) tmp = self.rho[np.ix_(iorb, iorb)] # *2 because there is a 1/2 in the paui_block_all function rho[iatom] = np.array( [np.trace(x) * 2 for x in pauli_block_all(tmp)]) self.charges[iatom] = np.real(rho[iatom][0]) self.spinat[iatom, :] = np.real(rho[iatom][1:]) self.rho_dict = rho return self.rho_dict
def get_A_ijR(self, G, dG, iatom, jatom, de): """ calculate A from G for a energy slice (de). It take the .. math:: A^{uv} = p T^u p T^v dE / pi where u, v are I, x, y, z (index 0, 1,2,3). p(i) = self.get_P_iatom(iatom) T^u(ijR) (u=0,1,2,3) = pauli_block_all(G) :param G: Green's function for all R, i, j. :param iatom: i :param jatom: j :param de: energy step. used for integeration :returns: a matrix of A_ij(u, v), where u, v =(0)0, x(1), y(2), z(3) :rtype: 4*4 matrix """ for R in self.Rlist: # G[i, j, R] GR = G[R] Gij = self.GR_atom(GR, iatom, jatom) # GijR , I, x, y, z component. Gij_Ixyz = pauli_block_all(Gij) # G(j, i, -R) Rm = tuple(-x for x in R) GRm = G[Rm] Gji = self.GR_atom(GRm, jatom, iatom) Gji_Ixyz = pauli_block_all(Gji) dGR = dG[R] dGij = self.GR_atom(dGR, iatom, jatom) # GijR , I, x, y, z component. dGij_Ixyz = pauli_block_all(dGij) # G(j, i, -R) Rm = tuple(-np.array(R)) dGRm = dG[Rm] dGji = self.GR_atom(dGRm, jatom, iatom) dGji_Ixyz = pauli_block_all(dGji) tmp1 = np.zeros((4, 4), dtype=complex) tmp2 = np.zeros((4, 4), dtype=complex) tmp3 = np.zeros((4, 4), dtype=complex) for a in range(4): for b in range(4): AijRab = np.matmul( np.matmul(self.get_P_iatom(iatom), Gij_Ixyz[a]), np.matmul(self.get_P_iatom(jatom), Gji_Ixyz[b])) A1 = np.matmul( np.matmul(self.get_P_iatom(iatom), dGij_Ixyz[a]), np.matmul(self.get_P_iatom(jatom), Gji_Ixyz[b])) A2 = np.matmul( np.matmul(self.get_P_iatom(iatom), Gij_Ixyz[a]), np.matmul(self.get_P_iatom(jatom), dGji_Ixyz[b])) A3 = np.matmul( np.matmul(self.get_dP_iatom(iatom), Gij_Ixyz[a]), np.matmul(self.get_P_iatom(jatom), Gji_Ixyz[b])) A4 = np.matmul( np.matmul(self.get_P_iatom(iatom), Gij_Ixyz[a]), np.matmul(self.get_dP_iatom(jatom), Gji_Ixyz[b])) AOijRab = A1 + A2 + A3 + A4 if False: B1 = np.matmul( np.matmul(self.get_dP_iatom(iatom), dGij_Ixyz[a]), np.matmul(self.get_P_iatom(jatom), Gji_Ixyz[b])) B2 = np.matmul( np.matmul(self.get_dP_iatom(iatom), Gij_Ixyz[a]), np.matmul(self.get_dP_iatom(jatom), Gji_Ixyz[b])) B3 = np.matmul( np.matmul(self.get_dP_iatom(iatom), Gij_Ixyz[a]), np.matmul(self.get_P_iatom(jatom), dGji_Ixyz[b])) B4 = np.matmul( np.matmul(self.get_P_iatom(iatom), dGij_Ixyz[a]), np.matmul(self.get_dP_iatom(jatom), Gji_Ixyz[b])) B5 = np.matmul( np.matmul(self.get_P_iatom(iatom), dGij_Ixyz[a]), np.matmul(self.get_P_iatom(jatom), dGji_Ixyz[b])) B6 = np.matmul( np.matmul(self.get_P_iatom(iatom), Gij_Ixyz[a]), np.matmul(self.get_dP_iatom(jatom), dGji_Ixyz[b])) tmp3[a, b] = np.trace(B1 + B2 + B3 + B4 + B5 + B6) # trace over orb tmp1[a, b] = np.trace(AijRab) tmp2[a, b] = np.trace(AOijRab) # Note: the full complex, rather than Re or Im part is stored into A_ijR. self.A_ijR[(R, iatom, jatom)] += tmp1 * de / np.pi self.AO_ijR[(R, iatom, jatom)] += tmp2 * de / np.pi self.AT_ijR[(R, iatom, jatom)] += tmp3 * de / np.pi