def response(epsilon, rho_0, probe, *perturbs): omega = 0 c = rho_0 for o, a in perturbs: omega += o c = commutator(a, c) / (omega - epsilon) return np.sum(probe.T * c)
def shg_lg(omega, r, r_gd, r2, epsilon, epsilon_gd, f_ij): o_m_e = omega - epsilon h = r / o_m_e #asij g = h * (f_ij.T) #asij g_gd = (r_gd * (f_ij.T) + epsilon_gd[:, None] * g) / o_m_e h2 = r2 / (-2. * omega - epsilon) #asij res = np.tensordot( h2, commutator(r[:, None], g) + 1j * g_gd, ((1, 2, 3), (2, 4, 3))) + 1j / 2. * np.tensordot(g_gd, h, ((2, 3, 4), (1, 3, 2))) return -res
def mk_r_bare(self, nv, nf, nc): vel_opt = jit(jacfwd(self.hm, argnums=(0)), static_argnums=(1)) vel_plane_wave = [] for d_qtm in self.Basis: k, d_qtm_nk = self.separate(d_qtm, self.dim) vel_plane_wave += [ vel_opt(np.asarray(k, dtype=np.float32), d_qtm_nk) ] vel_plane_wave = np.transpose(np.asarray(vel_plane_wave, dtype=np.complex64), axes=(3, 0, 1, 2)) vel = np.transpose(self.wv_funcs.conj(), axes=( 0, 2, 1)) @ vel_plane_wave @ self.wv_funcs #asij epsilon = self.energies[:, :, None] - self.energies[:, None] epsilon_inv = np.asarray(1. / (epsilon + np.diag(np.inf * np.ones( (self.num_nd_bands)))), dtype=np.float32) r_bare = -1j * vel * epsilon_inv energies_grad = np.einsum('asii->asi', vel) epsilon_gd = energies_grad[:, :, :, None] - energies_grad[:, :, None, :] #asij r_bare_gd = (commutator(r_bare[:, None], vel) - epsilon_gd[:, None] * r_bare) * epsilon_inv r_bare = np.transpose(r_bare[:, :, nf - nv:nf + nc, nf - nv:nf + nc], axes=(1, 2, 3, 0)) r_bare_cv = np.asarray(r_bare[:, nv:nv + nc, 0:nv].reshape( (-1, self.dim)), order='C') vel_bare = np.transpose(vel[:, :, nf - nv:nf + nc, nf - nv:nf + nc], axes=(1, 2, 3, 0)) vel_bare_cv = np.asarray(vel_bare[:, nv:nv + nc, 0:nv].reshape( (-1, self.dim)), order='C') self.r_bare = np.asarray(np.transpose(r_bare, axes=(3, 0, 1, 2)), order='F') self.vel_bare = np.asarray(np.transpose(vel_bare, axes=(3, 0, 1, 2)), order='F') self.r_bare_gd = np.asarray(r_bare_gd[:, :, :, nf - nv:nf + nc, nf - nv:nf + nc], order='F') self.epsilon = np.asarray(epsilon[:, nf - nv:nf + nc, nf - nv:nf + nc], order='F') self.epsilon_gd = np.asarray(epsilon_gd[:, :, nf - nv:nf + nc, nf - nv:nf + nc], order='F') self.r_bare_cv = r_bare_cv self.vel_bare_cv = vel_bare_cv print("r_bare solved")
def renormalize(t_pm, op_bare, f=1, grad=False, r_bare=None, op_bare_gd=None): if grad & ((len(t_pm) == 1) | (r_bare is None) | (op_bare_gd is None)): print( 'not given enough data to calculated op_rm_gd, only op_rm will be returned' ) grad = False temp = np.copy(t_pm, order='K') temp *= f[:, :, None, None] t = np.transpose(temp[..., 0], axes=(5, 0, 1, 2, 3, 4)) #basijo->obasij t += np.transpose(temp[..., 1], axes=(5, 0, 1, 2, 4, 3)).conj() if grad: for t_o in t: t_o[1:] += 1j * commutator(r_bare[:, None], t_o[0]) t_o[0] += op_bare t_o[1:] += op_bare_gd return t[:, 0], t[:, 1:] else: t[:, 0] += op_bare return t[:, 0]
def shg_vg(omega, vel, vel2, epsilon, f_ij): h = vel / (omega - epsilon) g = h * (f_ij.T) h2 = vel2 / (-2 * omega - epsilon) res = np.tensordot(h2, commutator(vel[:, None], g), ((1, 2, 3), (2, 4, 3))) return -res