/*----------------------------------------------------------*/ int main(int argc, char *argv[]) { xc_values_type xc; xc_lda_type lda_func; xc_gga_type gga_func; xc_hyb_gga_type hyb_gga_func; const xc_func_info_type *info; FLOAT *pv2rho = NULL; if(argc != 8){ printf("Usage:\n%s funct pol rhoa rhob sigmaaa sigmaab sigmabb\n", argv[0]); return 1; } init_values(&xc, argv); if(xc.nspin == 1){ xc.rho[0] += xc.rho[1]; xc.sigma[0] += 2.0*xc.sigma[1] + xc.sigma[2]; } info = NULL; switch(xc_family_from_id(xc.functional)) { case XC_FAMILY_LDA: if(xc.functional == XC_LDA_X) xc_lda_x_init(&lda_func, xc.nspin, 3, 0); else xc_lda_init(&lda_func, xc.functional, xc.nspin); info = lda_func.info; break; case XC_FAMILY_GGA: xc_gga_init(&gga_func, xc.functional, xc.nspin); info = gga_func.info; break; case XC_FAMILY_HYB_GGA: xc_hyb_gga_init(&hyb_gga_func, xc.functional, xc.nspin); info = hyb_gga_func.info; break; default: fprintf(stderr, "Functional '%d' not found\n", xc.functional); exit(1); } if(info->provides & XC_PROVIDES_FXC){ pv2rho = xc.v2rho; } switch(xc_family_from_id(xc.functional)) { case XC_FAMILY_LDA: xc_lda(&lda_func, xc.rho, &xc.zk, xc.vrho, pv2rho, NULL); break; case XC_FAMILY_GGA: xc_gga(&gga_func, xc.rho, xc.sigma, &xc.zk, xc.vrho, xc.vsigma, pv2rho, xc.v2rhosigma, xc.v2sigma); xc_gga_end(&gga_func); break; case XC_FAMILY_HYB_GGA: xc_hyb_gga(&hyb_gga_func, xc.rho, xc.sigma, &xc.zk, xc.vrho, xc.vsigma); xc_hyb_gga_end(&hyb_gga_func); break; } if(xc.nspin == 1){ xc.vrho[1] = xc.vrho[0]; xc.zk *= xc.rho[0] ; }else{ xc.zk *= (xc.rho[0] + xc.rho[1]); } print_values(&xc); return 0; }
/* * rho_u/rho_d = (den,grad_x,grad_y,grad_z,laplacian,tau) * In spin restricted case (spin == 1), rho_u is assumed to be the * spin-free quantities, rho_d is not used. */ static int _eval_xc(xc_func_type *func_x, int spin, int np, double *rho_u, double *rho_d, double *ex, double *vxc, double *fxc, double *kxc) { int i; double *rho, *sigma, *lapl, *tau; double *gxu, *gyu, *gzu, *gxd, *gyd, *gzd; double *lapl_u, *lapl_d, *tau_u, *tau_d; double *vsigma = NULL; double *vlapl = NULL; double *vtau = NULL; double *v2rhosigma = NULL; double *v2sigma2 = NULL; double *v2lapl2 = NULL; double *v2tau2 = NULL; double *v2rholapl = NULL; double *v2rhotau = NULL; double *v2sigmalapl = NULL; double *v2sigmatau = NULL; double *v2lapltau = NULL; double *v3rho2sigma = NULL; double *v3rhosigma2 = NULL; double *v3sigma3 = NULL; switch (func_x->info->family) { case XC_FAMILY_LDA: // ex is the energy density // NOTE libxc library added ex/ec into vrho/vcrho if (spin == XC_POLARIZED) { rho = malloc(sizeof(double) * np*2); for (i = 0; i < np; i++) { rho[i*2+0] = rho_u[i]; rho[i*2+1] = rho_d[i]; } xc_lda(func_x, np, rho, ex, vxc, fxc, kxc); free(rho); } else { rho = rho_u; xc_lda(func_x, np, rho, ex, vxc, fxc, kxc); } break; case XC_FAMILY_GGA: case XC_FAMILY_HYB_GGA: if (spin == XC_POLARIZED) { rho = malloc(sizeof(double) * np*2); sigma = malloc(sizeof(double) * np*3); gxu = rho_u + np; gyu = rho_u + np * 2; gzu = rho_u + np * 3; gxd = rho_d + np; gyd = rho_d + np * 2; gzd = rho_d + np * 3; for (i = 0; i < np; i++) { rho[i*2+0] = rho_u[i]; rho[i*2+1] = rho_d[i]; sigma[i*3+0] = gxu[i]*gxu[i] + gyu[i]*gyu[i] + gzu[i]*gzu[i]; sigma[i*3+1] = gxu[i]*gxd[i] + gyu[i]*gyd[i] + gzu[i]*gzd[i]; sigma[i*3+2] = gxd[i]*gxd[i] + gyd[i]*gyd[i] + gzd[i]*gzd[i]; } if (vxc != NULL) { // vrho = vxc vsigma = vxc + np * 2; } if (fxc != NULL) { // v2rho2 = fxc v2rhosigma = fxc + np * 3; v2sigma2 = v2rhosigma + np * 6; // np*6 } if (kxc != NULL) { // v3rho3 = kxc v3rho2sigma = kxc + np * 4; v3rhosigma2 = v3rho2sigma + np * 9; v3sigma3 = v3rhosigma2 + np * 12; // np*10 } #if (XC_MAJOR_VERSION == 2 && XC_MINOR_VERSION < 2) xc_gga(func_x, np, rho, sigma, ex, vxc, vsigma, fxc, v2rhosigma, v2sigma2); #else xc_gga(func_x, np, rho, sigma, ex, vxc, vsigma, fxc, v2rhosigma, v2sigma2, kxc, v3rho2sigma, v3rhosigma2, v3sigma3); #endif free(rho); free(sigma); } else { rho = rho_u; sigma = malloc(sizeof(double) * np); gxu = rho_u + np; gyu = rho_u + np * 2; gzu = rho_u + np * 3; for (i = 0; i < np; i++) { sigma[i] = gxu[i]*gxu[i] + gyu[i]*gyu[i] + gzu[i]*gzu[i]; } if (vxc != NULL) { vsigma = vxc + np; } if (fxc != NULL) { v2rhosigma = fxc + np; v2sigma2 = v2rhosigma + np; } if (kxc != NULL) { v3rho2sigma = kxc + np; v3rhosigma2 = v3rho2sigma + np; v3sigma3 = v3rhosigma2 + np; } #if (XC_MAJOR_VERSION == 2 && XC_MINOR_VERSION < 2) xc_gga(func_x, np, rho, sigma, ex, vxc, vsigma, fxc, v2rhosigma, v2sigma2); #else xc_gga(func_x, np, rho, sigma, ex, vxc, vsigma, fxc, v2rhosigma, v2sigma2, kxc, v3rho2sigma, v3rhosigma2, v3sigma3); #endif free(sigma); } break; case XC_FAMILY_MGGA: case XC_FAMILY_HYB_MGGA: if (spin == XC_POLARIZED) { rho = malloc(sizeof(double) * np*2); sigma = malloc(sizeof(double) * np*3); lapl = malloc(sizeof(double) * np*2); tau = malloc(sizeof(double) * np*2); gxu = rho_u + np; gyu = rho_u + np * 2; gzu = rho_u + np * 3; gxd = rho_d + np; gyd = rho_d + np * 2; gzd = rho_d + np * 3; lapl_u = rho_u + np * 4; tau_u = rho_u + np * 5; lapl_d = rho_d + np * 4; tau_d = rho_d + np * 5; for (i = 0; i < np; i++) { rho[i*2+0] = rho_u[i]; rho[i*2+1] = rho_d[i]; sigma[i*3+0] = gxu[i]*gxu[i] + gyu[i]*gyu[i] + gzu[i]*gzu[i]; sigma[i*3+1] = gxu[i]*gxd[i] + gyu[i]*gyd[i] + gzu[i]*gzd[i]; sigma[i*3+2] = gxd[i]*gxd[i] + gyd[i]*gyd[i] + gzd[i]*gzd[i]; lapl[i*2+0] = lapl_u[i]; lapl[i*2+1] = lapl_d[i]; tau[i*2+0] = tau_u[i]; tau[i*2+1] = tau_d[i]; } if (vxc != NULL) { // vrho = vxc vsigma = vxc + np * 2; vlapl = vsigma + np * 3; vtau = vlapl + np * 2; // np*2 } if (fxc != NULL) { // v2rho2 = fxc v2rhosigma = fxc + np * 3; v2sigma2 = v2rhosigma + np * 6; v2lapl2 = v2sigma2 + np * 6; v2tau2 = v2lapl2 + np * 3; v2rholapl = v2tau2 + np * 3; v2rhotau = v2rholapl + np * 4; v2lapltau = v2rhotau + np * 4; v2sigmalapl = v2lapltau + np * 4; v2sigmatau = v2sigmalapl + np * 6; // np*6 } xc_mgga(func_x, np, rho, sigma, lapl, tau, ex, vxc, vsigma, vlapl, vtau, fxc, v2sigma2, v2lapl2, v2tau2, v2rhosigma, v2rholapl, v2rhotau, v2sigmalapl, v2sigmatau, v2lapltau); free(rho); free(sigma); free(lapl); free(tau); } else { rho = rho_u; sigma = malloc(sizeof(double) * np); lapl = rho_u + np * 4; tau = rho_u + np * 5; gxu = rho_u + np; gyu = rho_u + np * 2; gzu = rho_u + np * 3; for (i = 0; i < np; i++) { sigma[i] = gxu[i]*gxu[i] + gyu[i]*gyu[i] + gzu[i]*gzu[i]; } if (vxc != NULL) { vsigma = vxc + np; vlapl = vsigma + np; vtau = vlapl + np; } if (fxc != NULL) { v2rhosigma = fxc + np; v2sigma2 = v2rhosigma + np; v2lapl2 = v2sigma2 + np; v2tau2 = v2lapl2 + np; v2rholapl = v2tau2 + np; v2rhotau = v2rholapl + np; v2lapltau = v2rhotau + np; v2sigmalapl = v2lapltau + np; v2sigmatau = v2sigmalapl + np; } xc_mgga(func_x, np, rho, sigma, lapl, tau, ex, vxc, vsigma, vlapl, vtau, fxc, v2sigma2, v2lapl2, v2tau2, v2rhosigma, v2rholapl, v2rhotau, v2sigmalapl, v2sigmatau, v2lapltau); free(sigma); } break; default: fprintf(stderr, "functional %d '%s' is not implmented\n", func_x->info->number, func_x->info->name); exit(1); } return 1; }