def apply_l0(self, sab, comega=1j * 0.0): """ This applies the non-interacting four point Green's function to a suitable vector (e.g. dipole matrix elements)""" assert sab.size == (self.norbs2), "%r,%r" % (sab.size, self.norbs2) sab = sab.reshape([self.norbs, self.norbs]) self.l0_ncalls += 1 nb2v = np.dot(self.xocc, sab) nm2v = blas.cgemm(1.0, nb2v, np.transpose(self.xvrt)) if use_numba: div_eigenenergy_numba(self.ksn2e, self.ksn2f, self.nfermi, self.vstart, comega, nm2v.real, nm2v.imag, self.ksn2e.shape[2]) else: for n, [en, fn] in enumerate( zip(self.ksn2e[0, 0, :self.nfermi], self.ksn2f[0, 0, :self.nfermi])): for j, [em, fm] in enumerate( zip(self.ksn2e[0, 0, n + 1:], self.ksn2f[0, 0, n + 1:])): m = j + n + 1 - self.vstart nm2v[n,m] = nm2v[n,m] * (fn-fm) *\ ( 1.0 / (comega - (em - en)) - 1.0 / (comega + (em - en)) ) nb2v = blas.cgemm(1.0, nm2v, self.xvrt) ab2v = blas.cgemm(1.0, np.transpose(self.xocc), nb2v) return ab2v
def computeQ(kij, vels, om, idsl, idsr, nl, nr, tn, dt, s): """ Compute the spectral heat current across the interface """ vfft = np.fft.fft(vels, axis=0) * dt qom = np.zeros(tn).astype(complex) vl = np.zeros((tn, nl * 3)).astype(complex) vr = np.zeros((tn, nr * 3)).astype(complex) vl[:, 0::3] = vfft[:, idsl * 3] vl[:, 1::3] = vfft[:, idsl * 3 + 1] vl[:, 2::3] = vfft[:, idsl * 3 + 2] vr[:, 0::3] = vfft[:, idsr * 3] vr[:, 1::3] = vfft[:, idsr * 3 + 1] vr[:, 2::3] = vfft[:, idsr * 3 + 2] vl = np.asfortranarray(vl) vr = np.asfortranarray(vr) kij = np.asfortranarray(kij) print('\n\tNow computing heat current for block ' + str(s + 1) + '\n') num = tn / 10 for j in range(tn): if j != 0 and j % (num) == 0: #print progress updates print('\t\tNow ' + str(10 * np.round(j / num, decimals=1)) + '% done computing heat current for block ' + str(s + 1)) if j == 0: qom[j] = 0 + 0j else: qom[j] = -(blas.cgemm((1 + 0j), vr[j, None].conj(), blas.cgemm( (1 + 0j), kij, vl[j, None].T))) / om[j] return qom
def apply_l0(self, sab, comega=1j * 0.0): """ This applies the non-interacting four point Green's function to a suitable vector (e.g. dipole matrix elements)""" assert sab.size == (self.nspin * self.norbs2) self.l0_ncalls += 1 sab = sab.reshape((self.nspin, self.norbs, self.norbs)) ab2v = np.zeros_like(sab, dtype=self.dtypeComplex) for s, (ab, xv, xo, x, n2e, n2f) in enumerate( zip(sab, self.xvrt_l0, self.xocc_l0, self.x_l0, self.ksn2e_l0, self.ksn2f_l0)): nm2v = zeros((self.norbs, self.norbs), self.dtypeComplex) nm2v[self.vstart_l0[s]:, :self.nfermi_l0[s]] = blas.cgemm( 1.0, dot(xv, ab), xo.T) nm2v[:self.nfermi_l0[s], self.vstart_l0[s]:] = blas.cgemm(1.0, dot(xo, ab), xv.T) for n, (en, fn) in enumerate(zip(n2e, n2f)): for m, (em, fm) in enumerate(zip(n2e, n2f)): nm2v[n, m] = nm2v[n, m] * (fn - fm) / (comega - (em - en)) nb2v = blas.cgemm(1.0, nm2v, x) ab2v[s] += blas.cgemm(1.0, x.T, nb2v) return ab2v.reshape(-1)
def apply_l0_ref(self, sab, comega=1j*0.0): """ This applies the non-interacting four point Green's function to a suitable vector (e.g. dipole matrix elements)""" assert sab.size==(self.norbs2), "%r,%r"%(sab.size,self.norbs2) sab = sab.reshape([self.norbs,self.norbs]) self.l0_ncalls+=1 nb2v = dot(self.x[0], sab) nm2v = blas.cgemm(1.0, nb2v, self.x[0].T) for n,[en,fn] in enumerate(zip(self.ksn2e[0,0,:],self.ksn2f[0,0,:])): for m,[em,fm] in enumerate(zip(self.ksn2e[0,0,:],self.ksn2f[0,0,:])): nm2v[n,m] = nm2v[n,m] * (fn-fm) * ( 1.0 / (comega - (em - en))) nb2v = blas.cgemm(1.0, nm2v, self.x[0]) ab2v = blas.cgemm(1.0, self.x[0].T, nb2v) return ab2v
def apply_l0_exp(self, sab, comega=1j*0.0): """ This applies the non-interacting four point Green's function to a suitable vector (e.g. dipole matrix elements)""" assert sab.size==(self.norbs2), "%r,%r"%(sab.size,self.norbs2) sab = sab.reshape([self.norbs,self.norbs]) self.l0_ncalls+=1 nb2v = dot(self.x[0], sab) nm2v = blas.cgemm(1.0, nb2v, self.x[0].T) print(nm2v.dtype) print(nm2v[self.vstart[0]:, :self.nfermi[0]]) print(nm2v[:self.nfermi[0], self.vstart[0]:]) nm2v = zeros((self.norbs,self.norbs), self.dtypeComplex) nb2v1 = dot(self.xocc[0], sab) nm2v1 = blas.cgemm(1.0, nb2v1, self.xvrt[0].T) nb2v2 = dot(self.xvrt[0], sab) nm2v2 = blas.cgemm(1.0, nb2v2, self.xocc[0].T) nm2v[self.vstart[0]:, :self.nfermi[0]] = nm2v2 nm2v[:self.nfermi[0], self.vstart[0]:] = nm2v1 print(nm2v.dtype, nm2v1.shape, nm2v1.dtype) print(nm2v[self.vstart[0]:, :self.nfermi[0]]) print(nm2v[:self.nfermi[0], self.vstart[0]:]) #raise RuntimeError('11') #nm2v2 = np.copy(nm2v1) #for n,[en,fn] in enumerate(zip(self.ksn2e[0,0,:self.nfermi],self.ksn2f[0,0,:self.nfermi])): #for m,[em,fm] in enumerate(zip(self.ksn2e[0,0,self.vstart:],self.ksn2f[0,0,self.vstart:])): #nm2v1[n,m] = nm2v1[n,m] * (fn-fm) * ( 1.0 / (comega - (em - en))) #for n,[en,fn] in enumerate(zip(self.ksn2e[0,0,:self.nfermi],self.ksn2f[0,0,:self.nfermi])): #for m,[em,fm] in enumerate(zip(self.ksn2e[0,0,self.vstart:],self.ksn2f[0,0,self.vstart:])): #nm2v2[n,m] = nm2v2[n,m] * (fm-fn) * ( 1.0 / (comega - (en - em))) for n,[en,fn] in enumerate(zip(self.ksn2e[0,0,:],self.ksn2f[0,0,:])): for m,[em,fm] in enumerate(zip(self.ksn2e[0,0,:],self.ksn2f[0,0,:])): nm2v[n,m] = nm2v[n,m] * (fn-fm) * ( 1.0 / (comega - (em - en))) nb2v = blas.cgemm(1.0, nm2v, self.x[0]) ab2v = blas.cgemm(1.0, self.x[0].T, nb2v) return ab2v
def apply_rf0(self, v, comega=1j * 0.0): """ This applies the non-interacting response function to a vector (a set of vectors?) """ assert len(v) == len(self.moms0), "%r, %r " % (len(v), len(self.moms0)) self.rf0_ncalls += 1 # np.require may perform a copy of v, is it really necessary?? vdp = self.cc_da * np.require(v, dtype=np.complex64) no = self.norbs sab = csr_matrix((np.transpose(vdp) * self.v_dab).reshape([no, no])) if self.tddft_iter_gpu.GPU: vdp = self.tddft_iter_gpu.apply_rf0_gpu(self.xocc, sab, comega) else: # # WARNING!!!! # nb2v is column major, while self.xvrt is row major # What a mess!! nb2v = self.xocc * sab nm2v = blas.cgemm(1.0, nb2v, np.transpose(self.xvrt)) if use_numba: div_eigenenergy_numba(self.ksn2e, self.ksn2f, self.nfermi, self.vstart, comega, nm2v, self.ksn2e.shape[2]) else: for n, [en, fn] in enumerate( zip(self.ksn2e[0, 0, :self.nfermi], self.ksn2f[0, 0, :self.nfermi])): for j, [em, fm] in enumerate( zip(self.ksn2e[0, 0, n + 1:], self.ksn2f[0, 0, n + 1:])): m = j + n + 1 - self.vstart nm2v[n,m] = nm2v[n,m] * (fn-fm) *\ ( 1.0 / (comega - (em - en)) - 1.0 / (comega + (em - en)) ) nb2v = blas.cgemm(1.0, nm2v, self.xvrt) ab2v = blas.cgemm(1.0, np.transpose(self.xocc), nb2v).reshape(no * no) vdp = self.v_dab * ab2v return vdp * self.cc_da
def apply_l0_ref(self, sab, comega=1j * 0.0): """ This applies the non-interacting four point Green's function to a suitable vector (e.g. dipole matrix elements)""" assert sab.size == (self.nspin * self.norbs2) self.l0_ncalls += 1 sab = sab.reshape((self.nspin, self.norbs, self.norbs)) ab2v = np.zeros_like(sab, dtype=self.dtypeComplex) for s in range(self.nspin): nb2v = dot(self.x_l0[s], sab[s]) nm2v = blas.cgemm(1.0, nb2v, self.x_l0[s].T) for n, [en, fn] in enumerate( zip(self.ksn2e_l0[s, :], self.ksn2f_l0[s, :])): for m, [em, fm] in enumerate( zip(self.ksn2e_l0[s, :], self.ksn2f_l0[s, :])): nm2v[n, m] = nm2v[n, m] * (fn - fm) * (1.0 / (comega - (em - en))) nb2v = blas.cgemm(1.0, nm2v, self.x_l0[s]) ab2v[s] += blas.cgemm(1.0, self.x_l0[s].T, nb2v) return ab2v.reshape(-1)
def apply_l0_spin_non_diag(self, sab, comega=1j * 0.0): """ The definition of L0 which is not spin-diagonal even for parallel-spin references""" assert sab.size == (self.nspin * self.norbs2) self.l0_ncalls += 1 sab = sab.reshape((self.nspin, self.norbs, self.norbs)) ab2v = np.zeros_like(sab, dtype=self.dtypeComplex) for ns in range(self.nspin): for ms in range(self.nspin): nb2v = dot(self.x_l0[ns], sab[ns]) nm2v = blas.cgemm(1.0, nb2v, self.x_l0[ms].T) for n, [en, fn] in enumerate( zip(self.ksn2e_l0[ns, :], self.ksn2f_l0[ns, :])): for m, [em, fm] in enumerate( zip(self.ksn2e_l0[ms, :], self.ksn2f_l0[ms, :])): nm2v[n, m] = nm2v[n, m] * (fn - fm) * (1.0 / (comega - (em - en))) nb2v = blas.cgemm(1.0, nm2v, self.x_l0[ms]) ab2v[ns] += blas.cgemm(0.5, self.x_l0[ns].T, nb2v) return ab2v.reshape(-1)
vk = np.asfortranarray(vk[freq, :].T) for i in range(1): #nl) #loop over left atoms if i != 0 and i % (nl / 10) == 0: #print progress updates print('\t\tNow ' + str(10 * np.round(i / (nl / 10), 1)) + '% done ' 'comptuting spectral conductance for block ' + str(s + 1)) phix = np.asfortranarray(fijk[i * 3, ...]) #phi on i in x phiy = np.asfortranarray(fijk[i * 3 + 1, ...]) #phi on i in y phiz = np.asfortranarray(fijk[i * 3 + 2, ...]) #phi on i in z #faster to compute this dot product only once per atom for w in range(nfreq): #loop over omega prime pxdotvk[:, w] = blas.cgemm((1 + 0j), phix, vk[:, w]).reshape(nr * 3) pydotvk[:, w] = blas.cgemm((1 + 0j), phiy, vk[:, w]).reshape(nr * 3) pzdotvk[:, w] = blas.cgemm((1 + 0j), phiz, vk[:, w]).reshape(nr * 3) # vj = np.flipud(vj[freq,:]).conj() #(freqmax,-freqmax) # vj = np.roll(vj,1,axis=0) #roll once to start at 0 in the loop # om = om[freq] # omp = np.roll(np.flipud(om),1,axis=0) # for w in range(nfreq): # if w != 0 and w%(nfreq/100) == 0: #print progress updates # print('\t\tNow '+str(np.round(w/(nfreq/100),1))+'% done ' # 'comptuting the etc term for block '+str(s+1)) # fx.toc() #
rvelsfft[:,1::3] = velsfft[:,idsR*3+1] #vy rvelsfft[:,2::3] = velsfft[:,idsR*3+2] #vz ######################################## lvelsfft = np.asfortranarray(lvelsfft) #faster blas dot product rvelsfft = np.asfortranarray(rvelsfft) #faster blas dot product kij = np.asfortranarray(kij) #faster blas dot product for j in range(tn): if j%(tn/10) == 0: print('\t\t'+str(((j/(tn/10))+1)*10)+'% done with chunk '+ str(i+1)) if j == 0: #avoid divide by zero qom[j,0] = 0+0j else: qom[j,0] = -(blas.cgemm((1+0j),lvelsfft[j,np.newaxis], blas.cgemm((1+0j),kij,rvelsfft[j,np.newaxis].conj().T)) /om[j]) ####################################### # for j in range(tn): # if j%(tn/10) == 0: # print('\t\t'+str(((j/(tn/10))+1)*10)+'% done with chunk '+ # str(i+1)) # if j == 0: #avoid divide by zero # qom[j,0] = 0+0j # else: # qom[j,0] = -(np.dot(lvelsfft[j,:], # np.dot(kij,rvelsfft[j,:].transpose().conj()))/om[j]) qom = -2*1j*qom/(tn*dt*dn) qom = qom*1.602e-19/1e-24 #convert to J/s. Units are F*v^2 =