Esempio n. 1
0
bool needs_VV10(int func_id, double & b, double & C) {
  b=0.0;
  C=0.0;
  
  bool ret=false;
#ifdef XC_FLAGS_VV10
  if(func_id>0) {
    xc_func_type func;
    if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0){
      ERROR_INFO();
      std::ostringstream oss;
      oss << "Functional "<<func_id<<" not found!";
      throw std::runtime_error(oss.str());
    }
    // Get flag
    ret=func.info->flags & XC_FLAGS_VV10;
    if(ret)
      XC(nlc_coef)(&func, &b, &C);
    // Free functional
    xc_func_end(&func);
  }
#endif
  
  return ret;
}
Esempio n. 2
0
bool laplacian_needed(int func_id) {
  // Is gradient necessary?

  bool lapl=0;

  if(func_id>0) {
    xc_func_type func;
    if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0){
      ERROR_INFO();
      std::ostringstream oss;
      oss << "Functional "<<func_id<<" not found!";
      throw std::runtime_error(oss.str());
    }

    switch(func.info->family)
      {
      case XC_FAMILY_MGGA:
      case XC_FAMILY_HYB_MGGA:
	lapl=1;
	break;
      }
    // Free functional
    xc_func_end(&func);
  }

  return lapl;
}
Esempio n. 3
0
bool is_range_separated(int func_id, bool check) {
  bool ans=false;
  
  if(func_id>0) {
    xc_func_type func;
    if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0){
      ERROR_INFO();
      std::ostringstream oss;
      oss << "Functional "<<func_id<<" not found!";
      throw std::runtime_error(oss.str());
    }
    // Get flag
    ans=func.info->flags & XC_FLAGS_HYB_CAM;
    // Free functional
    xc_func_end(&func);
  }

  if(check) {
    // Sanity check
    double w, a, b;
    range_separation(func_id,w,a,b);
    
    if(ans && w==0.0)
      fprintf(stderr,"Error in libxc detected - functional is marked range separated but with vanishing omega!\n");
    else if(!ans && w!=0.0)
      fprintf(stderr,"Error in libxc detected - functional is not marked range separated but has nonzero omega!\n");
  }
  
  return ans;
}
Esempio n. 4
0
bool is_kinetic(int func_id) {
  bool ans=0;

  if(func_id>0) {
    xc_func_type func;
    if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0){
      ERROR_INFO();
      std::ostringstream oss;
      oss << "Functional "<<func_id<<" not found!";
      throw std::runtime_error(oss.str());
    }

    switch(func.info->kind)
      {
	/* By default we assign exchange-correlation functionals as
	   the exchange functional, since we check whether the
	   exchange part includes exact exchange. */
      case XC_KINETIC:
	ans=1;
	break;
      default:
	ans=0;
      }
    // Free functional
    xc_func_end(&func);
  } else
    // Dummy correlation
    ans=0;

  return ans;
}
Esempio n. 5
0
double exact_exchange(int func_id) {
  // Default - no exact exchange.
  double f=0.0;

  if(func_id>0) {
    xc_func_type func;
    if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0){
      ERROR_INFO();
      std::ostringstream oss;
      oss << "Functional "<<func_id<<" not found!";
      throw std::runtime_error(oss.str());
    }

    switch(func.info->family)
      {
      case XC_FAMILY_HYB_GGA:
      case XC_FAMILY_HYB_MGGA:
	// libxc prior to 2.0.0
	// f=xc_hyb_gga_exx_coef(func.gga);
	// libxc 2.0.0
	f=xc_hyb_exx_coef(&func);
	break;
      }

    xc_func_end(&func);
  }

  //  printf("Fraction of exact exchange is %f.\n",f);

  return f;
}
Esempio n. 6
0
void test_neg_rho()
{
  xc_func_type func;
  double rho[5][2] = { {9.03897273e-06,-1.00463992e-06}, 
		       {8.48383564e-06,-3.51231267e-07}, 
		       {1.45740621e-08,-2.94546705e-09}, 
		       {2.62778445e-07, -1.00191745e-07}, 
		       {2.55745103e-06, -1.54789964e-06} };
  double sigma[5][3] = { {1.20122271e-08,4.83240746e-09,6.24774836e-09}, 
			 {1.54146602e-07,1.41584609e-07,1.36663204e-07}, 
			 {2.75312438e-08,2.75224049e-08,2.75135719e-08}, 
			 {1.90251649e-07,1.91241798e-07,1.92240989e-07}, 
			 {9.29562712e-09,7.83940082e-09, 8.05714636e-09} };
  double vsigma[5][3];
  double zk[5], vk[5][2];
  int i, func_id;

  for(func_id=1; func_id<1000; func_id++){
    if(xc_func_init(&func, func_id, XC_POLARIZED) != 0) continue;
    if(func_id == XC_LDA_C_2D_PRM || func_id == XC_GGA_X_LB) goto end;

    printf("\n%s:\n", func.info->name);

    switch(func.info->family){
    case XC_FAMILY_LDA:
      xc_lda_exc_vxc(&func, 5, &rho[0][0], zk, &vk[0][0]);
      break;
    case XC_FAMILY_GGA:
      xc_gga_exc_vxc(&func, 5, &rho[0][0], &sigma[0][0], zk, &vk[0][0], &vsigma[0][0]);
      break;
    }

    switch(func.info->family){
    case XC_FAMILY_LDA:
      for(i=0; i<5; i+=1)
	printf("%.8e %.8e %.8e %.8e %.8e\n", 
	       rho[i][0], rho[i][1], zk[i], vk[i][0], vk[i][1]);
      break;
    case XC_FAMILY_GGA:
      for(i=0; i<5; i+=1)
	printf("%.8e %.8e %.8e %.8e %.8e %.8e %.8e %.8e %.8e %.8e %.8e\n", 
	       rho[i][0], rho[i][1], sigma[i][0], sigma[i][1], sigma[i][2], 
	       zk[i], vk[i][0], vk[i][1], vsigma[i][0], vsigma[i][1], vsigma[i][2]);
      break;
    }

  end:
    xc_func_end(&func);
  }
}
Esempio n. 7
0
int VXCnr_eval_x(int x_id, int spin, int relativity, int np,
                 double *rho_u, double *rho_d,
                 double *ex, double *vxc, double *fxc, double *kxc)
{
        xc_func_type func_x = {};
        if (xc_func_init(&func_x, x_id, spin) != 0) {
                fprintf(stderr, "X functional %d not found\n", x_id);
                exit(1);
        }
#if defined XC_SET_RELATIVITY
        xc_lda_x_set_params(&func_x, relativity);
#endif
        _eval_xc(&func_x, spin, np, rho_u, rho_d, ex, vxc, fxc, kxc);
        xc_func_end(&func_x);
        return 1;
}
Esempio n. 8
0
void is_gga_mgga(int func_id, bool & gga, bool & mgga) {
  // Initialize
  gga=false;
  mgga=false;

  // Correlation and exchange functionals
  xc_func_type func;
  if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0) {
    ERROR_INFO();
    std::ostringstream oss;
    oss << "Functional "<<func_id<<" not found!";
    throw std::runtime_error(oss.str());
  }  

  switch(func.info->family)
    {
    case XC_FAMILY_LDA:
      gga=false;
      mgga=false;
      break;

    case XC_FAMILY_GGA:
    case XC_FAMILY_HYB_GGA:
      gga=true;
      mgga=false;
      break;

    case XC_FAMILY_MGGA:
    case XC_FAMILY_HYB_MGGA:
      gga=false;
      mgga=true;
      break;

    default:
      {
        ERROR_INFO();
	std::ostringstream oss;
        oss << "Functional family " << func.info->family << " not currently supported in ERKALE!\n";
        throw std::runtime_error(oss.str());
      }
    }

  // Free functional
  xc_func_end(&func);
}
Esempio n. 9
0
bool has_exc(int func_id) {
  bool ans=false;

  if(func_id>0) {
    xc_func_type func;
    if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0){
      ERROR_INFO();
      std::ostringstream oss;
      oss << "Functional "<<func_id<<" not found!";
      throw std::runtime_error(oss.str());
    }
    // Get flag
    ans=func.info->flags & XC_FLAGS_HAVE_EXC;
    // Free functional
    xc_func_end(&func);
  }
  
  return ans;
}
Esempio n. 10
0
void range_separation(int func_id, double & omega, double & alpha, double & beta, bool check) {
  // Defaults
  omega=0.0;
  alpha=0.0;
  beta=0.0;

  if(func_id>0) {
    xc_func_type func;
    if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0){
      ERROR_INFO();
      std::ostringstream oss;
      oss << "Functional "<<func_id<<" not found!";
      throw std::runtime_error(oss.str());
    }

    switch(func.info->family)
      {
      case XC_FAMILY_HYB_GGA:
      case XC_FAMILY_HYB_MGGA:
	XC(hyb_cam_coef(&func,&omega,&alpha,&beta));
	break;
      }

    xc_func_end(&func);
  }

  bool ans=is_range_separated(func_id,false);
  if(check) {
    if(ans && omega==0.0) {
      fprintf(stderr,"Error in libxc detected - functional is marked range separated but with vanishing omega!\n");
      printf("Error in libxc detected - functional is marked range separated but with vanishing omega!\n");
    } else if(!ans && omega!=0.0) {
      fprintf(stderr,"Error in libxc detected - functional is not marked range separated but has nonzero omega!\n");
      printf("Error in libxc detected - functional is not marked range separated but has nonzero omega!\n");
    }
  }

  // Work around libxc bug
  if(!ans) {
    omega=0.0;
    beta=0.0;
  }
}
Esempio n. 11
0
int VXCnr_eval_c(int c_id, int spin, int relativity, int np,
                 double *rho_u, double *rho_d,
                 double *ex, double *vxc, double *fxc, double *kxc)
{
        int not0 = 1;
        xc_func_type func_c = {};
        if (xc_func_init(&func_c, c_id, spin) != 0) {
                fprintf(stderr, "C functional %d not found\n", c_id);
                exit(1);
        }
        if (!(func_c.info->family == XC_FAMILY_HYB_GGA ||
              func_c.info->family == XC_FAMILY_HYB_MGGA)) {
                not0 = 0;
#if defined XC_SET_RELATIVITY
        xc_lda_x_set_params(&func_c, relativity);
#endif
                _eval_xc(&func_c, spin, np, rho_u, rho_d, ex, vxc, fxc, kxc);
        }
        xc_func_end(&func_c);
        return not0;
}
Esempio n. 12
0
double VXChybrid_coeff(int xc_id, int spin)
{
        xc_func_type func;
        double factor;
        if(xc_func_init(&func, xc_id, spin) != 0){
                fprintf(stderr, "XC functional %d not found\n", xc_id);
                exit(1);
        }
        switch(func.info->family)
        {
                case XC_FAMILY_HYB_GGA:
                case XC_FAMILY_HYB_MGGA:
                        factor = xc_hyb_exx_coef(&func);
                        break;
                default:
                        factor = 0;
        }

        xc_func_end(&func);
        return factor;
}
Esempio n. 13
0
void print_info(int func_id) {
  if(func_id>0) {
    xc_func_type func;
    if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0) {
      ERROR_INFO();
      std::ostringstream oss;
      oss << "\nFunctional "<<func_id<<" not found!\n";
      throw std::runtime_error(oss.str());
    }

#if XC_MAJOR_VERSION < 3
    printf("'%s', defined in the reference(s):\n%s\n", func.info->name, func.info->refs);
#else
    printf("'%s', defined in the reference(s):\n", func.info->name);
    for(int i=0;i<5;i++)
      if(func.info->refs[i]!=NULL)
	printf("%s (DOI %s)\n",func.info->refs[i]->ref,func.info->refs[i]->doi);
#endif
    xc_func_end(&func);
  }
  if(!has_exc(func_id)) {
    printf("The functional doesn't have an energy density, so the calculated energy is incorrect.");
  }
}
Esempio n. 14
0
void test_functional(int functional)
{
  xc_func_type func;
  const xc_func_info_type *info;
  int i, j, k, p_max[6][5];
  double max_diff[6][5], avg_diff[6][5], val[5];

#if defined(HAVE_FEENABLEEXCEPT)
  feenableexcept(FE_INVALID | FE_OVERFLOW);
#endif

  /* initialize functional */
  if(xc_func_init(&func, functional, nspin) != 0){
    fprintf(stderr, "Functional '%d' not found\n", functional);
    exit(1);    
  }

  info = func.info;

  if(functional == XC_LDA_C_2D_PRM)
    xc_lda_c_2d_prm_set_params(&func, 10.0);
  
  for(k=0; k<6; k++)
    for(j=0; j<5; j++){
      avg_diff[k][j] = 0.0;
      
      p_max[k][j]    = 0;
      max_diff[k][j] = -1.0;
    }

  for(i=0; xc_trial_points[i][0]!=0.0; i++){
    double e, v_fd[5], f_fd[5][5], v_an[5], f_an[5][5];

    for(j=0; j<5; j++)
      v_fd[j] = v_an[j] = 0.0;

    get_val(xc_trial_points[i], val);

    /* first, get the analytic gradients */
    get_vxc(&func, val, &e, v_an);

    /* now get the numerical gradients */
    first_derivative(&func, val, v_fd, 0);

    if(info->flags & XC_FLAGS_HAVE_FXC){
      int i, j;
      
      /* initialize */
      for(i=0; i<5; i++)
	for(j=0; j<5; j++)
	  f_an[i][j] = f_fd[i][j] = 0.0;

      /* now get the second derivatives */
      second_derivatives(&func, val, f_fd);
      get_fxc(&func, val, f_an);
    }

    /* make statistics */
    for(j=0; j<5; j++){
      double diff = fabs(v_an[j] - v_fd[j]);

      /* do not test in case of spin unpolarized or if spin down is zero */
      if((nspin==1 || val[1]==0.0) && (j!=0 && j!=2))
	continue;

      avg_diff[0][j] += diff;
      if(diff > max_diff[0][j]){
	max_diff[0][j] = diff;
	p_max[0][j] = i;
      }

      if(info->flags & XC_FLAGS_HAVE_FXC){
	for(k=0; k<5; k++){
	  /* do not test in case of spin unpolarized or if spin down is zero */
	  if((nspin==1 || val[1]==0.0) && (k!=0 && k!=2))
	    continue;

	  diff = fabs(f_an[k][j] - f_fd[k][j]);

	  avg_diff[k+1][j] += diff;
	  if(diff > max_diff[k+1][j]){
	    max_diff[k+1][j] = diff;
	    p_max[k+1][j] = i;
	  }
	}
      }
    }

  }

  for(k=0; k<6; k++)
    for(j=0; j<5; j++){
      avg_diff[k][j] /= i;
    }

  /* print statistics */
  {
    double diff;
    int i, j;

    printf("Functional: %s\n", info->name);
    print_error("Avg.", "vrho", (avg_diff[0][0] + avg_diff[0][1])/2.0, NULL, NULL);
    j = (max_diff[0][0] > max_diff[0][1]) ? 0 : 1;
    get_val(xc_trial_points[p_max[0][j]], val);
    print_error("Max.", "vrho", max_diff[0][j], &func, val);

    if(info->family > XC_FAMILY_LDA){
      print_error("Avg.", "vsig", (avg_diff[0][2] + avg_diff[0][3] + avg_diff[0][4])/3.0, NULL, NULL);
      j = (max_diff[0][2] > max_diff[0][3]) ? 2 : 3;
      j = (max_diff[0][j] > max_diff[0][4]) ? j : 4;
      get_val(xc_trial_points[p_max[0][j]], val);
      print_error("Max.", "vsig", max_diff[0][j], &func, val);
    }

    if(info->flags & XC_FLAGS_HAVE_FXC){
      diff = avg_diff[1][0] + avg_diff[1][1] + avg_diff[2][1];
      diff = diff/3.0;
      print_error("Avg.", "v2rho2", diff, NULL, NULL);
      if(max_diff[1][0] > max_diff[1][1]) {i=1; j=0;} else {i=1; j=1;}
      if(max_diff[2][1] > max_diff[i][j]) {i=2; j=1;}
      get_val(xc_trial_points[p_max[i][j]], val);
      print_error("Max.", "v2rho2", max_diff[i][j], &func, val);

      if(info->family > XC_FAMILY_LDA){
	diff = avg_diff[3][0] + avg_diff[4][0] + avg_diff[5][0] + avg_diff[3][1] + avg_diff[4][1] + avg_diff[5][1];
	diff = diff/6.0;
	print_error("Avg.", "v2rhosig", diff, NULL, NULL);
	if(max_diff[3][0] > max_diff[4][0]) {i=3; j=0;} else {i=4; j=0;}
	if(max_diff[5][0] > max_diff[i][j]) {i=5; j=0;}
	if(max_diff[3][1] > max_diff[i][j]) {i=3; j=1;}
	if(max_diff[4][1] > max_diff[i][j]) {i=4; j=1;}
	if(max_diff[5][1] > max_diff[i][j]) {i=5; j=1;}
	get_val(xc_trial_points[p_max[i][j]], val);
	print_error("Max.", "v2rhosig", max_diff[i][j], &func, val);

	diff = avg_diff[3][2] + avg_diff[4][2] + avg_diff[5][2] + avg_diff[4][3] + avg_diff[5][3] + avg_diff[5][4];
	diff = diff/6.0;
	print_error("Avg.", "v2sig2", diff, NULL, NULL);
	if(max_diff[3][2] > max_diff[4][2]) {i=3; j=2;} else {i=4; j=2;}
	if(max_diff[5][2] > max_diff[i][j]) {i=5; j=2;}
	if(max_diff[4][3] > max_diff[i][j]) {i=4; j=3;}
	if(max_diff[5][3] > max_diff[i][j]) {i=5; j=3;}
	if(max_diff[5][4] > max_diff[i][j]) {i=5; j=4;}
	get_val(xc_trial_points[p_max[i][j]], val);
	print_error("Max.", "v2sig2", max_diff[i][j], &func, val);
      }
    }
  }

  xc_func_end(&func);
}