예제 #1
0
파일: testall.c 프로젝트: dftlibs/xcfun
/* Test permutation symmetries over variables and modes etc. */
void consistency_test(void)
{
  xc_functional fun = xc_new_functional();
  double d_unpolarized[8] = {1,1, 2,-3,4, 2,-3,4};
  double d_pol_a[8] = {1,2.1, 2,-3,4, 7,-8,9};
  double d_pol_b[8] = {2.1,1, 7,-8,9, 2,-3,4};
  int nout;
  double *output;
  double *out2;
  xc_set(fun,"pbe",1.0);
  xc_eval_setup(fun,XC_A_B_AX_AY_AZ_BX_BY_BZ,XC_PARTIAL_DERIVATIVES,1);
  nout = xc_output_length(fun);
  check("correct output length 1",nout == 9); // 1 + 8
  output = malloc(sizeof(*output)*nout);
  out2 = malloc(sizeof(*output)*nout);
  xc_eval(fun,d_unpolarized,output);

  checknum("unpolarized symmetry 1",output[1] - output[2],0,1e-14,1e-12);
  checknum("unpolarized symmetry 2",output[3] - output[6],0,1e-14,1e-12);
  checknum("unpolarized symmetry 3",output[4] - output[7],0,1e-14,1e-12);
  checknum("unpolarized symmetry 4",output[5] - output[8],0,1e-14,1e-12);
  xc_eval(fun,d_pol_a,output);
  xc_eval(fun,d_pol_b,out2);
  checknum("polarized symmetry 1",output[1] - out2[2],0,1e-14,1e-12);
  checknum("polarized symmetry 2",output[3] - out2[6],0,1e-14,1e-12);
  checknum("polarized symmetry 3",output[4] - out2[7],0,1e-14,1e-12);
  checknum("polarized symmetry 4",output[5] - out2[8],0,1e-14,1e-12);
  checknum("polarized symmetry 5",out2[1] - output[2],0,1e-14,1e-12);
  checknum("polarized symmetry 6",out2[3] - output[6],0,1e-14,1e-12);
  checknum("polarized symmetry 7",out2[4] - output[7],0,1e-14,1e-12);
  checknum("polarized symmetry 8",out2[5] - output[8],0,1e-14,1e-12);
  free(output);
  free(out2);
  xc_free_functional(fun);
}
예제 #2
0
파일: testall.c 프로젝트: dftlibs/xcfun
// Test that gradient square norma and gradient elements modes are consistent
void gradient_forms_test(void)
{
  xc_functional fun = xc_new_functional();
  double d_elements[8] = {1, 2.1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6};
  double d_sqnorm[5] = {d_elements[0],d_elements[1]};
  int nout,i;
  double *output;
  double *out2;
  xc_set(fun,"blyp",1.0);

  xc_eval_setup(fun,XC_A_B_AX_AY_AZ_BX_BY_BZ,XC_PARTIAL_DERIVATIVES,1);
  nout = xc_output_length(fun);

  check("correct output length 1",nout == 9); // 1 + 8
  output = malloc(sizeof(*output)*nout);
  xc_eval(fun,d_elements,output);

  xc_eval_setup(fun,XC_A_B_GAA_GAB_GBB, XC_PARTIAL_DERIVATIVES,1);
  nout = xc_output_length(fun);

  check("correct output length 1",nout == 6); // 1 + 5
  out2 = malloc(sizeof(*out2)*nout);
  d_sqnorm[2] = d_elements[2]*d_elements[2] + d_elements[3]*d_elements[3] + d_elements[4]*d_elements[4];
  d_sqnorm[3] = d_elements[2]*d_elements[5] + d_elements[3]*d_elements[6] + d_elements[4]*d_elements[7];
  d_sqnorm[4] = d_elements[5]*d_elements[5] + d_elements[6]*d_elements[6] + d_elements[7]*d_elements[7];
  xc_eval(fun,d_sqnorm,out2);

  checknum("Grad modes energy",output[0] - out2[0],0,1e-14,1e-12);
  checknum("Grad modes density derivs alpha",output[1] - out2[1],0,1e-14,1e-12);
  checknum("Grad modes density derivs beta", output[2] - out2[2],0,1e-14,1e-12);
  // d/dg_ax = d/dgaa * g_ax + d/dgab * g_bx
  for (i=0;i<3;i++)
    {
      checknum("Grad modes density grad alpha",output[3+i] - (2*out2[3]*d_elements[2+i] + out2[4]*d_elements[5+i])   ,0,1e-14,1e-12);
      checknum("Grad modes density grad beta",output[6+i] - (2*out2[5]*d_elements[5+i] + out2[4]*d_elements[2+i])   ,0,1e-14,1e-12);
    }

  free(output);
  free(out2);
  xc_free_functional(fun);
}
예제 #3
0
// Compute the xc potential(s). This is simple for lda and more complicated for 
// GGA's. For metaGAA's that depend on tau this is a non-local problem and 
// cannot be solved by xcfun. Laplacian dependent metaGGA's could be implemented..
// Another option is to evaluate the divergence directly in cartesian coordinates,
// but one have to find a way to do this without introducing the gradient components
// explicitly (for niceness)
void xc_potential(xc_functional fun, const double *density, double *e_xc, double *v_xc)
{
  if (fun->mode == XC_VARS_AB)
    {
      if (fun->type == XC_LDA) 
	{
	  double out[3];
	  xc_eval(fun,1,density,out);
	  e_xc[0] = out[0];
	  v_xc[0] = out[1];
	  v_xc[1] = out[2];
	}
      // Expecting lap_a and lap_b as element 5 and 6 of density
      // Using that v_xc = dE/dn - div dE/dgradn
      // When deriving the expressions it helps to have the operator
      // (g_a).nabla act on the basic variables (and the same for g_b). 
      else if (fun->type == XC_GGA)  
	{
	  const int gaa = 2, gab = 3, gbb = 4, lapa = 5, lapb = 6;
	  double out[21];
	  xc_eval(fun,2,density,out);
	  e_xc[0] = out[XC_D00000];

	  v_xc[0]  = out[XC_D10000];
	  v_xc[0] -= 2*density[lapa]*out[XC_D00100] + density[lapb]*out[XC_D00010];
	  v_xc[0] -= 2*(out[XC_D10100]*density[gaa]   + 
			out[XC_D01100]*density[gab] +
			out[XC_D00200]*(2*density[lapa]*density[gaa]) +
			out[XC_D00110]*(density[lapa]*density[gab] + density[lapb]*density[gaa]) +
			out[XC_D00101]*(2*density[lapb]*density[gab]) 
			); 
	  v_xc[0] -= (out[XC_D10010]*density[gab] +
		      out[XC_D01010]*density[gbb] +
		      out[XC_D00110]*(2*density[lapa]*density[gab]) +
		      out[XC_D00020]*(density[lapb]*density[gab] + density[lapa]*density[gbb]) +
		      out[XC_D00011]*(2*density[lapb]*density[gbb])); 

	  v_xc[1]  = out[XC_D01000];
	  v_xc[1] -= 2*density[lapb]*out[XC_D00001] + density[lapa]*out[XC_D00010];
	  v_xc[1] -= 2*(out[XC_D01001]*density[gbb]   + 
			out[XC_D10001]*density[gab]  +
			out[XC_D00002]*(2*density[lapb]*density[gbb]) +
			out[XC_D00011]*(density[lapb]*density[gab] + density[lapa]*density[gbb]) +
			out[XC_D00101]*(2*density[lapa]*density[gab])  ); 
	  v_xc[1] -= (out[XC_D01010]*density[gab] +
		      out[XC_D10010]*density[gaa] +
		      out[XC_D00011]*(2*density[lapb]*density[gab]) +
		      out[XC_D00020]*(density[lapa]*density[gab] + density[lapb]*density[gaa]) +
		      out[XC_D00110]*(2*density[lapa]*density[gaa])); 
	}
      else
	{
	  xcint_die("xc_potential() not implemented for metaGGA's",fun->type);
	}
    }
  else if (fun->mode == XC_VARS_N)
    {
      if (fun->type == XC_LDA) 
	{
	  double out[2];
	  xc_eval(fun,1,density,out);
	  e_xc[0] = out[0];
	  v_xc[0] = out[1];
	}      
      else
	{
	  xcint_die("xc_potential() GGA not implemented for XC_VARS_N",
		    fun->type);
	}
    }
  else 
    {
      xcint_die("xc_potential() GGA only implemented for AB mode",
		fun->mode);
    }
}