Beispiel #1
0
/*----------------------------------------------------------*/
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;
}
Beispiel #2
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;
}