Libxc 5.0.x

Compatibility notice

This manual is for Libxc 5.0.x.

See the Change Log for a complete list of changes made to the library API over the different Libxc versions.

An example

Probably the best way to explain the usage of Libxc is through an example. The following small program calculates the xc energy for a given functional for several values of the density; the available C bindings can be found in header file xc.h. When compiling this example it is necessary to ink with libxc.a or libxc.so, depending if you compiled the static or shared versions of the library.

#include <stdio.h>

#include <xc.h>

int main()
{
  xc_func_type func;
  double rho[5] = {0.1, 0.2, 0.3, 0.4, 0.5};
  double sigma[5] = {0.2, 0.3, 0.4, 0.5, 0.6};
  double exc[5];
  int i, vmajor, vminor, vmicro, func_id = 1;
  /* Get the libxc version */
  xc_version(&vmajor, &vminor, &vmicro);
  printf("Libxc version: %d.%d.%d\n", vmajor, vminor, vmicro);
  /* Initialize the functional */
  if(xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0){
    fprintf(stderr, "Functional '%d' not found\n", func_id);
    return 1;
  }
  /* Evaluate the energy density, depending on the family */
  switch(func.info->family)
    {
    case XC_FAMILY_LDA:
      xc_lda_exc(&func, 5, rho, exc);
      break;
    case XC_FAMILY_GGA:
    case XC_FAMILY_HYB_GGA:
      xc_gga_exc(&func, 5, rho, sigma, exc);
      break;
    }
  /* Print out density and energy density per particle */
  for(i=0; i<5; i+=1){
    printf("%lf %lf\n", rho[i], exc[i]);
  }
  /* Deallocate memory */
  xc_func_end(&func);
}

The functionals are divided in families (LDA, GGA, etc.). Given a functional identifier xc.func_id, the functional is initialized by xc_func_init, and evaluated by xc_XXX_exc, which returns the energy per particle exc. Finally the function xc_func_end cleans up.

The output of the above example should look something like this:

Libxc version: 4.0.0
0.100000 -0.342809
0.200000 -0.431912
0.300000 -0.494416
0.400000 -0.544175
0.500000 -0.586194

Fortran 90 bindings (following the Fortran 2003 standard) are also included in Libxc. These can be found in the file [libxc_master.F90] (https://gitlab.com/libxc/libxc/blob/master/src/libxc_master.F90). In general, calling Libxc from Fortran is as simple as from C. Note that you also need to link with libxcf90.a or libxcf90.so when using the Fortran 90 interface. Here is the previous example in Fortran:

program lxctest
  use xc_f90_lib_m
  implicit none
  TYPE(xc_f90_func_t) :: xc_func
  TYPE(xc_f90_func_info_t) :: xc_info
  integer(8), parameter :: npoints = 5
  real(8) :: rho(npoints) = (/0.1, 0.2, 0.3, 0.4, 0.5/)
  real(8) :: sigma(npoints) = (/0.2, 0.3, 0.4, 0.5, 0.6/)
  real(8) :: exc(npoints)
  integer :: i, vmajor, vminor, vmicro, func_id = 1
  ! Print out the version  
  call xc_f90_version(vmajor, vminor, vmicro)
  write(*,'("Libxc version: ",I1,".",I1,".",I1)') vmajor, vminor, vmicro
  ! Initialize the functional
  call xc_f90_func_init(xc_func, func_id, XC_UNPOLARIZED)
  ! Get the information
  xc_info = xc_f90_func_get_info(xc_func)
  ! Evaluate energy depending on the family
  select case (xc_f90_func_info_get_family(xc_info))
    case(XC_FAMILY_LDA)
      call xc_f90_lda_exc(xc_func, npoints, rho(1), exc(1))
    case(XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
      call xc_f90_gga_exc(xc_func, npoints, rho(1), sigma(1), exc(1))
  end select
  ! Print out density and energy density per particle
  do i = 1, npoints
    write(*,"(F8.6,1X,F9.6)") rho(i), exc(i)
  end do
  ! Deallocate memory
  call xc_f90_func_end(xc_func)
 end program lxctest

The info structure

For each functional there is a structure that holds several pieces of information. The relevant part of this structure for the end user is defined as:

#define XC_FLAGS_HAVE_EXC         (1 <<  0) /*     1 */
#define XC_FLAGS_HAVE_VXC         (1 <<  1) /*     2 */
#define XC_FLAGS_HAVE_FXC         (1 <<  2) /*     4 */
#define XC_FLAGS_HAVE_KXC         (1 <<  3) /*     8 */
#define XC_FLAGS_HAVE_LXC         (1 <<  4) /*    16 */
#define XC_FLAGS_1D               (1 <<  5) /*    32 */
#define XC_FLAGS_2D               (1 <<  6) /*    64 */
#define XC_FLAGS_3D               (1 <<  7) /*   128 */
#define XC_FLAGS_HYB_CAM          (1 <<  8) /*   256 */
#define XC_FLAGS_HYB_CAMY         (1 <<  9) /*   512 */
#define XC_FLAGS_VV10             (1 << 10) /*  1024 */
#define XC_FLAGS_HYB_LC           (1 << 11) /*  2048 */
#define XC_FLAGS_HYB_LCY          (1 << 12) /*  4096 */
#define XC_FLAGS_STABLE           (1 << 13) /*  8192 */
#define XC_FLAGS_DEVELOPMENT      (1 << 14) /* 16384 */
#define XC_FLAGS_NEEDS_LAPLACIAN  (1 << 15) /* 32768 */

typedef struct{
  int   number;   /* identifier number */
  int   kind;     /* XC_EXCHANGE, XC_CORRELATION, XC_EXCHANGE_CORRELATION, XC_KINETIC */
  
  char *name;     /* name of the functional, e.g. "PBE" */
  int   family;   /* type of the functional, e.g. XC_FAMILY_GGA */
  func_reference_type *refs[XC_MAX_REFERENCES];  /* index of the references */
  
  int   flags;    /* see above for a list of possible flags */
  
  double dens_threshold;
  
  /* this allows to have external parameters in the functional */
  int n_ext_params;
  const func_params_type *ext_params;
  void (*set_ext_params)(struct xc_func_type *p, const double *ext_params);
  
  ...
} xc_func_info_type;

For example, for the Slater exchange functional, this structure is defined as

const xc_func_info_type xc_func_info_lda_x = {
  XC_LDA_X,
  XC_EXCHANGE,
  "Slater exchange",
  XC_FAMILY_LDA,
  {&xc_ref_Dirac1930_376, &xc_ref_Bloch1929_545, NULL, NULL, NULL},
  XC_FLAGS_3D | XC_FLAGS_HAVE_EXC | XC_FLAGS_HAVE_VXC | XC_FLAGS_HAVE_FXC | XC_FLAGS_HAVE_KXC,
  1e-24,
  0, NULL, NULL,
  ...
};

The user of the library can access the information in the following way:

#include <stdio.h>
#include <xc.h>
  
int main()
{
  int ii;
  xc_func_type func;
  /* Initialize the functional */  
  xc_func_init(&func, XC_GGA_X_B88, XC_UNPOLARIZED);
  /* Print out information */
  printf("The functional '%s' is ", func.info->name);
  switch (func.info->kind) {
  case (XC_EXCHANGE):
    printf("an exchange functional");
    break;
  case (XC_CORRELATION):
    printf("a correlation functional");
    break;
  case (XC_EXCHANGE_CORRELATION):
    printf("an exchange-correlation functional");
    break;
  case (XC_KINETIC):
    printf("a kinetic energy functional");
    break;
  default:
    printf("of unknown kind");
    break;
  }
  printf(", it belongs to the '", func.info->name);
  /* Print out family */  
  switch (func.info->family) {
  case (XC_FAMILY_LDA):
    printf("LDA");
    break;
  case (XC_FAMILY_GGA):
    printf("GGA");
    break;
  case (XC_FAMILY_HYB_GGA):
    printf("Hybrid GGA");
    break;
  case (XC_FAMILY_MGGA):
    printf("MGGA");
    break;
  case (XC_FAMILY_HYB_MGGA):
    printf("Hybrid MGGA");
    break;
  default:
    printf("unknown");
    break;
  }
  printf("' family and is defined in the reference(s):\n");
  /* Print out references */
  for(ii = 0; func.info->refs[ii] != NULL; ii++){
    printf("[%d] %s\n", ii+1, func.info->refs[ii]->ref);
  }
  /* Deallocate memory */
  xc_func_end(&func);
}

The output of this example should look like this:

The functional 'Becke 88' belongs to the 'GGA' family and is defined in the reference(s):
[1] A. D. Becke, Phys. Rev. A 38, 3098 (1988)

Several routines are available to access the information about the functional from Fortran. Here is the previous example using the Fortran 90 interface:

program xcinfo
  use xc_f90_lib_m
  implicit none
  type(xc_f90_func_t) :: xc_func
  type(xc_f90_func_info_t) :: xc_info
  integer :: i
  character(len=120) :: kind, family
  ! Initialize the functional
  call xc_f90_func_init(xc_func, XC_GGA_X_B88, XC_UNPOLARIZED)
  xc_info = xc_f90_func_get_info(xc_func)
  ! Get the type of the functional
  select case(xc_f90_func_info_get_kind(xc_info))
  case (XC_EXCHANGE)
    write(kind, '(a)') 'an exchange functional'
  case (XC_CORRELATION)
    write(kind, '(a)') 'a correlation functional'
  case (XC_EXCHANGE_CORRELATION)
    write(kind, '(a)') 'an exchange-correlation functional'
  case (XC_KINETIC)
    write(kind, '(a)') 'a kinetic energy functional'
  case default
    write(kind, '(a)') 'of unknown kind'
  end select
  ! Get the family
  select case (xc_f90_func_info_get_family(xc_info))
  case (XC_FAMILY_LDA);
    write(family,'(a)') "LDA"
  case (XC_FAMILY_GGA);
    write(family,'(a)') "GGA"
  case (XC_FAMILY_HYB_GGA);
    write(family,'(a)') "Hybrid GGA"
  case (XC_FAMILY_MGGA);
    write(family,'(a)') "MGGA"
  case (XC_FAMILY_HYB_MGGA);
    write(family,'(a)') "Hybrid MGGA"
  case default;
    write(family,'(a)') "unknown"
  end select
  ! Print out information
  write(*,'("The functional ''", a, "'' is ", a, ", it belongs to the ''", a, "'' family and is defined in the reference(s):")') &
    trim(xc_f90_func_info_get_name(xc_info)), trim(kind), trim(family)
  ! Print out references
  i = 0
  do while(i >= 0)
    write(*, '(a,i1,2a)') '[', i+1, '] ', trim(xc_f90_func_reference_get_ref(xc_f90_func_info_get_references(xc_info, i)))
  end do
  ! Free the memory
  call xc_f90_func_end(xc_func)
end program xcinfo

Initialization

A functional is initialized by the routine

int xc_func_init(xc_func_type *p, int functional, int nspin);

input:
  functional: which functional do we want?
  nspin: either XC_UNPOLARIZED or XC_POLARIZED
output:
  p: structure that holds our functional
returns: 0 (OK) or -1 (ERROR)

External parameters

There are some functionals that require extra information, like the number of particles or the temperature. The number of parameters and a short description of their meaning is included in the info structure


typedef struct{
  double value;
  char *description;
} func_params_type;
 
typedef struct{
  ...
  
  /* this allows to have external parameters in the functional */
  int n_ext_params;
  const func_params_type *ext_params;
  void (*set_ext_params)(struct xc_func_type *p, const double *ext_params);
  
  ...
} xc_func_info_type;

Note that several functions are provided in the Fortran interface to access this information.

These parameters are set by default to some value and changing them is done using the xc_func_set_ext_params function

xc_func_set_ext_params(xc_func_type *p, double *ext_params);

input:
  p: structure obtained from calling xc_func_init
  ext_params: array of external parameters

Evaluation

The routines that should be used depend on the functional family. Note: The routines expect a nonnegative density.

LDA

This is done by the routines

void xc_lda_exc(const xc_lda_type *p, int np, double *rho, 
     double *exc);
void xc_lda_vxc(const xc_lda_type *p, int np, double *rho, 
     double *vrho);
void xc_lda_exc_vxc(const xc_lda_type *p, inp np, double *rho, 
     double *exc, double *vrho);
void xc_lda_fxc(const xc_lda_type *p, int np, double *rho, 
     double *v2rho2);
void xc_lda_kxc(const xc_lda_type *p, int np, double *rho, 
     double *v3rho3);
void xc_lda_lxc(const xc_lda_type *p, int np, double *rho, 
     double *v4rho4);
void xc_lda(const xc_lda_type *p, int np, double *rho, double *exc,
     double *vrho, double *v2rho2, double *v3rho3, double *v4rho4);

input:
  p: structure obtained from calling xc_func_init
  np: number of points
  rho[]: the density
output:
  exc[]: the energy per unit particle
  vrho[]: first derivative of the energy per unit volume
  v2rho2[]: second derivative of the energy per unit volume
  v3rho3[]: third derivative of the energy per unit volume
  v4rho4[]: fourth derivative of the energy per unit volume

The components of the density rho are

$$ \mathrm{rho}[0] = \rho_\uparrow \qquad \mathrm{rho}[1] = \rho_\downarrow $$

The derivatives are defined as

1st order $$ \mathrm{vrho}_\alpha \quad;\quad \frac{d \epsilon}{d \rho_\alpha} \quad;\quad [(0), (1)] $$

2nd order $$ \mathrm{v2rho2}_{\alpha\beta} \quad;\quad \frac{d^2 \epsilon}{d \rho_\alpha d \rho_\beta} \quad;\quad [(0,0), (0,1), (1,1)] $$

3rd order $$ \mathrm{v3rho3}_{\alpha\beta\gamma} \quad;\quad \frac{d^3 \epsilon}{d \rho_\alpha d \rho_\beta d \rho_\gamma} \quad;\quad [(0,0,0), (0,0,1), (0,1,1), (1,1,1)] $$

4th order $$ \mathrm{v4rho4}_{\alpha\beta\gamma\kappa} \quad;\quad \frac{d^4 \epsilon}{d \rho_\alpha d \rho_\beta d \rho_\gamma d \rho_\kappa} \quad;\quad [(0,0,0,0), (0,0,0,1), (0,0,1,1), (0,1,1,1), (1,1,1,1)] $$

If the functional was initialized with nspin=XC_UNPOLARIZED, the spin indices should be dropped from the previous expressions, resulting in arrays of size np. Otherwise, the parameters have dimensions rho[2*np], vrho[2*np], v2rho2[3*np], v3rho3[4*np], and v4rho4[5*np]. The energy per unit particle array always has dimensions exc[np]. The components are

GGA

This is done by the routines

void xc_gga_exc(const xc_func_type *p, int np, double *rho, double *sigma, 
     double *exc)
void xc_gga_vxc(const xc_func_type *p, int np, double *rho, double *sigma, 
     double *vrho, double *vsigma)
void xc_gga_exc_vxc(const xc_func_type *p, int np, double *rho, double *sigma, 
     double *exc, double *vrho, double *vsigma)
void xc_gga_fxc(const xc_func_type *p, int np, double *rho, double *sigma, 
     double *v2rho2, double *v2rhosigma, double *v2sigma2)
void xc_gga_kxc(const xc_func_type *p, int np, double *rho, double *sigma, 
     double *v3rho3, double *v3rho2sigma, double *v3rhosigma2, double *v3sigma3)
void xc_gga_lxc(const xc_func_type *p, int np, double *rho, double *sigma, 
     double *v4rho4, double *v4rho3sigma, double *v4rho2sigma2, double *v4rhosigma3, double *v4sigma4)
void xc_gga(const xc_func_type *p, int np, double *rho, double *sigma, 
     double *exc, double *vrho, double *vsigma, 
     double *v2rho2, double *v2rhosigma, double *v2sigma2
     double *v3rho3, double *v3rho2sigma, double *v3rhosigma2, double *v3sigma3)
     double *v4rho4, double *v4rho3sigma, double *v4rho2sigma2, double *v4rhosigma3, double *v4sigma4)

input:
  p: structure obtained from calling xc_func_init
  np: number of points
  rho[]: the density
  sigma[]: contracted gradients of the density
output:
  exc[]: the energy per unit particle
  vrho[]: first partial derivative of the energy per unit volume in terms of the density
  vsigma[]: first partial derivative of the energy per unit volume in terms of sigma
  v2rho2[]: second partial derivative of the energy per unit volume in terms of the density
  v2rhosigma[]: second partial derivative of the energy per unit volume in terms of the density and sigma
  v2sigma2[]: second partial derivative of the energy per unit volume in terms of sigma
  etc.

The components of the contracted gradient sigma are

$$ \sigma[0] = \nabla \rho_\uparrow \cdot \nabla \rho_\uparrow \qquad \sigma[1] = \nabla \rho_\uparrow \cdot \nabla \rho_\downarrow \qquad \sigma[2] = \nabla \rho_\downarrow \cdot \nabla \rho_\downarrow \qquad $$

The extra derivatives are defined as

1st order $$ \mathrm{vsigma}_{\alpha} \quad;\quad \frac{\partial \epsilon}{\partial \sigma_\alpha} \quad;\quad [(0), (1), (2)] $$

2nd order $$ \mathrm{v2rhosigma}_{\alpha\beta} \quad;\quad \frac{\partial \epsilon}{\partial \rho_\alpha \partial \sigma_\beta} \quad;\quad [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2)] $$ $$ \mathrm{v2sigma2}_{\alpha\beta} \quad;\quad \frac{d^2 \epsilon}{\partial \sigma_\alpha \partial \sigma_\beta} \quad;\quad [(0,0), (0,1), (0,2), (1,1), (1,2), (2,2)] $$

3rd order $$ \mathrm{v3rho2sigma}_{\alpha\beta\gamma} \quad;\quad \frac{d^3 \epsilon}{\partial \rho_\alpha \partial \rho_\beta \partial \sigma_\gamma} \quad;\quad [(0,0,0), (0,0,1), (0,0,2), (0,1,0), (0,1,1), (0,1,2), (1,1,0), (1,1,1), (1,1,2)] $$ $$ \mathrm{v3rhosigma2}_{\alpha\beta\gamma} \quad;\quad \frac{d^3 \epsilon}{\partial \rho_\alpha \partial \sigma_\beta \partial \sigma_\gamma} \quad;\quad [(0,0,0), (0,0,1), (0,0,2), (0,1,1), (0,1,2), (0,2,2) (1,0,0), (1,0,1), (1,0,2), (1,1,1), (1,1,2), (1,2,2)] $$ $$ \mathrm{v3sigma3}_{\alpha\beta\gamma} \quad;\quad \frac{d^3 \epsilon}{\partial \sigma_\alpha \partial \sigma_\beta \partial \sigma_\gamma} \quad;\quad [(0,0,0), (0,0,1), (0,0,2), (0,1,1), (0,1,2), (0,2,2), (1,1,1), (1,1,2), (1,2,2), (2,2,2)] $$

4th order $$ \mathrm{v4rho3sigma}_{\alpha\beta\gamma\kappa} \quad;\quad \frac{d^4 \epsilon}{\partial \rho_\alpha \partial \rho_\beta \partial \rho_\gamma \partial \sigma_\kappa} \quad;\quad [ (0,0,0,0), (0,0,0,1), (0,0,0,2), (0,0,1,0), (0,0,1,1), (0,0,1,2), (0,1,1,0), (0,1,1,1), (0,1,1,2), (1,1,1,0), (1,1,1,1), (1,1,1,2) ] $$ $$ \mathrm{v4rho2sigma2}_{\alpha\beta\gamma\kappa} \quad;\quad \frac{d^4 \epsilon}{\partial \rho_\alpha \partial \rho_\beta \partial \sigma_\gamma \partial \sigma_\kappa} \quad;\quad [ (0,0,0,0), (0,0,0,1), (0,0,0,2), (0,0,1,1), (0,0,0,2), (0,1,0,0), (0,1,0,1), (0,1,0,2), (0,1,1,1), (0,1,0,2), (1,1,0,0), (1,1,0,1), (1,1,0,2), (1,1,1,1), (1,1,0,2) ] $$ $$ \mathrm{v4rhosigma3}_{\alpha\beta\gamma\kappa} \quad;\quad \frac{d^4 \epsilon}{\partial \rho_\alpha \partial \sigma_\beta \partial \sigma_\gamma \partial \sigma_\kappa} \quad;\quad [ (0,0,0,0), (0,0,0,1), (0,0,0,2), (0,0,1,1), (0,0,1,2), (0,0,2,2), (0,1,1,1), (0,1,1,2), (0,1,2,2), (0,2,2,2), (1,0,0,0), (1,0,0,1), (1,0,0,2), (1,0,1,1), (1,0,1,2), (1,0,2,2), (1,1,1,1), (1,1,1,2), (1,1,2,2), (1,2,2,2) ] $$ $$ \mathrm{v4sigma4}_{\alpha\beta\gamma\kappa} \quad;\quad \frac{d^4 \epsilon}{\partial \sigma_\alpha \partial \sigma_\beta \partial \sigma_\gamma \partial \sigma_\kappa} \quad;\quad [ (0,0,0,0), (0,0,0,1), (0,0,0,2), (0,0,1,1), (0,0,1,2), (0,0,2,2), (0,1,1,1), (0,1,1,2), (0,1,2,2), (0,2,2,2), (1,1,1,1), (1,1,1,2), (1,1,2,2), (1,2,2,2), (2,2,2,2) ] $$

MetaGGA

This is done by the routines

void xc_mgga_exc(const xc_func_type *p, int np, double *rho, double *sigma, double *lapl, double *tau, 
     double *exc)
void xc_mgga_vxc(const xc_func_type *p, int np, double *rho, double *sigma, double *lapl, double *tau, 
     double *vrho, double *vsigma, double *vlapl, double *vtau)
void xc_mgga_exc_vxc(const xc_func_type *p, int np, double *rho, double *sigma, double *lapl, double *tau, 
     double * exc, double *vrho, double *vsigma, double *vlapl, double *vtau)
void xc_mgga_fxc(const xc_func_type *p, int np, double *rho, double *sigma, double *lapl, double *tau,
     double *v2rho2, double *v2rhosigma, double *v2rholapl, double *v2rhotau, double *v2sigma2,
     double *v2sigmalapl, double *v2sigmatau, double *v2lapl2, double *v2lapltau,  double *v2tau2)
void xc_mgga_kxc(const xc_func_type *p, int np, double *rho, double *sigma, double *lapl, double *tau,
     double *v3rho3, double *v3rho2sigma, double *v3rho2lapl, double *v3rho2tau, double *v3rhosigma2,
     double *v3rhosigmalapl, double *v3rhosigmatau, double *v3rholapl2, double *v3rholapltau,
     double *v3rhotau2, double *v3sigma3, double *v3sigma2lapl, double *v3sigma2tau,
     double *v3sigmalapl2, double *v3sigmalapltau, double *v3sigmatau2, double *v3lapl3,
     double *v3lapl2tau, double *v3lapltau2, double *v3tau3)
void xc_mgga_lxc(const xc_func_type *p, int np, double *rho, double *sigma, double *lapl, double *tau,
     double *v4rho4, double *v4rho3sigma, double *v4rho3lapl, double *v4rho3tau, double *v4rho2sigma2,
     double *v4rho2sigmalapl, double *v4rho2sigmatau, double *v4rho2lapl2, double *v4rho2lapltau,
     double *v4rho2tau2, double *v4rhosigma3, double *v4rhosigma2lapl, double *v4rhosigma2tau,
     double *v4rhosigmalapl2, double *v4rhosigmalapltau, double *v4rhosigmatau2,
     double *v4rholapl3, double *v4rholapl2tau, double *v4rholapltau2, double *v4rhotau3,
     double *v4sigma4, double *v4sigma3lapl, double *v4sigma3tau, double *v4sigma2lapl2,
     double *v4sigma2lapltau, double *v4sigma2tau2, double *v4sigmalapl3, double *v4sigmalapl2tau,
     double *v4sigmalapltau2, double *v4sigmatau3, double *v4lapl4, double *v4lapl3tau,
     double *v4lapl2tau2, double *v4lapltau3, double *v4tau4)
void xc_mgga(const xc_func_type *p, int np, double *rho, double *sigma, double *lapl, double *tau,
     double *exc, double *vrho, double *vsigma, double *vlapl, double *vtau,
     double *v2rho2, double *v2rhosigma, double *v2rholapl, double *v2rhotau, double *v2sigma2,
     double *v2sigmalapl, double *v2sigmatau, double *v2lapl2, double *v2lapltau, double *v2tau2,
     double *v3rho3, double *v3rho2sigma, double *v3rho2lapl, double *v3rho2tau, double *v3rhosigma2,
     double *v3rhosigmalapl, double *v3rhosigmatau, double *v3rholapl2, double *v3rholapltau,
     double *v3rhotau2, double *v3sigma3, double *v3sigma2lapl, double *v3sigma2tau,
     double *v3sigmalapl2, double *v3sigmalapltau, double *v3sigmatau2, double *v3lapl3,
     double *v3lapl2tau, double *v3lapltau2, double *v3tau3,
     double *v4rho4, double *v4rho3sigma, double *v4rho3lapl, double *v4rho3tau, double *v4rho2sigma2,
     double *v4rho2sigmalapl, double *v4rho2sigmatau, double *v4rho2lapl2, double *v4rho2lapltau,
     double *v4rho2tau2, double *v4rhosigma3, double *v4rhosigma2lapl, double *v4rhosigma2tau,
     double *v4rhosigmalapl2, double *v4rhosigmalapltau, double *v4rhosigmatau2,
     double *v4rholapl3, double *v4rholapl2tau, double *v4rholapltau2, double *v4rhotau3,
     double *v4sigma4, double *v4sigma3lapl, double *v4sigma3tau, double *v4sigma2lapl2,
     double *v4sigma2lapltau, double *v4sigma2tau2, double *v4sigmalapl3, double *v4sigmalapl2tau,
     double *v4sigmalapltau2, double *v4sigmatau3, double *v4lapl4, double *v4lapl3tau,
     double *v4lapl2tau2, double *v4lapltau3, double *v4tau4)

input:
  p: structure obtained from calling xc_func_init
  np: number of points
  rho[]: the density
  sigma[]: contracted gradients of the density
  lapl[]: the laplacian of the density
  tau[]: the kinetic energy density
output:
  exc[]: energy density per unit particle
  vrho[]: first partial derivative of the energy per unit volume in terms of the density
  vsigma[]: first partial derivative of the energy per unit volume in terms of sigma
  vlapl[]: first partial derivative of the energy per unit volume in terms of the laplacian of the density
  vtau[]: first partial derivative of the energy per unit volume in terms of the kinetic energy density
  etc.

Note that the kinetic energy density is defined with the 1/2 factor (until Libxc version 1.2, tau was defined as twice the kinetic energy density):

$$ \mathrm{lapl}[0] = \nabla^2 \rho_\uparrow \qquad \mathrm{lapl}[1] = \nabla^2 \rho_\downarrow $$ $$ {\tau}_{\alpha} = \frac{1}{2}\sum_i | \nabla \psi_{\alpha i} |^2 \qquad \mathrm{tau}[0] = {\tau}_\uparrow \qquad \mathrm{tau}[1] = {\tau}_\downarrow $$

The extra derivatives are defined as

1st order $$ \mathrm{vlapl}_{\alpha} \quad;\quad \frac{\partial \epsilon}{\partial \nabla^2 \rho_\alpha} \quad;\quad [(0), (1)] $$ $$ \mathrm{vtau}_{\alpha} \quad;\quad \frac{\partial \epsilon}{\partial \tau_\alpha} \quad;\quad [(0), (1)] $$

By now you should have understood how the higher derivatives (2nd, 3rd, and 4th) work. Just recall that the order of variables is $[\rho,\sigma,\nabla^2 \rho, \tau]$.

Accessor functions

Some functionals provide accessor functions that give parameters needed for calculating quantities outside of libxc:

The mixing parameter for global hybrids:

double xc_hyb_exx_coef(const xc_func_type *p);

Parameters for CAM-type hybrids, where omega is the range-separation parameter, alpha is the fraction of Hartree-Fock exchange, and beta is the fraction of short-range exchange:

void xc_hyb_cam_coef(const xc_func_type *p, double *omega, double *alpha, double *beta);

Non-local correlation parameters for functionals such as WB97X_V, VV10, LC_VV10, and WB97M_V:

void  xc_nlc_coef(const xc_func_type *p, double *nlc_b, double *nlc_C);

Asymptotic parameter for AK13:

double xc_gga_ak13_get_asymptotic(double homo);

Destruction

If you no longer need your xc functional, you should destroy it with the routine

void xc_func_end (xc_func_type *p);

input:
  p: structure holding the functional to destroy

Other useful functions

xc_family_from_id

If you have the identifier of a functional (that was read, for example from an input file), and want to find out to which family it belongs to, you can use the routine

int xc_family_from_id(int functional);

input:
  functional: identifier of the functional
returns:
  XC_FAMILY_UNKNOWN: could not find the family
  XC_FAMILY_LDA, XC_FAMILY_GGA, etc.

Analogously for Fortran:

  integer function xc_family_from_id (functional)

xc_functional_get_name

If you know the identifier of a functional and want to know its name without having to call xc_func_init, you can use the function

char *xc_functional_get_name(int number);

input
  number: identifier of the functional
returns:
  The name of the functional

xc_functional_get_number

If you know the name of a functional and want to know its identifier, you can use the function

int xc_functional_get_number(const char *name);

input
  name: then name of the functional in the form "xc_gga_x_pbe" or "gga_x_pbe". Note that the name is case insesitive.
returns:
  The functional identifier

xc_number_of_functionals

This function returns the total number of functionals available in the library. It is particularly useful if one wants to construct a list of all the available functional names and/or identification numbers (see xc_available_functional_names and xc_available_functional_names).

int xc_number_of_functionals();

returns:
  Number of functionals

xc_maximum_name_length

This function returns the maximum string length of all the functional names available in the library. It is particularly useful if one wants to construct a list of all the available functional names (see xc_available_functional_names).

int xc_maximum_name_length();

returns:
  Maximum name length.

xc_available_functional_numbers

Returns a list of all known functional identifiers.

void xc_available_functional_numbers(int *list);

output:
  list: list of all the known functional identifiers.

xc_available_functional_names

Returns a list of all known functional names.

void xc_available_functional_names(char **list);

output:
  list: list of all the known functional names.

Density threshold

When the density is smaller than a certain threshold, the library will skip the evaluation of the functional and instead set all the output quantities to zero. This is to avoid underflows and/or overflows. Each functional is defined with a default threshold that should be adquate for most cases, but the range of densities in which a functional can be safely evaluated might depend on the computer architecture or the compiler and compiler flags used. Therefore, the library provides a function to change the threshold

void xc_func_set_dens_threshold(xc_func_type *p, double dens_threshold);

input
  p: structure holding the functional
  dens_threshold: the new density threshold

In order to help the user choose an appropriate value for the density threshold, the xc-threshold utility is provided to evaluate a functional for several different trial densities.

Version

The actual version of libxc being used can be obtained by calling

void xc_version (int *major, int *minor, int *micro);

output:
  major: the major version number
  minor: the minor version number
  micro: the micro version number

This information is also available in the xc_version.h header file, where XC_VERSION, XC_MAJOR_VERSION, XC_MINOR_VERSION, and XC_MICRO_VERSION symbols are defined.

Linking via GNU autotools

An m4 macro for use in a configure script for a project linking to the Fortran 90 Libxc interface is available in the distribution, taken from Octopus.