Exemplo n.º 1
0
void print_error(char *type, char *what, double diff, xc_func_type *func, double *p)
{
  static char *red="\033[31;1m", *norm="\033[0m";
  char *color;

  color = (diff > 5e-4) ? red : norm;
  
  printf("%s error %s: %s%g%s\n", type, what, color, diff, norm);

  if(func == NULL) return;

  printf("   point (% 8.2e, % 8.2e, % 8.2e, % 8.2e, % 8.2e)\n", 
	 p[0], p[1], p[2], p[3], p[4]);

  if(strcmp(what, "vrho")==0 || strcmp(what, "vsig")==0){
    double e, v_an[5], v_fd[5];
    int j;

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

    get_vxc(func, p, &e, v_an);
    first_derivative(func, p, v_fd, 0);

    if(strcmp(what, "vrho") == 0){
      printf("  analyt (% 8.2e, % 8.2e)\n", v_an[0], v_an[1]);
      printf("      fd (% 8.2e, % 8.2e)\n", v_fd[0], v_fd[1]);
    }

    if(strcmp(what, "vsig") == 0){
      printf("  analyt (% 8.2e, % 8.2e, % 8.2e)\n", v_an[2], v_an[3], v_an[4]);
      printf("      fd (% 8.2e, % 8.2e, % 8.2e)\n", v_fd[2], v_fd[3], v_fd[4]);
    }
  }

  if(strcmp(what, "v2rho2")==0 || strcmp(what, "v2rhosig")==0 || strcmp(what, "v2sig2")==0){
    double f_an[5][5], f_fd[5][5];
    int i, j;

    get_fxc(func, p, f_an);
    second_derivatives(func, p, f_fd);

    if(strcmp(what, "v2rho2") == 0){
      printf("  analyt (% 8.2e, % 8.2e, % 8.2e)\n", f_an[0][0], f_an[0][1], f_an[1][1]);
      printf("      fd (% 8.2e, % 8.2e, % 8.2e)\n", f_fd[0][0], f_fd[0][1], f_fd[1][1]);
    }

    if(strcmp(what, "v2rhosig") == 0){
      printf("  analyt (% 8.2e, % 8.2e, % 8.2e, % 8.2e, % 8.2e, % 8.2e)\n", 
	     f_an[2][0], f_an[3][0], f_an[4][0], f_an[2][1], f_an[3][1], f_an[4][1]);
      printf("      fd (% 8.2e, % 8.2e, % 8.2e, % 8.2e, % 8.2e, % 8.2e)\n", 
	     f_fd[2][0], f_fd[3][0], f_fd[4][0], f_fd[2][1], f_fd[3][1], f_fd[4][1]);
    }

    if(strcmp(what, "v2sig2") == 0){
      printf("  analyt (% 8.2e, % 8.2e, % 8.2e, % 8.2e, % 8.2e, % 8.2e)\n", 
	     f_an[2][2], f_an[3][2], f_an[4][2], f_an[3][3], f_an[4][3], f_an[4][4]);
      printf("      fd (% 8.2e, % 8.2e, % 8.2e, % 8.2e, % 8.2e, % 8.2e)\n", 
	     f_fd[2][2], f_fd[3][2], f_fd[4][2], f_fd[3][3], f_fd[4][3], f_fd[4][4]);
    }
  }

}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
void test_functional(int functional)
{
    functionals_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];

    /* initialize functional */
    func.family = xc_family_from_id(functional);
    switch(func.family)
    {
    case XC_FAMILY_LDA:
        if(functional == XC_LDA_X)
            xc_lda_x_init(&(func.lda_func), nspin, 3, 0);
        else
            xc_lda_init(&(func.lda_func), functional, nspin);

        info = func.lda_func.info;
        break;
    case XC_FAMILY_GGA:
        xc_gga_init(&(func.gga_func), functional, nspin);

        info = func.gga_func.info;
        break;
    case XC_FAMILY_HYB_GGA:
        xc_hyb_gga_init(&(func.hyb_gga_func), functional, nspin);

        info = func.hyb_gga_func.info;
        break;
    default:
        fprintf(stderr, "Functional '%d' not found\n", functional);
        exit(1);
    }

    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 analitic gradients */
        get_vxc(&func, val, &e, v_an);

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

        if(info->provides & XC_PROVIDES_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->provides & XC_PROVIDES_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(func.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->provides & XC_PROVIDES_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(func.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);
            }
        }
    }
}