XCFun
XCFun is a library of DFT exchange-correlation (XC) functionals. It is
based on automatic differentiation and can therefore generate
arbitrary order derivatives of these functionals. For more information
see the website admol.org/xcfun.
This documentation refers to the development version of the XCFun library,
make sure that you are up to date.
Installation and linking
Compile the library using one of the
included makefiles (for example
Makefile.gcc). This will
generate a library file
lib/libxcfun.a which can be
statically linked to your application. Include files listing all
available functionals will be generated during the compilation of
XCFun. These files are
include/xcfun_autogen.h (for the C
interface), and
fortran/xcfun_autogen.F90 for the Fortran
module. C or C++ programs that uses XCFun should include the
xcfun.h header file, while Fortran programs should use the
xcfun module defined in
fortran/xcfun_module.F90.
See also Compile Time Options below.
Usage
To use the library you should first create
one xc_functional object for each functional and each thread
you want to use. Each functional object can only be used by one thread
at a time. After creating these objects
using xc_new_functional() you should set them up by defining
the variables to differentiate with respect to, as well as the
parameters of the functional you want to use. After having done so you
can use xc_eval() to evaluate the exchange correlation energy
and its derivatives.
Example C program that evaluates BLYP to order 2 using alpha/beta variables:
#include "xcfun.h"
int main(int argc, char *argv[])
{
int derivative_order = 2;
int nr_points = 1;
double density[5] = {1,2,3,5,4}; /* na nb ga.ga gb.gb ga.gb */
double output[21]; /* We have 21 output numbers for derivatives up to order 2 */
xc_functional fun = xc_new_functional();
xc_set_mode(fun, XC_VARS_AB);
xc_set_param(fun, XC_LYPC, 1.0);
xc_set_param(fun, XC_BECKEX, 1.0);
xc_eval(fun, derivative_order, nr_points, density, output);
}
Please see the complete API documentation below
Input, output and units
The library uses atomic units for all
input and output variables.
The XC energy density and derivatives can be
evaluated using local spin-up (α) and spin-down (β)
quantities. In the most general case these are
- nα The spin-up electron number density.
- nβ The spin-down density.
- σαα = ∇nα·∇nα The square magnitude of the spin-up density gradient.
- σαβ = ∇nα·∇nβ The dot product between the spin-up and spin-down gradient vectors.
- σββ = ∇nβ·∇nβ The square magnitude of the spin-down density gradient.
- τα = 1/2 Σi |∇ψiα|2 The spin-up Kohn-Sham kinetic energy density.
- τβ The spin-down Kohn-Sham kinetic energy density.
Alternatively you can use total density (
n = nα + nβ) and spin density (
s = nα - nβ) variables. These also have corresponding gradient and kinetic energy components. See
xc_set_mode() below for more information.
The output is given in graded reverse lexicographical order. For example a spin-polarized second order GGA functional will give 21 output elements, starting with the XC energy density. Symbolically we may write this as a list starting with the energy
E,
followed by five gradient elements
Eα Eβ
Eσαα
Eσαβ
Eσββ
and 15 second derivatives
Eαα
Eαβ
Eασαα
...
Eββ
Eβσαα
...
Eσββσββ. See the function xc_derivative_index() for information about addressing these elements.
API
The library is written in C++, but can also be directly used in a C
project or Fortran project. The C interface is described
in
include/xcfun.h, while the Fortran interface is described
in the module file
fortran/xcfun_module.F90. This
documentation tries to describe both the C and Fortran API at the same
time, even though small differences may exist between the two
interfaces.
Setup and Testing
const char *xcfun_splash()
Return a multi-line
string describing the library. Please print this string so that your
users find the right citation for the library. The Fortran version
is
xcfun_splash(text), and the message is put in the string
text.
xcfun_version()
Return a double precision version number of the library.
xcfun_test()
Run all internal tests and return the
number of failed tests.
Creating and destroying functional objects
xc_new_functional()
Create a new functional
object. The C version returns an object of
type
xc_functional. The Fortran version returns an
integer. The creation of this object may be rather slow; create an
object once for each calculation, not once for each grid point.
xc_free_functional(functional)
Release the memory associated with functional (previously allocated by
xc_new_functional()).
Defining a functional
xc_set_mode(functional, mode)
Set
functional to operate in
mode, one of
- XC_VARS_A Full spin polarization using only alpha
quantities, in the
order nα, σαα, τα
- XC_VARS_N Completely unpolarized mode using only total density quantities. n, σnn, τn
- XC_VARS_AB Using alpha and beta variables: nα, nβ, σαα, σαβ, σββ, τα, τβ
- XC_VARS_NS Using total density/spin polarization variables: n, s, σnn, σns, σss, τn, τs
The mode and the type of functional (LDA, GGA, metaGGA) determines the
number of variables used by the functional.
xc_set_param(functional, param, value)
Set the
parameter param in functional to some double
precision value. Param is one of the named constants
listed in include/xcfun_autogen.h
(or fortran/xcfun_autogen.F90). The parameters can be the
weight of different functionals, or some other parameter in the
functional definition. Example of parameters are XC_VWN5C,
the amount of VWN5 LDA correlation, and XC_RANGESEP_MU, the
range separation constant μ used in range separated hybrid
functionals. You can iterate over all parameters by using the XC_NR_PARAMS constant. C parameters start at 0 and Fortran parameters start at 1.
The functional weights default to 0, while other parameters default to some sensible value. The current value of a parameter can be checked with the double precision function
xc_get_param(functional, param)
which returns the
current value of
param. Note that different functionals may
have different parameter values set.
xc_name(param)
Returns the name
of param. This name is the same as the symbolic constant used
in the programming interface, so the first three characters
(XC_) can be stripped off before printing the string to the
user. The Fortran version is xc_name(param, name).
xc_short_description(param)
Return a single line
(without newline) describing
param. This may be a null string
if the parameter was not described in the library. The Fortran version
puts the description in the second argument to this subroutine.
xc_long_description(param)
Return a multi-line
string (if present) ending with a newline. This string describes the
functional or parameter in more detail, and should include references
for citation and further information. The Fortran version
puts the description in the second argument to this subroutine.
Evaluating a functional
Given a functional that has been set up using the functions above
we may evaluate this functional up to the highest order defined in
src/config.h. Increasing the maximum order increases the
compile time and size of the library, so it is important to keep this
limit rather low. The current limits of the library may be queried with
the function
xc_max_order(functional)
which returns the highest derivative order supported by the previously defined
functional.
xc_get_type(functional)
Returns one of the integers
depending on the parameters set in the functional.
xc_input_length(functional)
Returns the length of the input array (i.e. the number of density variables. This depends on the type of functional and on the evaluation mode. Typical values are 2 (LDA with incomplete spin polarization) or 5 (GGA with incomplete spin polarization).
xc_output_length(functional, order)
Return the
number of output coefficients computed by
xc_eval() if
functional is evaluate up to
order. Note that all derivatives
up to
order are calculated, not only those of the particular
order.
xc_regularize_density(functional, density)
Modify
density in-place so that
functional can be evaluated without
infinities or floating point errors. This mainly involves making sure
that the density is physical and nonzero. In cases where the
derivatives should be infinite they will instead be very large, but
otherwise the effect on the output should be minimal.
C xc_eval(functional, order, density,result)
C Vector version xc_eval_vec(functional, order, nr_points, density, density_pitch,
result, result_pitch)
Fortran xc_eval(functional, order, nr_points, densities, results)
Evaluate the previously defined functional
at nr_points different points, with derivatives up
to order. The input array density contains nr_points*N
density values, where N is the value returned by
xc_input_length(). Similarly for the output array result. The input
and output arrays have the values for each point packed together. The output values
are stored in graded lexicographical order. For an LDA functional with alpha/beta variables we would therefore have the order E Ea Eb Eaa Eab Ebb Eaaa Eaab Eabb Ebbb ...
The C vector version accepts two 'pitch' arguments, which is the
distance in memory between the first elements of each point in the
input and output arrays.
The Fortran always works on an array of points, and automatically
determines the pitch values. Note that the input numbers for each
point must be consecutive in memory (stride must be one).
xc_potential(functional, density, energy, potential)
Compute the XC energy and potential (potential[0] is alpha and potential[1] is beta) at a single point. For LDA this is
simply vαxc = dE/dnα and for GGA the expression is
vαxc = dE/dnα - ∇·dE/d∇nα. The latter case thus needs the evaluation of the second derivatives of the functional.
In the case of GGA the values of the density laplacians should be given at the end of the density array,
giving at total of seven numbers in the XC_VARS_AB case (which is the only one supported at the moment).
This function has to be called one point at a time.
MetaGGA's are not supported at the moment, although this is in principle possible to implement for functionals
that depend on the density laplacian (but not on the kinetic energy density).
xc_derivative_index(functional, derivative)
Given an
integer array of "exponents" this function returns the index into the
output array of xc_eval where the corresponding derivative is
located. Note that this position depends on the functional type and
mode. Alternatively you can, for low orders, use the predefined constants
of the form
XC_D01000 (which corresponds to the first derivative
with respect to the second variable,
for setups with five variables). To use these
predefined constants you must therefore know the type of your functional
beforehand. For LDA in a two variable mode the corresponding constant would be
XC_D01, but this is a
different index from
XC_D01000.
Compile Time Options
The file
src/config.h contains a number of compile time options. These are
- XC_MAX_ORDER Define this to the highest order of
derivatives that the library should support. Too high values make
the library huge in size.
- XC_NO_REGULARIZATION Define this to turn off
regularization of the input densities in xc_eval(). If you
use this option and feed the library unphysical densities it can and
will stop or crash. Use mainly to investigate numerical behaviour
near singular points.
- XC_NO_SCHWARZ_REGULARIZATION Do not strictly enforce
the Schwarz inequality for the gradient norms. This inequality can
be violated without encountering any problems for most functionals,
and it's suggested that this option is kept active (i.e. the
regularization is turned off).
- XCFUN_IN_DEVELOPMENT Enable code that is still "in
development". This code is probably marked "in development" for a
reason, and may contain bugs.
- XCFUN_REF_PW92C Use the truncated valued from the
reference implementation for some exact constants in the PW92C
correlation functional. This can help getting an exact agreement
with other implementations. Functionals that use PW92C (i.e.
PBEC) are also affected by this options.