def getXC(gr,nel,**kwargs): "Form the exchange-correlation matrix" functional = kwargs.get('functional','SVWN') do_grad_dens = need_gradients[functional] do_spin_polarized = kwargs.get('do_spin_polarized') gr.floor_density() # Insure that the values of the density don't underflow gr.renormalize(nel) # Renormalize to the proper # electrons dens = gr.dens() weight = gr.weights() gamma = gr.get_gamma() npts = len(dens) if gr.version == 1: amdens = zeros((2,npts),'d') amgamma = zeros((3,npts),'d') amdens[0,:] = amdens[1,:] = 0.5*dens if gamma is not None: amgamma[0,:] = amgamma[1,:] = amgamma[2,:] = 0.25*gamma elif gr.version == 2: amdens = gr.density.T amgamma = gr.gamma.T fxc,dfxcdna,dfxcdnb,dfxcdgaa,dfxcdgab,dfxcdgbb = XC(amdens,amgamma,**kwargs) Exc = dot(weight,fxc) wva = weight*dfxcdna # Combine w*v in a vector for multiplication by bfs # First do the part that doesn't depend upon gamma nbf = gr.get_nbf() Fxca = zeros((nbf,nbf),'d') for i in xrange(nbf): wva_i = wva*gr.bfgrid[:,i] for j in xrange(nbf): Fxca[i,j] = dot(wva_i,gr.bfgrid[:,j]) # Now do the gamma-dependent part. # Fxc_a += dot(2 dfxcdgaa*graddensa + dfxcdgab*graddensb,grad(chia*chib)) # We can do the dot product as # sum_grid sum_xyz A[grid,xyz]*B[grid,xyz] # or a 2d trace product # Here A contains the dfxcdgaa stuff # B contains the grad(chia*chib) # Possible errors: gr.grad() here should be the grad of the b part? if do_grad_dens: # A,B are dimensioned (npts,3) A = transpose(0.5*transpose(gr.grad())*(weight*(2*dfxcdgaa+dfxcdgab))) for a in xrange(nbf): for b in xrange(a+1): B = gr.grad_bf_prod(a,b) Fxca[a,b] += sum(ravel(A*B)) Fxca[b,a] = Fxca[a,b] if not do_spin_polarized: return Exc,Fxca wvb = weight*dfxcdnb # Combine w*v in a vector for multiplication by bfs # First do the part that doesn't depend upon gamma Fxcb = zeros((nbf,nbf),'d') for i in xrange(nbf): wvb_i = wvb*gr.bfgrid[:,i] for j in xrange(nbf): Fxcb[i,j] = dot(wvb_i,gr.bfgrid[:,j]) # Now do the gamma-dependent part. # Fxc_b += dot(2 dfxcdgbb*graddensb + dfxcdgab*graddensa,grad(chia*chib)) # We can do the dot product as # sum_grid sum_xyz A[grid,xyz]*B[grid,xyz] # or a 2d trace product # Here A contains the dfxcdgaa stuff # B contains the grad(chia*chib) # Possible errors: gr.grad() here should be the grad of the b part? if do_grad_dens: # A,B are dimensioned (npts,3) A = transpose(0.5*transpose(gr.grad())*(weight*(2*dfxcdgbb+dfxcdgab))) for a in xrange(nbf): for b in xrange(a+1): B = gr.grad_bf_prod(a,b) Fxcb[a,b] += sum(ravel(A*B)) Fxcb[b,a] = Fxcb[a,b] return Exc,Fxca,Fxcb
def getXC(gr, nel, **kwargs): "Form the exchange-correlation matrix" functional = kwargs.get('functional', 'SVWN') do_grad_dens = need_gradients[functional] do_spin_polarized = kwargs.get('do_spin_polarized') gr.floor_density() # Insure that the values of the density don't underflow gr.renormalize(nel) # Renormalize to the proper # electrons dens = gr.dens() weight = gr.weights() gamma = gr.get_gamma() npts = len(dens) if gr.version == 1: amdens = zeros((2, npts), 'd') amgamma = zeros((3, npts), 'd') amdens[0, :] = amdens[1, :] = 0.5 * dens if gamma is not None: amgamma[0, :] = amgamma[1, :] = amgamma[2, :] = 0.25 * gamma elif gr.version == 2: amdens = gr.density.T amgamma = gr.gamma.T fxc, dfxcdna, dfxcdnb, dfxcdgaa, dfxcdgab, dfxcdgbb = XC( amdens, amgamma, **kwargs) Exc = dot(weight, fxc) wva = weight * dfxcdna # Combine w*v in a vector for multiplication by bfs # First do the part that doesn't depend upon gamma nbf = gr.get_nbf() Fxca = zeros((nbf, nbf), 'd') for i in xrange(nbf): wva_i = wva * gr.bfgrid[:, i] for j in xrange(nbf): Fxca[i, j] = dot(wva_i, gr.bfgrid[:, j]) # Now do the gamma-dependent part. # Fxc_a += dot(2 dfxcdgaa*graddensa + dfxcdgab*graddensb,grad(chia*chib)) # We can do the dot product as # sum_grid sum_xyz A[grid,xyz]*B[grid,xyz] # or a 2d trace product # Here A contains the dfxcdgaa stuff # B contains the grad(chia*chib) # Possible errors: gr.grad() here should be the grad of the b part? if do_grad_dens: # A,B are dimensioned (npts,3) A = transpose(0.5 * transpose(gr.grad()) * (weight * (2 * dfxcdgaa + dfxcdgab))) for a in xrange(nbf): for b in xrange(a + 1): B = gr.grad_bf_prod(a, b) Fxca[a, b] += sum(ravel(A * B)) Fxca[b, a] = Fxca[a, b] if not do_spin_polarized: return Exc, Fxca wvb = weight * dfxcdnb # Combine w*v in a vector for multiplication by bfs # First do the part that doesn't depend upon gamma Fxcb = zeros((nbf, nbf), 'd') for i in xrange(nbf): wvb_i = wvb * gr.bfgrid[:, i] for j in xrange(nbf): Fxcb[i, j] = dot(wvb_i, gr.bfgrid[:, j]) # Now do the gamma-dependent part. # Fxc_b += dot(2 dfxcdgbb*graddensb + dfxcdgab*graddensa,grad(chia*chib)) # We can do the dot product as # sum_grid sum_xyz A[grid,xyz]*B[grid,xyz] # or a 2d trace product # Here A contains the dfxcdgaa stuff # B contains the grad(chia*chib) # Possible errors: gr.grad() here should be the grad of the b part? if do_grad_dens: # A,B are dimensioned (npts,3) A = transpose(0.5 * transpose(gr.grad()) * (weight * (2 * dfxcdgbb + dfxcdgab))) for a in xrange(nbf): for b in xrange(a + 1): B = gr.grad_bf_prod(a, b) Fxcb[a, b] += sum(ravel(A * B)) Fxcb[b, a] = Fxcb[a, b] return Exc, Fxca, Fxcb