diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b3e8964563d4e49f692aa46e74ecb23aa471c183 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# genxc + +New approach to generate fast code based on libxc, this repository is organized as follows: + +- **src**: code generation approach with SymPy. +- **ref**: case study with gga\_x\_pbe to evaluate performance benefits before having full approach developed. diff --git a/ref/Makefile b/ref/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cc7aaa4467017777414fb7f3914968b935e58323 --- /dev/null +++ b/ref/Makefile @@ -0,0 +1,34 @@ +# GCC +#CC=/usr/bin/cc +#CFLAGS=-O3 -DHAVE_CBRT -DXC_DONT_COMPILE_KXC -DXC_DONT_COMPILE_LXC -std=gnu99 -lm -fopenmp + +# Intel compiler +CC=/apps/intel/ComposerXE2019/compilers_and_libraries_2019.5.281/linux/bin/intel64/icc +#CFLAGS=-xHost -O3 -DHAVE_CBRT -DXC_DONT_COMPILE_KXC -DXC_DONT_COMPILE_LXC -std=gnu99 -lm -fopenmp +CFLAGS=-xCORE-AVX512 -Ofast -qopt-zmm-usage=high -DHAVE_CBRT -DXC_DONT_COMPILE_KXC -DXC_DONT_COMPILE_LXC -std=gnu99 -lm -fopenmp + +LINKER=$(CC) +BUILD_DIR=build +Q?=@ + +VPATH=common libxc genxc +OBJ = $(patsubst common/%.c, $(BUILD_DIR)/%.o, $(wildcard common/*.c)) +OBJ += $(patsubst libxc/%.c, $(BUILD_DIR)/%.o, $(wildcard libxc/*.c)) +OBJ += $(patsubst genxc/%.c, $(BUILD_DIR)/%.o, $(wildcard genxc/*.c)) + +main: $(BUILD_DIR) main.c $(OBJ) + $(info ===> LINKING AND COMPILING $@) + $(Q)${LINKER} -o $@ main.c $(OBJ) $(CFLAGS) + +$(BUILD_DIR)/%.o: %.c + $(info ===> COMPILE $@) + $(Q)$(CC) -c $< -o $@ $(CFLAGS) + +$(BUILD_DIR): + @mkdir -p $(BUILD_DIR) + +.PHONY: clean + +clean: + @rm -f gga_x_pbe + @rm -rf $(BUILD_DIR) diff --git a/ref/common/functionals.c b/ref/common/functionals.c new file mode 100644 index 0000000000000000000000000000000000000000..94eb6a69e47191f568280cc6ca4853b6e88b36f1 --- /dev/null +++ b/ref/common/functionals.c @@ -0,0 +1,492 @@ +/* + Copyright (C) 2006-2021 M.A.L. Marques + 2015-2021 Susi Lehtola + 2019 X. Andrade + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#include "xc.h" +#include "registered_funcs.h" +#include <string.h> +#ifdef _MSC_VER +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#else +#include <strings.h> +#endif + +/*------------------------------------------------------*/ +int xc_functional_get_number(const char *name) +{ + int ii; + int key=-1; + const char *p; + + /* Does name begin with xc_? */ + if(strncasecmp(name,"XC_",3) == 0) { + p=name+3; + } else { + p=name; + } + + for(ii=0;;ii++){ + if(xc_functional_keys[ii].number == -1) + break; + if(strcasecmp(xc_functional_keys[ii].name, p) == 0){ + key = xc_functional_keys[ii].number; + break; + } + } + + return key; +} + + +/*------------------------------------------------------*/ +char *xc_functional_get_name(int number) +{ + int ii; + char *p; + + for(ii=0;;ii++){ + if(xc_functional_keys[ii].number == -1) + return NULL; + if(xc_functional_keys[ii].number == number) { + /* return duplicated: caller has the responsibility to dealloc string. + Do this the old way since strdup and strndup aren't C standard. */ + p = (char *) libxc_malloc(strlen(xc_functional_keys[ii].name) + 1); + strcpy(p,xc_functional_keys[ii].name); + return p; + } + } +} + + +/*------------------------------------------------------*/ +int xc_family_from_id(int id, int *family, int *number) +{ + int ii; + + /* first let us check if it is an LDA */ + for(ii=0; xc_lda_known_funct[ii]!=NULL; ii++){ + if(xc_lda_known_funct[ii]->number == id){ + if(family != NULL) *family = XC_FAMILY_LDA; + if(number != NULL) *number = ii; + return XC_FAMILY_LDA; + } + } + + /* or is it a GGA? */ + for(ii=0; xc_gga_known_funct[ii]!=NULL; ii++){ + if(xc_gga_known_funct[ii]->number == id){ + if(family != NULL) *family = XC_FAMILY_GGA; + if(number != NULL) *number = ii; + return XC_FAMILY_GGA; + } + } + + /* or is it a meta GGA? */ + for(ii=0; xc_mgga_known_funct[ii]!=NULL; ii++){ + if(xc_mgga_known_funct[ii]->number == id){ + if(family != NULL) *family = XC_FAMILY_MGGA; + if(number != NULL) *number = ii; + return XC_FAMILY_MGGA; + } + } + + return XC_FAMILY_UNKNOWN; +} + +/*------------------------------------------------------*/ +int xc_number_of_functionals() +{ + int num; + + for(num=0;;num++){ + if(xc_functional_keys[num].number == -1) + return num; + } + + fprintf(stderr, "Internal error in functionals.c\n"); + exit(1); +} + +int xc_maximum_name_length() +{ + int i, N, maxlen, tmp; + + N=xc_number_of_functionals(); + + maxlen=0; + for(i=0;i<N;i++){ + tmp=strlen(xc_functional_keys[i].name); + if(tmp > maxlen) maxlen=tmp; + } + + return maxlen; +} + +/*------------------------------------------------------*/ +static int compare_int(const void *a, const void *b) { + return *(int *)a - *(int *) b; +} + +void xc_available_functional_numbers(int *list) +{ + int ii, N; + N=xc_number_of_functionals(); + for(ii=0;ii<N;ii++){ + list[ii]=xc_functional_keys[ii].number; + } + /* Sort list by id */ + qsort(list, N, sizeof(int), compare_int); +} + +static int compare_func_names(const void *a, const void *b) { + int ia, ib; + int fama, famb; + int hyba, hybb; + + ia = *(int *)a; + ib = *(int *)b; + + /* First we sort by the family: LDAs, GGAs, meta-GGAs */ + fama = xc_family_from_id(xc_functional_keys[ia].number, NULL, NULL); + famb = xc_family_from_id(xc_functional_keys[ib].number, NULL, NULL); + if(fama < famb) + return -1; + else if(fama > famb) + return 1; + + /* Then we sort by hybrid type: non-hybrids go first */ + hyba = (strncmp(xc_functional_keys[ia].name, "hyb_", 4) == 0); + hybb = (strncmp(xc_functional_keys[ib].name, "hyb_", 4) == 0); + if(!hyba && hybb) + return -1; + else if(hyba && !hybb) + return 1; + + /* Last we sort by name */ + return strcmp(xc_functional_keys[ia].name, xc_functional_keys[ib].name); +} + +void xc_available_functional_numbers_by_name(int *list) +{ + int ii, N; + + /* Arrange list of functional IDs by name */ + N=xc_number_of_functionals(); + for(ii=0;ii<N;ii++) { + list[ii]=ii; + } + qsort(list, N, sizeof(int), compare_func_names); + /* Map the internal list to functional IDs */ + for(ii=0;ii<N;ii++){ + list[ii]=xc_functional_keys[list[ii]].number; + } +} + +void xc_available_functional_names(char **list) +{ + int ii, N; + int *idlist; + + /* Arrange list of functional IDs by name */ + N=xc_number_of_functionals(); + idlist=(int *) libxc_malloc(N*sizeof(int)); + for(ii=0;ii<N;ii++) { + idlist[ii]=ii; + } + qsort(idlist, N, sizeof(int), compare_func_names); + + /* Now store the correctly ordered output */ + for(ii=0;ii<N;ii++) { + strcpy(list[ii],xc_functional_keys[idlist[ii]].name); + } + + /* Deallocate work array */ + libxc_free(idlist); +} + +/*------------------------------------------------------*/ +xc_func_type *xc_func_alloc() +{ + xc_func_type *func; + + func = (xc_func_type *) libxc_malloc (sizeof (xc_func_type)); + return func; +} + +/*------------------------------------------------------*/ +void xc_func_nullify(xc_func_type *func) +{ + assert(func != NULL); + + func->info = NULL; + func->nspin = XC_UNPOLARIZED; + + func->n_func_aux = 0; + func->func_aux = NULL; + func->mix_coef = NULL; + + func->hyb_number_terms = 0; + func->hyb_type = NULL; + func->hyb_coeff = NULL; + func->hyb_omega = NULL; + + func->nlc_b = func->nlc_C = 0.0; + + func->ext_params = NULL; + func->params = NULL; + + func->dens_threshold = 0.0; + func->zeta_threshold = 0.0; + func->sigma_threshold = 0.0; + func->tau_threshold = 0.0; +} + +/*------------------------------------------------------*/ +int xc_func_init(xc_func_type *func, int functional, int nspin) +{ + int number; + + assert(func != NULL); + assert(nspin==XC_UNPOLARIZED || nspin==XC_POLARIZED); + + xc_func_nullify(func); + + /* initialize structure */ + func->nspin = nspin; + + // we have to make a copy because the *_known_funct arrays live in + // host memory (libxc_malloc instead returns memory than can be read + // from GPU and CPU). + xc_func_info_type * finfo = (xc_func_info_type *) libxc_malloc(sizeof(xc_func_info_type)); + + // initialize the dimension structure + libxc_memset(&(func->dim), 0, sizeof(xc_dimensions)); + switch(xc_family_from_id(functional, NULL, &number)){ + case(XC_FAMILY_LDA): + *finfo = *xc_lda_known_funct[number]; + internal_counters_set_lda(func->nspin, &(func->dim)); + break; + + case(XC_FAMILY_GGA): + *finfo = *xc_gga_known_funct[number]; + internal_counters_set_gga(func->nspin, &(func->dim)); + break; + + case(XC_FAMILY_MGGA): + *finfo = *xc_mgga_known_funct[number]; + internal_counters_set_mgga(func->nspin, &(func->dim)); + break; + + default: + return -2; /* family not found */ + } + + func->info = finfo; + + /* this is initialized for each functional from the info */ + func->dens_threshold = func->info->dens_threshold; + /* the density and sigma cutoffs should be connected, especially in + the case of kinetic energy functionals. This is the correct + scaling */ + func->sigma_threshold = pow(func->info->dens_threshold, 4.0/3.0); + + /* these are reasonable defaults */ + func->zeta_threshold = DBL_EPSILON; + func->tau_threshold = 1e-20; + + /* see if we need to initialize the functional */ + if(func->info->init != NULL) + func->info->init(func); + + /* see if we need to initialize the external parameters */ + if(func->info->ext_params.n > 0) { + func->ext_params = (double *) libxc_malloc(func->info->ext_params.n * sizeof(double)); + xc_func_set_ext_params(func, func->info->ext_params.values); + } + + return 0; +} + + +/*------------------------------------------------------*/ +void xc_func_end(xc_func_type *func) +{ + assert(func != NULL && func->info != NULL); + + /* call internal termination routine */ + if(func->info->end != NULL) + func->info->end(func); + + /* terminate any auxiliary functional */ + if(func->n_func_aux > 0){ + int ii; + + for(ii=0; ii<func->n_func_aux; ii++){ + xc_func_end(func->func_aux[ii]); + libxc_free(func->func_aux[ii]); + } + libxc_free(func->func_aux); + } + + /* deallocate coefficients for mixed functionals */ + if(func->mix_coef != NULL) + libxc_free(func->mix_coef); + + /* deallocate hybrid coefficients */ + if(func->hyb_type != NULL){ + libxc_free(func->hyb_type); + libxc_free(func->hyb_omega); + libxc_free(func->hyb_coeff); + } + + /* deallocate any used parameter */ + if(func->ext_params != NULL) + libxc_free(func->ext_params); + if(func->params != NULL) + libxc_free(func->params); + + libxc_free((void *) func->info); + + xc_func_nullify(func); +} + +/*------------------------------------------------------*/ +void xc_func_free(xc_func_type *p) +{ + libxc_free(p); +} + +/*------------------------------------------------------*/ +const xc_func_info_type *xc_func_get_info(const xc_func_type *p) +{ + return p->info; +} + +/*------------------------------------------------------*/ +void xc_func_set_dens_threshold(xc_func_type *p, double t_dens) +{ + int ii; + + if(t_dens > 0.0) + p->dens_threshold = t_dens; + + for(ii=0; ii<p->n_func_aux; ii++) { + xc_func_set_dens_threshold(p->func_aux[ii], t_dens); + } +} +/*------------------------------------------------------*/ +void xc_func_set_zeta_threshold(xc_func_type *p, double t_zeta) +{ + int ii; + + if(t_zeta > 0.0) + p->zeta_threshold = t_zeta; + + for(ii=0; ii<p->n_func_aux; ii++) { + xc_func_set_zeta_threshold(p->func_aux[ii], t_zeta); + } +} +/*------------------------------------------------------*/ +void xc_func_set_sigma_threshold(xc_func_type *p, double t_sigma) +{ + int ii; + + if(t_sigma > 0.0) + p->sigma_threshold = t_sigma; + + for(ii=0; ii<p->n_func_aux; ii++) { + xc_func_set_sigma_threshold(p->func_aux[ii], t_sigma); + } +} +/*------------------------------------------------------*/ +void xc_func_set_tau_threshold(xc_func_type *p, double t_tau) +{ + int ii; + + if(t_tau > 0.0) + p->tau_threshold = t_tau; + + for(ii=0; ii<p->n_func_aux; ii++) { + xc_func_set_tau_threshold(p->func_aux[ii], t_tau); + } +} + +/*------------------------------------------------------*/ +/* get/set external parameters */ +void +xc_func_set_ext_params(xc_func_type *p, const double *ext_params) +{ + int ii; + + assert(p->info->ext_params.n > 0); + /* We always store the current parameters in the functional instance */ + for(ii=0; ii<p->info->ext_params.n; ii++) + p->ext_params[ii] = (ext_params[ii] == XC_EXT_PARAMS_DEFAULT) ? p->info->ext_params.values[ii] : ext_params[ii]; + /* Update the parameters */ + p->info->ext_params.set(p, p->ext_params); +} + +void +xc_func_get_ext_params(const xc_func_type *p, double *ext_params) +{ + int ii; + assert(p->info->ext_params.n > 0); + assert(ext_params != NULL); + for(ii=0; ii<p->info->ext_params.n; ii++) + ext_params[ii] = p->ext_params[ii]; +} + +static int +xc_func_find_ext_params_name(const xc_func_type *p, const char *name) { + int ii; + assert(p != NULL && p->info->ext_params.n > 0); + for(ii=0; ii<p->info->ext_params.n; ii++){ + if(strcmp(p->info->ext_params.names[ii], name) == 0) { + return ii; + } + } + return -1; +} + +void +xc_func_set_ext_params_name(xc_func_type *p, const char *name, double par) +{ + int ii; + + ii = xc_func_find_ext_params_name(p, name); + assert(ii>=0); + p->ext_params[ii] = par; + xc_func_set_ext_params(p, p->ext_params); +} + +double +xc_func_get_ext_params_name(const xc_func_type *p, const char *name) +{ + int ii; + + ii = xc_func_find_ext_params_name(p, name); + assert(ii>=0); + return p->ext_params[ii]; +} + +double +xc_func_get_ext_params_value(const xc_func_type *p, int index) +{ + return p->ext_params[index]; +} + +/* returns the NLC parameters */ +void xc_nlc_coef(const xc_func_type *p, double *nlc_b, double *nlc_C) +{ + assert(p!=NULL); + + *nlc_b = p->nlc_b; + *nlc_C = p->nlc_C; +} diff --git a/ref/common/gga.c b/ref/common/gga.c new file mode 100644 index 0000000000000000000000000000000000000000..301a09ab5456c22a7cdfe2df393ea72d14eb3e94 --- /dev/null +++ b/ref/common/gga.c @@ -0,0 +1,221 @@ +/* + Copyright (C) 2006-2007 M.A.L. Marques + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + + +#include "util.h" + +/* Some useful formulas: + + sigma_st = grad rho_s . grad rho_t + zk = energy density per unit particle + + vrho_s = d zk / d rho_s + vsigma_st = d n*zk / d sigma_st + + v2rho2_st = d^2 n*zk / d rho_s d rho_t + v2rhosigma_svx = d^2 n*zk / d rho_s d sigma_tv + v2sigma2_stvx = d^2 n*zk / d sigma_st d sigma_vx + + v3rho3_stv = d^3 n*zk / d rho_s d rho_t d rho_v + v3rho2sigma_stvx = d^3 n*zk / d rho_s d rho_t d sigma_vx + v3rhosigma2_svxyz = d^3 n*zk / d rho_s d sigma_vx d sigma_yz + v3sigma3_stvxyz = d^3 n*zk / d sigma_st d sigma_vx d sigma_yz + +if nspin == 2 + rho(2) = (u, d) + sigma(3) = (uu, ud, dd) + + vrho(2) = (u, d) + vsigma(3) = (uu, ud, dd) + + v2rho2(3) = (u_u, u_d, d_d) + v2rhosigma(6) = (u_uu, u_ud, u_dd, d_uu, d_ud, d_dd) + v2sigma2(6) = (uu_uu, uu_ud, uu_dd, ud_ud, ud_dd, dd_dd) + + v3rho3(4) = (u_u_u, u_u_d, u_d_d, d_d_d) + v3rho2sigma(9) = (u_u_uu, u_u_ud, u_u_dd, u_d_uu, u_d_ud, u_d_dd, d_d_uu, d_d_ud, d_d_dd) + v3rhosigma2(12) = (u_uu_uu, u_uu_ud, u_uu_dd, u_ud_ud, u_ud_dd, u_dd_dd, d_uu_uu, d_uu_ud, d_uu_dd, d_ud_ud, d_ud_dd, d_dd_dd) + v3sigma(10) = (uu_uu_uu, uu_uu_ud, uu_uu_dd, uu_ud_ud, uu_ud_dd, uu_dd_dd, ud_ud_ud, ud_ud_dd, ud_dd_dd, dd_dd_dd) + +*/ +void xc_gga(const xc_func_type *func, size_t np, const double *rho, const double *sigma, + double *zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )) +{ + const xc_dimensions *dim = &(func->dim); + + /* sanity check */ + if(zk != NULL && !(func->info->flags & XC_FLAGS_HAVE_EXC)){ + fprintf(stderr, "Functional '%s' does not provide an implementation of Exc\n", + func->info->name); + exit(1); + } + + if(vrho != NULL && !(func->info->flags & XC_FLAGS_HAVE_VXC)){ + fprintf(stderr, "Functional '%s' does not provide an implementation of vxc\n", + func->info->name); + exit(1); + } + + if(v2rho2 != NULL && !(func->info->flags & XC_FLAGS_HAVE_FXC)){ + fprintf(stderr, "Functional '%s' does not provide an implementation of fxc\n", + func->info->name); + exit(1); + } + + if(v3rho3 != NULL && !(func->info->flags & XC_FLAGS_HAVE_KXC)){ + fprintf(stderr, "Functional '%s' does not provide an implementation of kxc\n", + func->info->name); + exit(1); + } + + if(v4rho4 != NULL && !(func->info->flags & XC_FLAGS_HAVE_LXC)){ + fprintf(stderr, "Functional '%s' does not provide an implementation of lxc\n", + func->info->name); + exit(1); + } + + /* initialize output to zero */ + if(zk != NULL) + libxc_memset(zk, 0, dim->zk*np*sizeof(double)); + + if(vrho != NULL){ + assert(vsigma != NULL); + + libxc_memset(vrho, 0, dim->vrho *np*sizeof(double)); + libxc_memset(vsigma, 0, dim->vsigma*np*sizeof(double)); + } + + if(v2rho2 != NULL){ + assert(v2rhosigma!=NULL && v2sigma2!=NULL); + + libxc_memset(v2rho2, 0, dim->v2rho2 *np*sizeof(double)); + libxc_memset(v2rhosigma, 0, dim->v2rhosigma*np*sizeof(double)); + libxc_memset(v2sigma2, 0, dim->v2sigma2 *np*sizeof(double)); + } + + if(v3rho3 != NULL){ + assert(v3rho2sigma!=NULL && v3rhosigma2!=NULL && v3sigma3!=NULL); + + libxc_memset(v3rho3, 0, dim->v3rho3 *np*sizeof(double)); + libxc_memset(v3rho2sigma, 0, dim->v3rho2sigma*np*sizeof(double)); + libxc_memset(v3rhosigma2, 0, dim->v3rhosigma2*np*sizeof(double)); + libxc_memset(v3sigma3, 0, dim->v3sigma3 *np*sizeof(double)); + } + + if(v4rho4 != NULL){ + assert(v4rho3sigma!=NULL && v4rho2sigma2!=NULL && v4rhosigma3!=NULL && v4sigma4!=NULL); + + libxc_memset(v4rho4, 0, dim->v4rho4 *np*sizeof(double)); + libxc_memset(v4rho3sigma, 0, dim->v4rho3sigma *np*sizeof(double)); + libxc_memset(v4rho2sigma2, 0, dim->v4rho2sigma2*np*sizeof(double)); + libxc_memset(v4rhosigma3, 0, dim->v4rhosigma3 *np*sizeof(double)); + libxc_memset(v4sigma4, 0, dim->v4sigma4 *np*sizeof(double)); + } + + /* call functional */ + if(func->info->gga != NULL) + func->info->gga(func, np, rho, sigma, zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA, )); + + /* + if(func->mix_coef != NULL) + xc_mix_func(func, np, rho, sigma, NULL, NULL, zk, vrho, vsigma, NULL, NULL, + v2rho2, v2rhosigma, NULL, NULL, v2sigma2, NULL, NULL, NULL, NULL, NULL, + v3rho3, v3rho2sigma, NULL, NULL, v3rhosigma2, NULL, NULL, NULL, NULL, NULL, + v3sigma3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + v4rho4, v4rho3sigma, NULL, NULL, v4rho2sigma2, NULL, NULL, NULL, NULL, NULL, + v4rhosigma3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + v4sigma4, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); + */ +} + +/* specializations */ +/* returns only energy */ +void +xc_gga_exc(const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *zk) +{ + xc_gga(p, np, rho, sigma, zk, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); +} + +/* returns only potential */ +void +xc_gga_vxc(const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *vrho, double *vsigma) +{ + xc_gga(p, np, rho, sigma, NULL, vrho, vsigma, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); +} + +/* returns both energy and potential (the most common call usually) */ +void +xc_gga_exc_vxc(const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *zk, double *vrho, double *vsigma) +{ + xc_gga(p, np, rho, sigma, zk, vrho, vsigma, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); +} + +/* returns energy, first and second derivatives */ +void xc_gga_exc_vxc_fxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *zk, double *vrho, double *vsigma, + double *v2rho2, double *v2rhosigma, double *v2sigma2) { + xc_gga(p, np, rho, sigma, zk, vrho, vsigma, v2rho2, v2rhosigma, v2sigma2, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); +} + +void xc_gga_vxc_fxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *vrho, double *vsigma, + double *v2rho2, double *v2rhosigma, double *v2sigma2) { + xc_gga(p, np, rho, sigma, NULL, vrho, vsigma, v2rho2, v2rhosigma, v2sigma2, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); +} + +/* returns energy, first, second and third derivatives */ +void xc_gga_exc_vxc_fxc_kxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *zk, double *vrho, double *vsigma, double *v2rho2, double *v2rhosigma, double *v2sigma2, + double *v3rho3, double *v3rho2sigma, double *v3rhosigma2, double *v3sigma3) { + xc_gga(p, np, rho, sigma, zk, vrho, vsigma, v2rho2, v2rhosigma, v2sigma2, v3rho3, v3rho2sigma, v3rhosigma2, v3sigma3, + NULL, NULL, NULL, NULL, NULL); +} + +void xc_gga_vxc_fxc_kxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *vrho, double *vsigma, double *v2rho2, double *v2rhosigma, double *v2sigma2, + double *v3rho3, double *v3rho2sigma, double *v3rhosigma2, double *v3sigma3) { + xc_gga(p, np, rho, sigma, NULL, vrho, vsigma, v2rho2, v2rhosigma, v2sigma2, v3rho3, v3rho2sigma, v3rhosigma2, v3sigma3, + NULL, NULL, NULL, NULL, NULL); +} + + +/* returns second derivatives */ +void +xc_gga_fxc(const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *v2rho2, double *v2rhosigma, double *v2sigma2) +{ + xc_gga(p, np, rho, sigma, NULL, NULL, NULL, v2rho2, v2rhosigma, v2sigma2, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); +} + +/* returns third derivatives */ +void +xc_gga_kxc(const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *v3rho3, double *v3rho2sigma, double *v3rhosigma2, double *v3sigma3) +{ + xc_gga(p, np, rho, sigma, NULL, NULL, NULL, NULL, NULL, NULL, v3rho3, v3rho2sigma, v3rhosigma2, v3sigma3, + NULL, NULL, NULL, NULL, NULL); +} + +/* returns fourth derivatives */ +void +xc_gga_lxc(const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *v4rho4, double *v4rho3sigma, double *v4rho2sigma2, double *v4rhosigma3, double *v4sigma4) +{ + xc_gga(p, np, rho, sigma, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + v4rho4, v4rho3sigma, v4rho2sigma2, v4rhosigma3, v4sigma4); +} diff --git a/ref/common/registered_funcs.h b/ref/common/registered_funcs.h new file mode 100644 index 0000000000000000000000000000000000000000..189fbff70f9d136fb19411667695eb0467126ac1 --- /dev/null +++ b/ref/common/registered_funcs.h @@ -0,0 +1,69 @@ +#include "xc.h" +#include "util.h" + +#ifndef __REGISTERED_FUNCS_H__ +#define __REGISTERED_FUNCS_H__ + +xc_functional_key_t xc_functional_keys[] = { +{"gga_x_pbe_mol", 49}, +{"gga_x_pbe_tca", 59}, +{"gga_x_pbe", 101}, +{"gga_x_pbe_r", 102}, +{"gga_x_pbe_sol", 116}, +{"gga_x_pbe_jsjr", 126}, +{"gga_x_pbek1_vdw", 140}, +{"gga_x_pbefe", 265}, +{"gga_x_pbe_mol_genxc", 1049}, +{"gga_x_pbe_tca_genxc", 1059}, +{"gga_x_pbe_genxc", 1101}, +{"gga_x_pbe_r_genxc", 1102}, +{"gga_x_pbe_sol_genxc", 1116}, +{"gga_x_pbe_jsjr_genxc", 1126}, +{"gga_x_pbek1_vdw_genxc", 1140}, +{"gga_x_pbefe_genxc", 1265}, +{"", -1}, +}; + +extern xc_func_info_type xc_func_info_gga_x_pbe_mol; +extern xc_func_info_type xc_func_info_gga_x_pbe_tca; +extern xc_func_info_type xc_func_info_gga_x_pbe; +extern xc_func_info_type xc_func_info_gga_x_pbe_r; +extern xc_func_info_type xc_func_info_gga_x_pbe_sol; +extern xc_func_info_type xc_func_info_gga_x_pbe_jsjr; +extern xc_func_info_type xc_func_info_gga_x_pbek1_vdw; +extern xc_func_info_type xc_func_info_gga_x_pbefe; +extern xc_func_info_type xc_func_info_gga_x_bcgp; +extern xc_func_info_type xc_func_info_gga_x_pbe_mol_genxc; +extern xc_func_info_type xc_func_info_gga_x_pbe_tca_genxc; +extern xc_func_info_type xc_func_info_gga_x_pbe_genxc; +extern xc_func_info_type xc_func_info_gga_x_pbe_r_genxc; +extern xc_func_info_type xc_func_info_gga_x_pbe_sol_genxc; +extern xc_func_info_type xc_func_info_gga_x_pbe_jsjr_genxc; +extern xc_func_info_type xc_func_info_gga_x_pbek1_vdw_genxc; +extern xc_func_info_type xc_func_info_gga_x_pbefe_genxc; +extern xc_func_info_type xc_func_info_gga_x_bcgp_genxc; + +const xc_func_info_type *xc_lda_known_funct[] = {}; +const xc_func_info_type *xc_mgga_known_funct[] = {}; +const xc_func_info_type *xc_gga_known_funct[] = { + &xc_func_info_gga_x_pbe_mol, + &xc_func_info_gga_x_pbe_tca, + &xc_func_info_gga_x_pbe, + &xc_func_info_gga_x_pbe_r, + &xc_func_info_gga_x_pbe_sol, + &xc_func_info_gga_x_pbe_jsjr, + &xc_func_info_gga_x_pbek1_vdw, + &xc_func_info_gga_x_pbefe, + &xc_func_info_gga_x_bcgp, + &xc_func_info_gga_x_pbe_mol_genxc, + &xc_func_info_gga_x_pbe_tca_genxc, + &xc_func_info_gga_x_pbe_genxc, + &xc_func_info_gga_x_pbe_r_genxc, + &xc_func_info_gga_x_pbe_sol_genxc, + &xc_func_info_gga_x_pbe_jsjr_genxc, + &xc_func_info_gga_x_pbek1_vdw_genxc, + &xc_func_info_gga_x_pbefe_genxc, + &xc_func_info_gga_x_bcgp_genxc, +}; + +#endif diff --git a/ref/common/util.c b/ref/common/util.c new file mode 100644 index 0000000000000000000000000000000000000000..a394bcb69238cd803bfb80dc4023869edb066698 --- /dev/null +++ b/ref/common/util.c @@ -0,0 +1,947 @@ +/* + Copyright (C) 2006-2021 M.A.L. Marques + 2015-2021 Susi Lehtola + 2019 X. Andrade + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + + +#include "util.h" + + +/* this function converts the spin-density into total density and + relative magnetization */ +/* inline */ GPU_FUNCTION void +xc_rho2dzeta(int nspin, const double *rho, double *d, double *zeta) +{ + if(nspin==XC_UNPOLARIZED){ + *d = m_max(rho[0], 0.0); + *zeta = 0.0; + }else{ + *d = rho[0] + rho[1]; + if(*d > 0.0){ + *zeta = (rho[0] - rho[1])/(*d); + *zeta = m_min(*zeta, 1.0); + *zeta = m_max(*zeta, -1.0); + }else{ + *d = 0.0; + *zeta = 0.0; + } + } +} + +const char *get_kind(const xc_func_type *func) { + switch(func->info->kind) { + case(XC_EXCHANGE): + return "XC_EXCHANGE"; + + case(XC_CORRELATION): + return "XC_CORRELATION"; + + case(XC_EXCHANGE_CORRELATION): + return "XC_EXCHANGE_CORRELATION"; + + case(XC_KINETIC): + return "XC_KINETIC"; + + default: + printf("Internal error in get_kind.\n"); + return ""; + } +} + +const char *get_family(const xc_func_type *func) { + switch(func->info->family) { + case(XC_FAMILY_UNKNOWN): + return "XC_FAMILY_UNKNOWN"; + + case(XC_FAMILY_LDA): + return "XC_FAMILY_LDA"; + + case(XC_FAMILY_GGA): + return "XC_FAMILY_GGA"; + + case(XC_FAMILY_MGGA): + return "XC_FAMILY_MGGA"; + + case(XC_FAMILY_LCA): + return "XC_FAMILY_LCA"; + + case(XC_FAMILY_OEP): + return "XC_FAMILY_OEP"; + + default: + printf("Internal error in get_family.\n"); + return ""; + } +} + +/* this function checks if it should use the default or + the user assigned value for an external parameter */ +double +get_ext_param(const xc_func_type *func, const double *values, int index) +{ + assert(index >= 0 && index < func->info->ext_params.n); + return func->ext_params[index]; +} + +/* Copy n parameters, assumes that p->params is just a series of doubles + so it can be accessed as a array, and and copies + ext_params to this. */ +static void copy_params(xc_func_type *p, const double *ext_params, int nparams) { + double *params; + int ii; + + assert(nparams >= 0); + if(nparams) { + /* Some functionals only set the hybrid parameters which require no extra storage */ + assert(p->params != NULL); + params = (double *) (p->params); + for(ii=0; ii<nparams; ii++) + params[ii] = get_ext_param(p, ext_params, ii); + } +} + +/* Just copy the parameters */ +void +set_ext_params_cpy(xc_func_type *p, const double *ext_params) +{ + int nparams; + assert(p != NULL); + nparams = p->info->ext_params.n; + copy_params(p, ext_params, nparams); +} + +/* + Copies parameters and sets the screening parameter, which should be + the last parameter of the functional. +*/ +void +set_ext_params_cpy_omega(xc_func_type *p, const double *ext_params) +{ + int nparams; + assert(p != NULL); + nparams = p->info->ext_params.n-1; + copy_params(p, ext_params, nparams); + + /* This omega is only meant for internal use */ + assert(p->hyb_number_terms == 1); + p->hyb_type[0] = XC_HYB_NONE; + p->hyb_coeff[0] = 0.0; + p->hyb_omega[0] = get_ext_param(p, ext_params, nparams); +} + +/* + Copies parameters and sets the exact exchange coefficient, which + should be the last parameter of the functional. +*/ +void +set_ext_params_cpy_exx(xc_func_type *p, const double *ext_params) +{ + int nparams; + assert(p != NULL); + nparams = p->info->ext_params.n-1; + copy_params(p, ext_params, nparams); + + assert(p->hyb_number_terms == 1); + p->hyb_type[0] = XC_HYB_FOCK; + p->hyb_coeff[0] = get_ext_param(p, ext_params, nparams); + p->hyb_omega[0] = 0.0; +} + +/* + Copies parameters and sets the HYB coefficients, which + should be the three last parameters of the functional. +*/ +void +set_ext_params_cpy_cam(xc_func_type *p, const double *ext_params) +{ + int nparams; + assert(p != NULL); + nparams = p->info->ext_params.n - 3; + copy_params(p, ext_params, p->info->ext_params.n - 3); + + assert(p->hyb_number_terms == 2); + p->hyb_type[0] = XC_HYB_ERF_SR; + p->hyb_coeff[0] = get_ext_param(p, ext_params, nparams + 1); + p->hyb_omega[0] = get_ext_param(p, ext_params, nparams + 2); + + p->hyb_type[1] = XC_HYB_FOCK; + p->hyb_coeff[1] = get_ext_param(p, ext_params, nparams); + p->hyb_omega[1] = 0.0; +} + +void +set_ext_params_cpy_camy(xc_func_type *p, const double *ext_params) +{ + set_ext_params_cpy_cam(p, ext_params); + p->hyb_type[0] = XC_HYB_YUKAWA_SR; +} + +/* + Short-range-only version +*/ +void +set_ext_params_cpy_cam_sr(xc_func_type *p, const double *ext_params) +{ + int nparams; + assert(p != NULL); + nparams = p->info->ext_params.n - 2; + copy_params(p, ext_params, p->info->ext_params.n - 2); + + assert(p->hyb_number_terms == 1); + p->hyb_type[0] = XC_HYB_ERF_SR; + p->hyb_coeff[0] = get_ext_param(p, ext_params, nparams); + p->hyb_omega[0] = get_ext_param(p, ext_params, nparams + 1); +} + +/* Long-range corrected functionals typically only have one parameter: the range separation parameter */ +void +set_ext_params_cpy_lc(xc_func_type *p, const double *ext_params) +{ + int nparams; + assert(p != NULL); + nparams = p->info->ext_params.n - 1; + copy_params(p, ext_params, p->info->ext_params.n - 1); + + assert(p->hyb_number_terms == 2); + p->hyb_type[0] = XC_HYB_ERF_SR; + p->hyb_coeff[0] = -1.0; + p->hyb_omega[0] = get_ext_param(p, ext_params, nparams); + + p->hyb_type[1] = XC_HYB_FOCK; + p->hyb_coeff[1] = 1.0; + p->hyb_omega[1] = 0.0; +} + +/* Free pointer */ +void +libxc_free(void *ptr) +{ +#ifdef HAVE_CUDA + cudaFree(ptr); +#else + free(ptr); +#endif +} + + +/* these functional handle the internal counters + used to move along the input and output arrays. + We have to pay particular attention to the spin, + of course. */ +void +internal_counters_set_lda(int nspin, xc_dimensions *dim) +{ + dim->rho = dim->vrho = nspin; + dim->zk = 1; + if(nspin == XC_UNPOLARIZED){ + dim->v2rho2 = dim->v3rho3 = dim->v4rho4 = 1; + }else{ + dim->v2rho2 = 3; + dim->v3rho3 = 4; + dim->v4rho4 = 5; + } +} + +void +internal_counters_set_gga(int nspin, xc_dimensions *dim) +{ + internal_counters_set_lda(nspin, dim); + + if(nspin == XC_UNPOLARIZED){ + dim->sigma = dim->vsigma = 1; + dim->v2rhosigma = dim->v2sigma2 = 1; + dim->v3rho2sigma = dim->v3rhosigma2 = dim->v3sigma3 = 1; + dim->v4rho3sigma = dim->v4rho2sigma2 = dim->v4rhosigma3 = dim->v4sigma4 = 1; + + }else{ + dim->sigma = 3; + + dim->vsigma = 3; + + dim->v2rhosigma = 2*3; + dim->v2sigma2 = 6; + + dim->v3rho2sigma = 3*3; + dim->v3rhosigma2 = 2*6; + dim->v3sigma3 = 10; + + dim->v4rho3sigma = 4*3; + dim->v4rho2sigma2 = 3*6; + dim->v4rhosigma3 = 2*10; + dim->v4sigma4 = 15; + } +} + +void +internal_counters_set_mgga(int nspin, xc_dimensions *dim) +{ + internal_counters_set_gga(nspin, dim); + + dim->lapl = dim->vlapl = nspin; + dim->tau = dim->vtau = nspin; + if(nspin == XC_UNPOLARIZED){ + dim->v2lapl2 = dim->v2tau2 = 1; + dim->v2rholapl = dim->v2rhotau = dim->v2lapltau = 1; + dim->v2sigmalapl = dim->v2sigmatau = 1; + + dim->v3lapl3 = dim->v3tau3 = dim->v3rho2lapl = dim->v3rho2tau = dim->v3rholapl2 = 1; + dim->v3rhotau2 = dim->v3lapl2tau = dim->v3lapltau2 = dim->v3rholapltau = 1; + dim->v3sigmalapl2 = dim->v3sigmatau2 = dim->v3sigma2lapl = dim->v3sigma2tau = 1; + dim->v3rhosigmalapl = dim->v3rhosigmatau = dim->v3sigmalapltau = 1; + + dim->v4rho4 = dim->v4rho3sigma = dim->v4rho3lapl = dim->v4rho3tau = dim->v4rho2sigma2 = 1; + dim->v4rho2sigmalapl = dim->v4rho2sigmatau = dim->v4rho2lapl2 = dim->v4rho2lapltau = 1; + dim->v4rho2tau2 = dim->v4rhosigma3 = dim->v4rhosigma2lapl = dim->v4rhosigma2tau = 1; + dim->v4rhosigmalapl2 = dim->v4rhosigmalapltau = dim->v4rhosigmatau2 = 1; + dim->v4rholapl3 = dim->v4rholapl2tau = dim->v4rholapltau2 = dim->v4rhotau3 = 1; + dim->v4sigma4 = dim->v4sigma3lapl = dim->v4sigma3tau = dim->v4sigma2lapl2 = 1; + dim->v4sigma2lapltau = dim->v4sigma2tau2 = dim->v4sigmalapl3 = dim->v4sigmalapl2tau = 1; + dim->v4sigmalapltau2 = dim->v4sigmatau3 = dim->v4lapl4 = dim->v4lapl3tau = 1; + dim->v4lapl2tau2 = dim->v4lapltau3 = dim->v4tau4 =1; + }else{ + /* in total: 30 */ + dim->v2rholapl = 2*2; + dim->v2rhotau = 2*2; + dim->v2sigmalapl = 3*2; + dim->v2sigmatau = 3*2; + dim->v2lapl2 = 3; + dim->v2lapltau = 2*2; + dim->v2tau2 = 3; + + /* in total: 130 */ + dim->v3rho2lapl = 3*2; + dim->v3rho2tau = 3*2; + dim->v3rhosigmalapl = 2*3*2; + dim->v3rhosigmatau = 2*3*2; + dim->v3rholapl2 = 2*3; + dim->v3rholapltau = 2*2*2; + dim->v3rhotau2 = 2*3; + dim->v3sigma2lapl = 6*2; + dim->v3sigma2tau = 6*2; + dim->v3sigmalapl2 = 3*3; + dim->v3sigmalapltau = 3*2*2; + dim->v3sigmatau2 = 3*3; + dim->v3lapl3 = 4; + dim->v3lapl2tau = 3*2; + dim->v3lapltau2 = 2*3; + dim->v3tau3 = 4; + + /* in total: 477 */ + dim->v4rho3lapl = 4*2; + dim->v4rho3tau = 4*2; + dim->v4rho2sigmalapl = 3*3*2; + dim->v4rho2sigmatau = 3*3*2; + dim->v4rho2lapl2 = 3*3; + dim->v4rho2lapltau = 3*2*2; + dim->v4rho2tau2 = 3*3; + dim->v4rhosigma2lapl = 3*6*2; + dim->v4rhosigma2tau = 3*6*2; + dim->v4rhosigmalapl2 = 2*3*3; + dim->v4rhosigmalapltau = 2*3*2*2; + dim->v4rhosigmatau2 = 2*6*3; + dim->v4rholapl3 = 2*4; + dim->v4rholapl2tau = 2*3*2; + dim->v4rholapltau2 = 2*2*3; + dim->v4rhotau3 = 2*4; + dim->v4sigma3lapl = 10*2; + dim->v4sigma3tau = 10*3; + dim->v4sigma2lapl2 = 6*3; + dim->v4sigma2lapltau = 6*2*2; + dim->v4sigma2tau2 = 6*3; + dim->v4sigmalapl3 = 3*4; + dim->v4sigmalapl2tau = 3*3*2; + dim->v4sigmalapltau2 = 3*2*3; + dim->v4sigmatau3 = 3*4; + dim->v4lapl4 = 5; + dim->v4lapl3tau = 4*2; + dim->v4lapl2tau2 = 3*3; + dim->v4lapltau3 = 2*4; + dim->v4tau4 = 5; + } +} + +GPU_FUNCTION void +internal_counters_lda_random + (const xc_dimensions *dim, int pos, int offset, const double **rho, + double **zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )) +{ + if(*rho != NULL) *rho += pos*dim->rho + offset; + if(*zk != NULL) *zk += pos*dim->zk + offset; +#ifndef XC_DONT_COMPILE_VXC + if(*vrho != NULL) *vrho += pos*dim->vrho + offset; +#ifndef XC_DONT_COMPILE_FXC + if(*v2rho2 != NULL) *v2rho2 += pos*dim->v2rho2 + offset; +#ifndef XC_DONT_COMPILE_KXC + if(*v3rho3 != NULL) *v3rho3 += pos*dim->v3rho3 + offset; +#ifndef XC_DONT_COMPILE_LXC + if(*v4rho4 != NULL) *v4rho4 += pos*dim->v4rho4 + offset; +#endif +#endif +#endif +#endif +} + +GPU_FUNCTION void +internal_counters_lda_next + (const xc_dimensions *dim, int offset, const double **rho, + double **zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )) +{ + if(*rho != NULL) *rho += dim->rho + offset; + if(*zk != NULL) *zk += dim->zk + offset; +#ifndef XC_DONT_COMPILE_VXC + if(*vrho != NULL) *vrho += dim->vrho + offset; +#ifndef XC_DONT_COMPILE_FXC + if(*v2rho2 != NULL) *v2rho2 += dim->v2rho2 + offset; +#ifndef XC_DONT_COMPILE_KXC + if(*v3rho3 != NULL) *v3rho3 += dim->v3rho3 + offset; +#ifndef XC_DONT_COMPILE_LXC + if(*v4rho4 != NULL) *v4rho4 += dim->v4rho4 + offset; +#endif +#endif +#endif +#endif +} + +GPU_FUNCTION void +internal_counters_lda_prev + (const xc_dimensions *dim, int offset, const double **rho, + double **zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )) +{ + if(*rho != NULL) *rho -= dim->rho + offset; + if(*zk != NULL) *zk -= dim->zk + offset; +#ifndef XC_DONT_COMPILE_VXC + if(*vrho != NULL) *vrho -= dim->vrho + offset; +#ifndef XC_DONT_COMPILE_FXC + if(*v2rho2 != NULL) *v2rho2 -= dim->v2rho2 + offset; +#ifndef XC_DONT_COMPILE_KXC + if(*v3rho3 != NULL) *v3rho3 -= dim->v3rho3 + offset; +#ifndef XC_DONT_COMPILE_LXC + if(*v4rho4 != NULL) *v4rho4 -= dim->v4rho4 + offset; +#endif +#endif +#endif +#endif +} + +GPU_FUNCTION void +internal_counters_gga_random + ( + const xc_dimensions *dim, int pos, int offset, const double **rho, const double **sigma, + double **zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )) +{ + internal_counters_lda_random(dim, pos, offset, rho, zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA, )); + + if(*sigma != NULL) *sigma += pos*dim->sigma + offset; +#ifndef XC_DONT_COMPILE_VXC + if(*vrho != NULL) *vsigma += pos*dim->vsigma + offset; +#ifndef XC_DONT_COMPILE_FXC + if(*v2rho2 != NULL) { + *v2rhosigma += pos*dim->v2rhosigma + offset; + *v2sigma2 += pos*dim->v2sigma2 + offset; + } +#ifndef XC_DONT_COMPILE_KXC + if(*v3rho3 != NULL) { + *v3rho2sigma += pos*dim->v3rho2sigma + offset; + *v3rhosigma2 += pos*dim->v3rhosigma2 + offset; + *v3sigma3 += pos*dim->v3sigma3 + offset; + } +#ifndef XC_DONT_COMPILE_LXC + if(*v4rho4 != NULL) { + *v4rho3sigma += pos*dim->v4rho3sigma + offset; + *v4rho2sigma2 += pos*dim->v4rho2sigma2 + offset; + *v4rhosigma3 += pos*dim->v4rhosigma3 + offset; + *v4sigma4 += pos*dim->v4sigma4 + offset; + } +#endif +#endif +#endif +#endif +} + +GPU_FUNCTION void +internal_counters_gga_next + ( + const xc_dimensions *dim, int offset, const double **rho, const double **sigma, + double **zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )) +{ + internal_counters_lda_next(dim, offset, rho, zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA, )); + + if(*sigma != NULL) *sigma += dim->sigma + offset; +#ifndef XC_DONT_COMPILE_VXC + if(*vrho != NULL) *vsigma += dim->vsigma + offset; +#ifndef XC_DONT_COMPILE_FXC + if(*v2rho2 != NULL) { + *v2rhosigma += dim->v2rhosigma + offset; + *v2sigma2 += dim->v2sigma2 + offset; + } +#ifndef XC_DONT_COMPILE_KXC + if(*v3rho3 != NULL) { + *v3rho2sigma += dim->v3rho2sigma + offset; + *v3rhosigma2 += dim->v3rhosigma2 + offset; + *v3sigma3 += dim->v3sigma3 + offset; + } +#ifndef XC_DONT_COMPILE_LXC + if(*v4rho4 != NULL) { + *v4rho3sigma += dim->v4rho3sigma + offset; + *v4rho2sigma2 += dim->v4rho2sigma2 + offset; + *v4rhosigma3 += dim->v4rhosigma3 + offset; + *v4sigma4 += dim->v4sigma4 + offset; + } +#endif +#endif +#endif +#endif +} + +GPU_FUNCTION void +internal_counters_gga_prev +(const xc_dimensions *dim, int offset, const double **rho, const double **sigma, + double **zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )) +{ + internal_counters_lda_prev(dim, offset, rho, zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA, )); + + if(*sigma != NULL) *sigma -= dim->sigma + offset; +#ifndef XC_DONT_COMPILE_VXC + if(*vrho != NULL) *vsigma -= dim->vsigma + offset; +#ifndef XC_DONT_COMPILE_FXC + if(*v2rho2 != NULL) { + *v2rhosigma -= dim->v2rhosigma + offset; + *v2sigma2 -= dim->v2sigma2 + offset; + } +#ifndef XC_DONT_COMPILE_KXC + if(*v3rho3 != NULL) { + *v3rho2sigma -= dim->v3rho2sigma + offset; + *v3rhosigma2 -= dim->v3rhosigma2 + offset; + *v3sigma3 -= dim->v3sigma3 + offset; + } +#ifndef XC_DONT_COMPILE_LXC + if(*v4rho4 != NULL) { + *v4rho3sigma -= dim->v4rho3sigma + offset; + *v4rho2sigma2 -= dim->v4rho2sigma2 + offset; + *v4rhosigma3 -= dim->v4rhosigma3 + offset; + *v4sigma4 -= dim->v4sigma4 + offset; + } +#endif +#endif +#endif +#endif +} + +GPU_FUNCTION void +internal_counters_mgga_random + (const xc_dimensions *dim, int pos, int offset, + const double **rho, const double **sigma, const double **lapl, const double **tau, + double **zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )) +{ + internal_counters_gga_random(dim, pos, offset, rho, sigma, zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA, )); + + if(*lapl != NULL) *lapl += pos*dim->lapl + offset; + if(*tau != NULL) *tau += pos*dim->tau + offset; + +#ifndef XC_DONT_COMPILE_VXC + if(*vrho != NULL) { + if (*vlapl != NULL) + *vlapl += pos*dim->vlapl + offset; + if (*vtau != NULL) + *vtau += pos*dim->vtau + offset; + } + +#ifndef XC_DONT_COMPILE_FXC + if(*v2rho2 != NULL) { + if (*v2lapl2 != NULL){ + *v2rholapl += pos*dim->v2rholapl + offset; + *v2sigmalapl += pos*dim->v2sigmalapl + offset; + *v2lapl2 += pos*dim->v2lapl2 + offset; + } + if(*v2tau2 != NULL){ + *v2rhotau += pos*dim->v2rhotau + offset; + *v2sigmatau += pos*dim->v2sigmatau + offset; + *v2tau2 += pos*dim->v2tau2 + offset; + } + if(*v2lapltau != NULL){ + *v2lapltau += pos*dim->v2lapltau + offset; + } + } + +#ifndef XC_DONT_COMPILE_KXC + if(*v3rho3 != NULL) { + if (*v3lapl3 != NULL){ + *v3rho2lapl += pos*dim->v3rho2lapl + offset; + *v3rhosigmalapl += pos*dim->v3rhosigmalapl + offset; + *v3rholapl2 += pos*dim->v3rholapl2 + offset; + *v3sigma2lapl += pos*dim->v3sigma2lapl + offset; + *v3sigmalapl2 += pos*dim->v3sigmalapl2 + offset; + *v3lapl3 += pos*dim->v3lapl3 + offset; + } + if(*v3tau3 != NULL){ + *v3rho2tau += pos*dim->v3rho2tau + offset; + *v3rhosigmatau += pos*dim->v3rhosigmatau + offset; + *v3rhotau2 += pos*dim->v3rhotau2 + offset; + *v3sigma2tau += pos*dim->v3sigma2tau + offset; + *v3sigmatau2 += pos*dim->v3sigmatau2 + offset; + *v3tau3 += pos*dim->v3tau3 + offset; + } + if(*v3rholapltau != NULL){ + *v3rholapltau += pos*dim->v3rholapltau + offset; + *v3sigmalapltau += pos*dim->v3sigmalapltau + offset; + *v3lapl2tau += pos*dim->v3lapl2tau + offset; + *v3lapltau2 += pos*dim->v3lapltau2 + offset; + } + } +#ifndef XC_DONT_COMPILE_LXC + if(*v4rho4 != NULL) { + if (*v4lapl4 != NULL){ + *v4rho3lapl += pos*dim->v4rho3lapl + offset; + *v4rho2sigmalapl += pos*dim->v4rho2sigmalapl + offset; + *v4rho2lapl2 += pos*dim->v4rho2lapl2 + offset; + *v4rhosigma2lapl += pos*dim->v4rhosigma2lapl + offset; + *v4rhosigmalapl2 += pos*dim->v4rhosigmalapl2 + offset; + *v4rholapl3 += pos*dim->v4rholapl3 + offset; + *v4sigma3lapl += pos*dim->v4sigma3lapl + offset; + *v4sigma2lapl2 += pos*dim->v4sigma2lapl2 + offset; + *v4sigmalapl3 += pos*dim->v4sigmalapl3 + offset; + *v4lapl4 += pos*dim->v4lapl4 + offset; + } + if(*v4tau4 != NULL){ + *v4rho3tau += pos*dim->v4rho3tau + offset; + *v4rho2sigmatau += pos*dim->v4rho2sigmatau + offset; + *v4rho2tau2 += pos*dim->v4rho2tau2 + offset; + *v4rhosigma2tau += pos*dim->v4rhosigma2tau + offset; + *v4rhosigmatau2 += pos*dim->v4rhosigmatau2 + offset; + *v4rhotau3 += pos*dim->v4rhotau3 + offset; + *v4sigma3tau += pos*dim->v4sigma3tau + offset; + *v4sigma2tau2 += pos*dim->v4sigma2tau2 + offset; + *v4sigmatau3 += pos*dim->v4sigmatau3 + offset; + *v4tau4 += pos*dim->v4tau4 + offset; + } + if(*v4rho2lapltau != NULL){ + *v4rho2lapltau += pos*dim->v4rho2lapltau + offset; + *v4rhosigmalapltau += pos*dim->v4rhosigmalapltau + offset; + *v4rholapl2tau += pos*dim->v4rholapl2tau + offset; + *v4rholapltau2 += pos*dim->v4rholapltau2 + offset; + *v4sigma2lapltau += pos*dim->v4sigma2lapltau + offset; + *v4sigmalapl2tau += pos*dim->v4sigmalapl2tau + offset; + *v4sigmalapltau2 += pos*dim->v4sigmalapltau2 + offset; + *v4lapl3tau += pos*dim->v4lapl3tau + offset; + *v4lapl2tau2 += pos*dim->v4lapl2tau2 + offset; + *v4lapltau3 += pos*dim->v4lapltau3 + offset; + } + } +#endif +#endif +#endif +#endif +} + +GPU_FUNCTION void +internal_counters_mgga_next + (const xc_dimensions *dim, int offset, + const double **rho, const double **sigma, const double **lapl, const double **tau, + double **zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )) +{ + internal_counters_gga_next(dim, offset, rho, sigma, zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA, )); + + if(*lapl != NULL) *lapl += dim->lapl + offset; + if(*tau != NULL) *tau += dim->tau + offset; + +#ifndef XC_DONT_COMPILE_VXC + if(*vrho != NULL) { + if (*vlapl != NULL) + *vlapl += dim->vlapl + offset; + if (*vtau != NULL) + *vtau += dim->vtau + offset; + } + +#ifndef XC_DONT_COMPILE_FXC + if(*v2rho2 != NULL) { + if (*v2lapl2 != NULL){ + *v2rholapl += dim->v2rholapl + offset; + *v2sigmalapl += dim->v2sigmalapl + offset; + *v2lapl2 += dim->v2lapl2 + offset; + } + if (*v2tau2 != NULL){ + *v2rhotau += dim->v2rhotau + offset; + *v2sigmatau += dim->v2sigmatau + offset; + *v2tau2 += dim->v2tau2 + offset; + } + if (*v2lapltau != NULL){ + *v2lapltau += dim->v2lapltau + offset; + } + } + +#ifndef XC_DONT_COMPILE_KXC + if(*v3rho3 != NULL) { + if (*v3lapl3 != NULL){ + *v3rho2lapl += dim->v3rho2lapl + offset; + *v3rhosigmalapl += dim->v3rhosigmalapl + offset; + *v3rholapl2 += dim->v3rholapl2 + offset; + *v3sigma2lapl += dim->v3sigma2lapl + offset; + *v3sigmalapl2 += dim->v3sigmalapl2 + offset; + *v3lapl3 += dim->v3lapl3 + offset; + } + if (*v3tau3 != NULL){ + *v3rho2tau += dim->v3rho2tau + offset; + *v3rhosigmatau += dim->v3rhosigmatau + offset; + *v3rhotau2 += dim->v3rhotau2 + offset; + *v3sigma2tau += dim->v3sigma2tau + offset; + *v3sigmatau2 += dim->v3sigmatau2 + offset; + *v3tau3 += dim->v3tau3 + offset; + } + if(*v3rholapltau != NULL){ + *v3rholapltau += dim->v3rholapltau + offset; + *v3sigmalapltau += dim->v3sigmalapltau + offset; + *v3lapl2tau += dim->v3lapl2tau + offset; + *v3lapltau2 += dim->v3lapltau2 + offset; + } + } +#ifndef XC_DONT_COMPILE_LXC + if(*v4rho4 != NULL) { + if (*v4lapl4 != NULL){ + *v4rho3lapl += dim->v4rho3lapl + offset; + *v4rho2sigmalapl += dim->v4rho2sigmalapl + offset; + *v4rho2lapl2 += dim->v4rho2lapl2 + offset; + *v4rhosigma2lapl += dim->v4rhosigma2lapl + offset; + *v4rhosigmalapl2 += dim->v4rhosigmalapl2 + offset; + *v4rholapl3 += dim->v4rholapl3 + offset; + *v4sigma3lapl += dim->v4sigma3lapl + offset; + *v4sigma2lapl2 += dim->v4sigma2lapl2 + offset; + *v4sigmalapl3 += dim->v4sigmalapl3 + offset; + *v4lapl4 += dim->v4lapl4 + offset; + } + if (*v4tau4 != NULL){ + *v4rho3tau += dim->v4rho3tau + offset; + *v4rho2sigmatau += dim->v4rho2sigmatau + offset; + *v4rho2tau2 += dim->v4rho2tau2 + offset; + *v4rhosigma2tau += dim->v4rhosigma2tau + offset; + *v4rhosigmatau2 += dim->v4rhosigmatau2 + offset; + *v4rhotau3 += dim->v4rhotau3 + offset; + *v4sigma3tau += dim->v4sigma3tau + offset; + *v4sigma2tau2 += dim->v4sigma2tau2 + offset; + *v4sigmatau3 += dim->v4sigmatau3 + offset; + *v4tau4 += dim->v4tau4 + offset; + } + if(*v4rho2lapltau != NULL){ + *v4rho2lapltau += dim->v4rho2lapltau + offset; + *v4rhosigmalapltau += dim->v4rhosigmalapltau + offset; + *v4rholapl2tau += dim->v4rholapl2tau + offset; + *v4rholapltau2 += dim->v4rholapltau2 + offset; + *v4sigma2lapltau += dim->v4sigma2lapltau + offset; + *v4sigmalapl2tau += dim->v4sigmalapl2tau + offset; + *v4sigmalapltau2 += dim->v4sigmalapltau2 + offset; + *v4lapl3tau += dim->v4lapl3tau + offset; + *v4lapl2tau2 += dim->v4lapl2tau2 + offset; + *v4lapltau3 += dim->v4lapltau3 + offset; + } + } +#endif +#endif +#endif +#endif +} + +GPU_FUNCTION void +internal_counters_mgga_prev + (const xc_dimensions *dim, int offset, + const double **rho, const double **sigma, const double **lapl, const double **tau, + double **zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )) +{ + internal_counters_gga_prev(dim, offset, rho, sigma, zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA, )); + + if(*lapl != NULL) *lapl -= dim->lapl + offset; + if(*tau != NULL) *tau -= dim->tau + offset; + +#ifndef XC_DONT_COMPILE_VXC + if(*vrho != NULL) { + if(*vlapl != NULL) + *vlapl -= dim->vlapl + offset; + if(*vtau != NULL) + *vtau -= dim->vtau + offset; + } + +#ifndef XC_DONT_COMPILE_FXC + if(*v2rho2 != NULL) { + if(*v2lapl2 != NULL){ + *v2rholapl -= dim->v2rholapl + offset; + *v2sigmalapl -= dim->v2sigmalapl + offset; + *v2lapl2 -= dim->v2lapl2 + offset; + } + if(*v2tau2 != NULL){ + *v2rhotau -= dim->v2rhotau + offset; + *v2sigmatau -= dim->v2sigmatau + offset; + *v2tau2 -= dim->v2tau2 + offset; + } + if(*v2lapltau){ + *v2lapltau -= dim->v2lapltau + offset; + } + } + +#ifndef XC_DONT_COMPILE_KXC + if(*v3rho3 != NULL) { + if(*v3lapl3 != NULL){ + *v3rho2lapl -= dim->v3rho2lapl + offset; + *v3rhosigmalapl -= dim->v3rhosigmalapl + offset; + *v3rholapl2 -= dim->v3rholapl2 + offset; + *v3sigma2lapl -= dim->v3sigma2lapl + offset; + *v3sigmalapl2 -= dim->v3sigmalapl2 + offset; + *v3lapl3 -= dim->v3lapl3 + offset; + } + if(*v3tau3 != NULL){ + *v3rho2tau -= dim->v3rho2tau + offset; + *v3rhosigmatau -= dim->v3rhosigmatau + offset; + *v3rhotau2 -= dim->v3rhotau2 + offset; + *v3sigma2tau -= dim->v3sigma2tau + offset; + *v3sigmatau2 -= dim->v3sigmatau2 + offset; + *v3tau3 -= dim->v3tau3 + offset; + } + if(*v3rholapltau){ + *v3rholapltau -= dim->v3rholapltau + offset; + *v3sigmalapltau -= dim->v3sigmalapltau + offset; + *v3lapl2tau -= dim->v3lapl2tau + offset; + *v3lapltau2 -= dim->v3lapltau2 + offset; + } + } +#ifndef XC_DONT_COMPILE_LXC + if(*v4rho4 != NULL) { + if (*v4lapl4 != NULL){ + *v4rho3lapl -= dim->v4rho3lapl + offset; + *v4rho2sigmalapl -= dim->v4rho2sigmalapl + offset; + *v4rho2lapl2 -= dim->v4rho2lapl2 + offset; + *v4rhosigma2lapl -= dim->v4rhosigma2lapl + offset; + *v4rhosigmalapl2 -= dim->v4rhosigmalapl2 + offset; + *v4rholapl3 -= dim->v4rholapl3 + offset; + *v4sigma3lapl -= dim->v4sigma3lapl + offset; + *v4sigma2lapl2 -= dim->v4sigma2lapl2 + offset; + *v4sigmalapl3 -= dim->v4sigmalapl3 + offset; + *v4lapl4 -= dim->v4lapl4 + offset; + } + if(*v4tau4 != NULL){ + *v4rho3tau -= dim->v4rho3tau + offset; + *v4rho2sigmatau -= dim->v4rho2sigmatau + offset; + *v4rho2tau2 -= dim->v4rho2tau2 + offset; + *v4rhosigma2tau -= dim->v4rhosigma2tau + offset; + *v4rhosigmatau2 -= dim->v4rhosigmatau2 + offset; + *v4rhotau3 -= dim->v4rhotau3 + offset; + *v4sigma3tau -= dim->v4sigma3tau + offset; + *v4sigma2tau2 -= dim->v4sigma2tau2 + offset; + *v4sigmatau3 -= dim->v4sigmatau3 + offset; + *v4tau4 -= dim->v4tau4 + offset; + } + if(*v4rho2lapltau != NULL){ + *v4rho2lapltau -= dim->v4rho2lapltau + offset; + *v4rhosigmalapltau -= dim->v4rhosigmalapltau + offset; + *v4rholapl2tau -= dim->v4rholapl2tau + offset; + *v4rholapltau2 -= dim->v4rholapltau2 + offset; + *v4sigma2lapltau -= dim->v4sigma2lapltau + offset; + *v4sigmalapl2tau -= dim->v4sigmalapl2tau + offset; + *v4sigmalapltau2 -= dim->v4sigmalapltau2 + offset; + *v4lapl3tau -= dim->v4lapl3tau + offset; + *v4lapl2tau2 -= dim->v4lapl2tau2 + offset; + *v4lapltau3 -= dim->v4lapltau3 + offset; + } + } +#endif +#endif +#endif +#endif +} + +/** Computes nderiv derivatives of B-spline Nip(u) + + The algorithm follows the textbook presentation in the NURBS + book, 2nd edition, by Les Piegl and Wayne Tiller. + + Input variables: + - i: function index + - p: spline order + - u: argument + - nderiv: number of derivatives to calculate (zero for just the function itself) + - U: knots + Output variables: + - ders: array [Nip(u), Nip'(u), Nip''(u), ..., Nip^(nderiv)(u)] +*/ +GPU_FUNCTION void +xc_bspline(int i, int p, double u, int nderiv, const double *U, double *ders) { + + /* Initialize output array */ + libxc_memset(ders, 0, (nderiv+1)*sizeof(double)); + + /* Check locality of support */ + if(u < U[i] || u >= U[i+p+1]) { + return; + } + + /* Arrays need static sizes for stack allocation */ +#define PMAX 8 + assert(p<PMAX); + + /* Array of normalized B splines, use dense storage for simpler code */ + double N[PMAX][PMAX]; + libxc_memset(N, 0, PMAX*PMAX*sizeof(double)); + + /* Initialize zeroth-degree functions: piecewise constants */ + for(int j=0; j<=p; j++) { + N[0][j] = (u >= U[i+j] && u < U[i+j+1]) ? 1.0 : 0.0; + } + + /* Fill out table of B splines */ + for(int k=1; k<=p; k++) { + double saved = (N[k-1][0] == 0.0) ? 0.0 : ((u-U[i])*N[k-1][0])/(U[i+k]-U[i]); + + for(int j=0; j<=p-k; j++) { + double Ul = U[i+j+1]; + double Ur = U[i+j+k+1]; + if(N[k-1][j+1] == 0.0) { + N[k][j] = saved; + saved = 0.0; + } else { + double temp = N[k-1][j+1] / (Ur-Ul); + N[k][j] = saved + (Ur-u)*temp; + saved = (u-Ul)*temp; + } + } + } + + /* Function value */ + ders[0] = N[p][0]; + if(nderiv==0) + return; + + /* Helper memory */ + assert(nderiv<=4); + double ND[5]; /* dimension nderiv+1 */ + int maxk = (nderiv < p) ? nderiv : p; + + /* Compute derivatives */ + for(int k=1; k<=maxk; k++) { + /* Load appropriate column */ + libxc_memset(ND, 0, (nderiv+1)*sizeof(double)); + for(int j=0; j<=k; j++) + ND[j] = N[p-k][j]; + + /* Compute table */ + for(int jj=1; jj<=k; jj++) { + double saved = (ND[0] == 0.0) ? 0.0 : ND[0]/(U[i+p-k+jj]-U[i]); + + for(int j=0; j<=k-jj; j++) { + double Ul = U[i+j+1]; + /* the -k term is missing in the book */ + double Ur = U[i+j+p-k+jj+1]; + if(ND[j+1] == 0.0) { + ND[j] = (p-k+jj)*saved; + saved = 0.0; + } else { + double temp = ND[j+1]/(Ur-Ul); + ND[j] = (p-k+jj)*(saved-temp); + saved = temp; + } + } + } + /* k:th derivative is */ + ders[k] = ND[0]; + } +} diff --git a/ref/common/util.h b/ref/common/util.h new file mode 100644 index 0000000000000000000000000000000000000000..97cebfc8dda008f6a37a5d3c35096f66be6a78bf --- /dev/null +++ b/ref/common/util.h @@ -0,0 +1,352 @@ +/* + Copyright (C) 2006-2007 M.A.L. Marques + Copyright (C) 2019 X. Andrade + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#ifndef _LDA_H +#define _LDA_H + +/* These are generic header files that are needed basically everywhere */ +#include <math.h> +#include <float.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#ifdef HAVE_CUDA +#include <cuda.h> +#endif + +#include "xc.h" + +#ifdef HAVE_CUDA +#define GPU_FUNCTION __host__ __device__ +#define CUDA_BLOCK_SIZE 256 +#else +#define GPU_FUNCTION +#endif + +/* This takes care of disabling specific derivatives from the info structures */ +#define XC_FLAGS_I_HAVE_EXC XC_FLAGS_HAVE_EXC + +#ifdef XC_DONT_COMPILE_VXC +# define XC_FLAGS_I_HAVE_VXC 0 +#else +# define XC_FLAGS_I_HAVE_VXC XC_FLAGS_HAVE_VXC +#endif + +#ifdef XC_DONT_COMPILE_FXC +# define XC_FLAGS_I_HAVE_FXC 0 +#else +# define XC_FLAGS_I_HAVE_FXC XC_FLAGS_HAVE_FXC +#endif + +#ifdef XC_DONT_COMPILE_KXC +# define XC_FLAGS_I_HAVE_KXC 0 +#else +# define XC_FLAGS_I_HAVE_KXC XC_FLAGS_HAVE_KXC +#endif + +#ifdef XC_DONT_COMPILE_LXC +# define XC_FLAGS_I_HAVE_LXC 0 +#else +# define XC_FLAGS_I_HAVE_LXC XC_FLAGS_HAVE_LXC +#endif + +#define XC_FLAGS_I_HAVE_ALL (XC_FLAGS_HAVE_EXC | XC_FLAGS_I_HAVE_VXC | \ + XC_FLAGS_I_HAVE_FXC | XC_FLAGS_I_HAVE_KXC | \ + XC_FLAGS_I_HAVE_LXC) + +/* Useful mathematical expressions */ +#ifndef M_E +# define M_E 2.7182818284590452354 /* e */ +#endif +#ifndef M_PI +# define M_PI 3.14159265358979323846 /* pi */ +#endif +#ifndef M_SQRT2 +# define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#endif + +#define POW_2(x) ((x)*(x)) +#define POW_3(x) ((x)*(x)*(x)) + +#define POW_1_2(x) sqrt(x) +#define POW_1_4(x) sqrt(sqrt(x)) +#define POW_3_2(x) ((x)*sqrt(x)) + +#ifdef HAVE_CBRT +#define CBRT(x) cbrt(x) +#define POW_1_3(x) cbrt(x) +#define POW_2_3(x) (cbrt(x)*cbrt(x)) +#define POW_4_3(x) ((x)*cbrt(x)) +#define POW_5_3(x) ((x)*cbrt(x)*cbrt(x)) +#define POW_7_3(x) ((x)*(x)*cbrt(x)) +#else +#define CBRT(x) pow((x), 1.0/3.0) +#define POW_1_3(x) pow((x), 1.0/3.0) +#define POW_2_3(x) pow((x), 2.0/3.0) +#define POW_4_3(x) pow((x), 4.0/3.0) +#define POW_5_3(x) pow((x), 5.0/3.0) +#define POW_7_3(x) pow((x), 7.0/3.0) +#endif + +/* this is the piecewise function used in maple */ +#define my_piecewise3(c, x1, x2) ((c) ? (x1) : (x2)) +#define my_piecewise5(c1, x1, c2, x2, x3) ((c1) ? (x1) : ((c2) ? (x2) : (x3))) + +/* Computes nderiv derivatives of B-spline Nip(u) */ +GPU_FUNCTION void xc_bspline(int i, int p, double u, int nderiv, const double *U, double *ders); + +#define M_SQRTPI 1.772453850905516027298167483341145182798L +#define M_CBRTPI 1.464591887561523263020142527263790391739L +#define M_SQRT3 1.732050807568877293527446341505872366943L +#define M_CBRT2 1.259921049894873164767210607278228350570L +#define M_CBRT3 1.442249570307408382321638310780109588392L +#define M_CBRT4 1.587401051968199474751705639272308260391L +#define M_CBRT5 1.709975946676696989353108872543860109868L +#define M_CBRT6 1.817120592832139658891211756327260502428L +#define M_CBRT7 1.912931182772389101199116839548760282862L +#define M_CBRT9 2.080083823051904114530056824357885386338L + +/* Very useful macros */ +#ifndef m_min +#define m_min(x,y) (((x)<(y)) ? (x) : (y)) +#endif +#ifndef m_max +#define m_max(x,y) (((x)<(y)) ? (y) : (x)) +#endif + +/* some useful constants */ +#define LOG_DBL_MIN (log(DBL_MIN)) +#define LOG_DBL_MAX (log(DBL_MAX)) +#define SQRT_DBL_EPSILON (sqrt(DBL_EPSILON)) + +/* special functions */ +#define Heaviside(x) (((x) >= 0) ? 1.0 : 0.0) +GPU_FUNCTION double LambertW(double z); +GPU_FUNCTION double xc_dilogarithm(const double x); +#define xc_E1_scaled(x) xc_expint_e1_impl(x, 1) + +/* we define this function here, so it can be properly inlined by all compilers */ +GPU_FUNCTION +static inline double +xc_cheb_eval(const double x, const double *cs, const int N) +{ + int i; + double twox, b0, b1, b2; + + b2 = b1 = b0 = 0.0; + + twox = 2.0*x; + for(i=N-1; i>=0; i--){ + b2 = b1; + b1 = b0; + b0 = twox*b1 - b2 + cs[i]; + } + + return 0.5*(b0 - b2); +} + +GPU_FUNCTION double xc_bessel_I0_scaled(const double x); +GPU_FUNCTION double xc_bessel_I0(const double x); +GPU_FUNCTION double xc_bessel_I1_scaled(const double x); +GPU_FUNCTION double xc_bessel_I1(const double x); +GPU_FUNCTION double xc_bessel_K0_scaled(const double x); +GPU_FUNCTION double xc_bessel_K0(const double x); +GPU_FUNCTION double xc_bessel_K1_scaled(const double x); +GPU_FUNCTION double xc_bessel_K1(const double x); + +GPU_FUNCTION double xc_expint_e1_impl(double x, const int scale); +GPU_FUNCTION static inline double expint_e1(const double x) { return xc_expint_e1_impl( x, 0); } +GPU_FUNCTION static inline double expint_e1_scaled(const double x) { return xc_expint_e1_impl( x, 1); } +GPU_FUNCTION static inline double expint_Ei(const double x) { return -xc_expint_e1_impl(-x, 0); } +#define Ei(x) expint_Ei(x) +GPU_FUNCTION static inline double expint_Ei_scaled(const double x) { return -xc_expint_e1_impl(-x, 1); } + +GPU_FUNCTION double xc_erfcx(double x); + +/* integration */ +typedef void integr_fn(double *x, int n, void *ex); + +GPU_FUNCTION double xc_integrate(integr_fn func, void *ex, double a, double b); + +GPU_FUNCTION +void xc_rdqagse(integr_fn f, void *ex, double *a, double *b, + double *epsabs, double *epsrel, int *limit, double *result, + double *abserr, int *neval, int *ier, double *alist__, + double *blist, double *rlist, double *elist, int *iord, int *last); + +/* root finding */ +typedef double xc_brent_f(double, void *); + +GPU_FUNCTION +double xc_math_brent(xc_brent_f f, double lower_bound, double upper_bound, + double TOL, double MAX_ITER, void *f_params); + + +typedef struct xc_functional_key_t { + char name[256]; + int number; +} xc_functional_key_t; + + +#define M_C 137.0359996287515 /* speed of light */ + +#define RS_FACTOR 0.6203504908994000166680068120477781673508 /* (3/(4*Pi))^1/3 */ +#define X_FACTOR_C 0.9305257363491000250020102180716672510262 /* 3/8*cur(3/pi)*4^(2/3) */ +#define X_FACTOR_2D_C 1.504505556127350098528211870828726895584 /* 8/(3*sqrt(pi)) */ +#define K_FACTOR_C 4.557799872345597137288163759599305358515 /* 3/10*(6*pi^2)^(2/3) */ +#define MU_GE 0.1234567901234567901234567901234567901235 /* 10/81 */ +#define MU_PBE 0.2195149727645171 /* mu = beta*pi^2/3, beta = 0.06672455060314922 */ +#define X2S 0.1282782438530421943003109254455883701296 /* 1/(2*(6*pi^2)^(1/3)) */ +#define X2S_2D 0.1410473958869390717370198628901931464610 /* 1/(2*(4*pi)^(1/2)) */ +#define FZETAFACTOR 0.5198420997897463295344212145564567011405 /* 2^(4/3) - 2 */ + +#define RS(x) (RS_FACTOR/CBRT(x)) +#define FZETA(x) ((pow(1.0 + (x), 4.0/3.0) + pow(1.0 - (x), 4.0/3.0) - 2.0)/FZETAFACTOR) +#define DFZETA(x) ((CBRT(1.0 + (x)) - CBRT(1.0 - (x)))*(4.0/3.0)/FZETAFACTOR) +#define D2FZETA(x) ((4.0/9.0)/FZETAFACTOR)* \ + (fabs(x)==1.0 ? (FLT_MAX) : (pow(1.0 + (x), -2.0/3.0) + pow(1.0 - (x), -2.0/3.0))) +#define D3FZETA(x) (-(8.0/27.0)/FZETAFACTOR)* \ + (fabs(x)==1.0 ? (FLT_MAX) : (pow(1.0 + (x), -5.0/3.0) - pow(1.0 - (x), -5.0/3.0))) + + +/* The following inlines confuse the xlc compiler */ +GPU_FUNCTION void xc_rho2dzeta(int nspin, const double *rho, double *d, double *zeta); + +/* Functions to handle the internal counters */ + +void internal_counters_set_lda (int nspin, xc_dimensions *dim); +GPU_FUNCTION void internal_counters_lda_random +(const xc_dimensions *dim, int ip, int offset, + const double **rho, + double **zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA double **, XC_NOARG)); +GPU_FUNCTION void internal_counters_lda_next +(const xc_dimensions *dim, int offset, + const double **rho, + double **zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA double **, XC_NOARG)); +GPU_FUNCTION void internal_counters_lda_prev +(const xc_dimensions *dim, int offset, + const double **rho, + double **zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA double **, XC_NOARG)); + +void internal_counters_set_gga (int nspin, xc_dimensions *dim); +GPU_FUNCTION void internal_counters_gga_random +(const xc_dimensions *dim, int pos, int offset, + const double **rho, const double **sigma, + double **zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )); +GPU_FUNCTION void internal_counters_gga_next +(const xc_dimensions *dim, int offset, + const double **rho, const double **sigma, + double **zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )); +GPU_FUNCTION void internal_counters_gga_prev +(const xc_dimensions *dim, int offset, + const double **rho, const double **sigma, + double **zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )); + +void internal_counters_set_mgga(int nspin, xc_dimensions *dim); +GPU_FUNCTION void internal_counters_mgga_random +(const xc_dimensions *dim, const int pos, int offset, + const double **rho, const double **sigma, const double **lapl, const double **tau, + double **zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )); +GPU_FUNCTION void internal_counters_mgga_next +(const xc_dimensions *dim, int offset, + const double **rho, const double **sigma, const double **lapl, const double **tau, + double **zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )); +GPU_FUNCTION void internal_counters_mgga_prev +(const xc_dimensions *dim, int offset, + const double **rho, const double **sigma, const double **lapl, const double **tau, + double **zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )); + +/* Functionals that are defined as deorbitalized */ +void xc_mgga_vars_allocate_all + (int family, size_t np, const xc_dimensions *dim, + int do_zk, int do_vrho, int do_v2rho2, int do_v3rho3, int do_v4rho4, + double **zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double **, )); +void xc_mgga_vars_free_all + (double *zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); +void xc_mgga_evaluate_functional + (const xc_func_type *func, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + double *zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); +void xc_deorbitalize_init + (xc_func_type *p, int mgga_id, int ked_id); +void xc_deorbitalize_func + (const xc_func_type *func, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + double *zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); + +/* Functionals that are defined as mixtures of others */ +void xc_mix_init(xc_func_type *p, int n_funcs, const int *funcs_id, const double *mix_coef); +void xc_mix_func + (const xc_func_type *func, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + double *zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); + +/* Hybrid functional intializers. The order of arguments is the same + as in the external parameter setters. + */ +void xc_hyb_init(xc_func_type *p, int n_terms, const int *type, const double *coeff, const double *omega); +void xc_hyb_init_hybrid(xc_func_type *p, double alpha); +void xc_hyb_init_sr (xc_func_type *p, double beta, double omega); +void xc_hyb_init_cam (xc_func_type *p, double alpha, double beta, double omega); +void xc_hyb_init_camy(xc_func_type *p, double alpha, double beta, double omega); +void xc_hyb_init_camg(xc_func_type *p, double alpha, double beta, double omega); + +/* Some useful functions */ +const char *get_kind(const xc_func_type *func); +const char *get_family(const xc_func_type *func); +double get_ext_param(const xc_func_type *func, const double *values, int index); +void set_ext_params_cpy (xc_func_type *p, const double *ext_params); +void set_ext_params_cpy_omega(xc_func_type *p, const double *ext_params); +void set_ext_params_cpy_exx(xc_func_type *p, const double *ext_params); +void set_ext_params_cpy_cam(xc_func_type *p, const double *ext_params); +void set_ext_params_cpy_camy(xc_func_type *p, const double *ext_params); +void set_ext_params_cpy_cam_sr(xc_func_type *p, const double *ext_params); +void set_ext_params_cpy_lc(xc_func_type *p, const double *ext_params); + +GPU_FUNCTION +double xc_mgga_x_br89_get_x(double Q); + +/* We need to be able to free memory allocated in the C code from the + Fortran side */ +void libxc_free(void *ptr); + +#ifndef HAVE_CUDA +#define libxc_malloc malloc +#define libxc_calloc calloc +#define libxc_memset memset +#define libxc_memcpy memcpy +#else + +template <class int_type> +void * libxc_malloc(const int_type size){ + void * mem; + cudaMallocManaged(&mem, size); + return mem; +} + +template <class int_type1, class int_type2> +void * libxc_calloc(const int_type1 size1, const int_type2 size2){ + void * mem; + cudaMallocManaged(&mem, size1*size2); + cudaMemset(mem, 0, size1*size2); + return mem; +} + +#define libxc_memset cudaMemset + +template <class int_type> +void libxc_memcpy(void *dest, void const *src, const int_type size){ + cudaMemcpy(dest, src, size, cudaMemcpyDefault); +} + +#endif + +#endif diff --git a/ref/common/xc.h b/ref/common/xc.h new file mode 100644 index 0000000000000000000000000000000000000000..01c4e086011cc72c72da40a2c36217762ecf3bdb --- /dev/null +++ b/ref/common/xc.h @@ -0,0 +1,513 @@ +/* + Copyright (C) 2006-2007 M.A.L. Marques + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#ifndef _XC_H +#define _XC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Get the literature reference for libxc */ +const char *xc_reference(); +/* Get the doi for the literature reference for libxc */ +const char *xc_reference_doi(); + +/* Get the major, minor, and micro version of libxc */ +void xc_version(int *major, int *minor, int *micro); +/* Get the version of libxc as a string */ +const char *xc_version_string(); + +#include <stddef.h> + +#define XC_UNPOLARIZED 1 +#define XC_POLARIZED 2 + +#define XC_NON_RELATIVISTIC 0 +#define XC_RELATIVISTIC 1 + +#define XC_EXCHANGE 0 +#define XC_CORRELATION 1 +#define XC_EXCHANGE_CORRELATION 2 +#define XC_KINETIC 3 + +#define XC_FAMILY_UNKNOWN -1 +#define XC_FAMILY_LDA 1 +#define XC_FAMILY_GGA 2 +#define XC_FAMILY_MGGA 4 +#define XC_FAMILY_LCA 8 +#define XC_FAMILY_OEP 16 + +/* flags that can be used in info.flags. Don't reorder these since it + will break the ABI of the library. */ +#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_VV10 (1 << 10) /* 1024 */ +#define XC_FLAGS_STABLE (1 << 13) /* 8192 */ +/* functionals marked with the development flag may have significant problems in the implementation */ +#define XC_FLAGS_DEVELOPMENT (1 << 14) /* 16384 */ +#define XC_FLAGS_NEEDS_LAPLACIAN (1 << 15) /* 32768 */ +#define XC_FLAGS_NEEDS_TAU (1 << 16) /* 65536 */ + +/* This is the case for most functionals in libxc */ +#define XC_FLAGS_HAVE_ALL (XC_FLAGS_HAVE_EXC | XC_FLAGS_HAVE_VXC | \ + XC_FLAGS_HAVE_FXC | XC_FLAGS_HAVE_KXC | \ + XC_FLAGS_HAVE_LXC) + +/* This magic value means use default parameter */ +#define XC_EXT_PARAMS_DEFAULT -999998888 + +/* Different flavors of many-body terms used in hybrids + The Fock term to be added to the Hamiltonian reads + + F = -1/2 <i j| f(r_12)/r_12 |j i> + + where the function f(r) is + + *) XC_HYB_FOCK f(r) = coeff + *) XC_HYB_ERF_SR f(r) = coeff * (1 - erf(omega r)) + *) XC_HYB_YUKAWA_SR f(r) = coeff * exp(-omega r) + *) XC_HYB_GAUSSIAN_SR f(r) = coeff * 2*omega/sqrt(pi) * exp(-omega^2 r^2) +*/ +#define XC_HYB_NONE 0 +#define XC_HYB_FOCK 1 /* Normal hybrid */ +#define XC_HYB_PT2 2 /* Used for double hybrids */ +#define XC_HYB_ERF_SR 4 /* Short range of range separated - erf version */ +#define XC_HYB_YUKAWA_SR 8 /* Short range of range separated - Yakawa version */ +#define XC_HYB_GAUSSIAN_SR 16 /* Short range of range separated - Gaussian version */ + +/* Different types of hybrid functionals. */ +#define XC_HYB_SEMILOCAL 0 /* Standard semi-local functional (not a hybrid) */ +#define XC_HYB_HYBRID 1 /* Standard hybrid functional */ +#define XC_HYB_CAM 2 /* Coulomb attenuated hybrid */ +#define XC_HYB_CAMY 3 /* Coulomb attenuated hybrid with a Yukawa screening */ +#define XC_HYB_CAMG 4 /* Coulomb attenuated hybrid with a Gaussian screening */ +#define XC_HYB_DOUBLE_HYBRID 5 /* Double hybrid */ +#define XC_HYB_MIXTURE 32768 /* More complicated mixture (have to check individual terms) */ + +#define XC_MAX_REFERENCES 5 + +/* This are the derivatives that a functional returns */ +#define XC_NOARG +#define XC_COMMA , +#define LDA_OUT_PARAMS_NO_EXC(P1_, P2_) \ + P1_ P2_ ## vrho P1_ P2_ ## v2rho2 \ + P1_ P2_ ## v3rho3 P1_ P2_ ## v4rho4 + +#define GGA_OUT_PARAMS_NO_EXC(P1_, P2_) \ + P1_ P2_ ## vrho P1_ P2_ ## vsigma \ + P1_ P2_ ## v2rho2 P1_ P2_ ## v2rhosigma \ + P1_ P2_ ## v2sigma2 \ + P1_ P2_ ## v3rho3 P1_ P2_ ## v3rho2sigma \ + P1_ P2_ ## v3rhosigma2 P1_ P2_ ## v3sigma3 \ + P1_ P2_ ## v4rho4 P1_ P2_ ## v4rho3sigma \ + P1_ P2_ ## v4rho2sigma2 P1_ P2_ ## v4rhosigma3 \ + P1_ P2_ ## v4sigma4 + +/* This are the derivatives of a mgga + 1st order: 4 + 2nd order: 10 + 3rd order: 20 + 4th order: 35 + */ +#define MGGA_OUT_PARAMS_NO_EXC(P1_, P2_) \ + P1_ P2_ ## vrho P1_ P2_ ## vsigma \ + P1_ P2_ ## vlapl P1_ P2_ ## vtau \ + P1_ P2_ ## v2rho2 P1_ P2_ ## v2rhosigma \ + P1_ P2_ ## v2rholapl P1_ P2_ ## v2rhotau \ + P1_ P2_ ## v2sigma2 P1_ P2_ ## v2sigmalapl \ + P1_ P2_ ## v2sigmatau P1_ P2_ ## v2lapl2 \ + P1_ P2_ ## v2lapltau P1_ P2_ ## v2tau2 \ + P1_ P2_ ## v3rho3 P1_ P2_ ## v3rho2sigma \ + P1_ P2_ ## v3rho2lapl P1_ P2_ ## v3rho2tau \ + P1_ P2_ ## v3rhosigma2 P1_ P2_ ## v3rhosigmalapl \ + P1_ P2_ ## v3rhosigmatau P1_ P2_ ## v3rholapl2 \ + P1_ P2_ ## v3rholapltau P1_ P2_ ## v3rhotau2 \ + P1_ P2_ ## v3sigma3 P1_ P2_ ## v3sigma2lapl \ + P1_ P2_ ## v3sigma2tau P1_ P2_ ## v3sigmalapl2 \ + P1_ P2_ ## v3sigmalapltau P1_ P2_ ## v3sigmatau2 \ + P1_ P2_ ## v3lapl3 P1_ P2_ ## v3lapl2tau \ + P1_ P2_ ## v3lapltau2 P1_ P2_ ## v3tau3 \ + P1_ P2_ ## v4rho4 P1_ P2_ ## v4rho3sigma \ + P1_ P2_ ## v4rho3lapl P1_ P2_ ## v4rho3tau \ + P1_ P2_ ## v4rho2sigma2 P1_ P2_ ## v4rho2sigmalapl \ + P1_ P2_ ## v4rho2sigmatau P1_ P2_ ## v4rho2lapl2 \ + P1_ P2_ ## v4rho2lapltau P1_ P2_ ## v4rho2tau2 \ + P1_ P2_ ## v4rhosigma3 P1_ P2_ ## v4rhosigma2lapl \ + P1_ P2_ ## v4rhosigma2tau P1_ P2_ ## v4rhosigmalapl2 \ + P1_ P2_ ## v4rhosigmalapltau P1_ P2_ ## v4rhosigmatau2 \ + P1_ P2_ ## v4rholapl3 P1_ P2_ ## v4rholapl2tau \ + P1_ P2_ ## v4rholapltau2 P1_ P2_ ## v4rhotau3 \ + P1_ P2_ ## v4sigma4 P1_ P2_ ## v4sigma3lapl \ + P1_ P2_ ## v4sigma3tau P1_ P2_ ## v4sigma2lapl2 \ + P1_ P2_ ## v4sigma2lapltau P1_ P2_ ## v4sigma2tau2 \ + P1_ P2_ ## v4sigmalapl3 P1_ P2_ ## v4sigmalapl2tau \ + P1_ P2_ ## v4sigmalapltau2 P1_ P2_ ## v4sigmatau3 \ + P1_ P2_ ## v4lapl4 P1_ P2_ ## v4lapl3tau \ + P1_ P2_ ## v4lapl2tau2 P1_ P2_ ## v4lapltau3 \ + P1_ P2_ ## v4tau4 + + +struct xc_func_type; + +typedef struct{ + const char *ref, *doi, *bibtex; +} func_reference_type; + +char const *xc_func_reference_get_ref(const func_reference_type *reference); +char const *xc_func_reference_get_doi(const func_reference_type *reference); +char const *xc_func_reference_get_bibtex(const func_reference_type *reference); + + +typedef struct{ + int n; /* Number of parameters */ + + const char **names; /* ATTENTION: if name starts with a _ it is an *internal* parameter, + changing the value effectively changes the functional! */ + const char **descriptions; /* long description of the parameters */ + const double *values; /* default values of the parameters */ + + void (*set)(struct xc_func_type *p, const double *ext_params); +} func_params_type; + + +typedef struct{ + int number; /* identifier number */ + int kind; /* XC_EXCHANGE, XC_CORRELATION, XC_EXCHANGE_CORRELATION, XC_KINETIC */ + + const 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 */ + func_params_type ext_params; + + void (*init)(struct xc_func_type *p); + void (*end) (struct xc_func_type *p); + void (*lda) (const struct xc_func_type *p, size_t np, + const double *rho, + double *zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); + void (*gga) (const struct xc_func_type *p, size_t np, + const double *rho, const double *sigma, + double *zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); + void (*mgga)(const struct xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl_rho, const double *tau, + double *zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); +} xc_func_info_type; + + +/* for API compability with older versions of libxc */ +#define XC(func) xc_ ## func + + +int xc_func_info_get_number(const xc_func_info_type *info); +int xc_func_info_get_kind(const xc_func_info_type *info); +char const *xc_func_info_get_name(const xc_func_info_type *info); +int xc_func_info_get_family(const xc_func_info_type *info); +int xc_func_info_get_flags(const xc_func_info_type *info); +const func_reference_type *xc_func_info_get_references(const xc_func_info_type *info, int number); + + +int xc_func_info_get_n_ext_params(const xc_func_info_type *info); +char const *xc_func_info_get_ext_params_name(const xc_func_info_type *p, int number); +char const *xc_func_info_get_ext_params_description(const xc_func_info_type *info, int number); +double xc_func_info_get_ext_params_default_value(const xc_func_info_type *info, int number); + + +struct xc_dimensions{ + int rho, sigma, lapl, tau; /* spin dimensions of the arrays */ + int zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA, ); +}; + +typedef struct xc_dimensions xc_dimensions; + + +struct xc_func_type{ + const xc_func_info_type *info; /* all the information concerning this functional */ + int nspin; /* XC_UNPOLARIZED or XC_POLARIZED */ + + int n_func_aux; /* how many auxiliary functions we need */ + struct xc_func_type **func_aux; /* most GGAs are based on a LDA or other GGAs */ + double *mix_coef; /* coefficients for the mixing */ + + /** + Parameters for range-separated hybrids + hyb_type[i]: XC_HYB_NONE, XC_HYB_FOCK, XC_HYB_ERF_SR, etc. + hyb_omega[i]: the range separation constant + hyb_coeff[i]: fraction of exchange, used both for + usual hybrids as well as range-separated ones + + N.B. Different conventions for alpha and beta can be found in + literature. In the convention used in libxc, at short range the + fraction of exact exchange is cam_alpha+cam_beta, while at long + range it is cam_alpha. + */ + int hyb_number_terms, *hyb_type; + double *hyb_coeff, *hyb_omega; + + double nlc_b; /* Non-local correlation, b parameter */ + double nlc_C; /* Non-local correlation, C parameter */ + + xc_dimensions dim; /* the dimensions of all input and output arrays */ + + /* This is where the values of the external parameters are stored */ + double *ext_params; + /* This is a placeholder for structs of parameters that are used in the Maple generated sources */ + void *params; + + double dens_threshold; /* functional is put to zero for spin-densities smaller than this */ + double zeta_threshold; /* idem for the absolute value of zeta */ + double sigma_threshold; + double tau_threshold; +}; + +typedef struct xc_func_type xc_func_type; + + +/** Get a functional's id number from its name */ +int xc_functional_get_number(const char *name); +/** Get a functional's name from its id number */ +char *xc_functional_get_name(int number); +/** Get a functional's family and the number within the family from the id number */ +int xc_family_from_id(int id, int *family, int *number); + +/** The number of functionals implemented in this version of libxc */ +int xc_number_of_functionals(); +/** The maximum name length of any functional */ +int xc_maximum_name_length(); +/** Returns the available functional number sorted by id */ +void xc_available_functional_numbers(int *list); +/** Returns the available functional number sorted by the functionals' + names; this function is a helper for the Python frontend. */ +void xc_available_functional_numbers_by_name(int *list); +/** Fills the list with the names of the available functionals, + ordered by name. The list array should be [Nfuncs][maxlen+1]. */ +void xc_available_functional_names(char **list); + +/** Dynamically allocates a libxc functional; which will also need to be initialized. */ +xc_func_type *xc_func_alloc(); +/** Initializes a functional by id with nspin spin channels */ +int xc_func_init(xc_func_type *p, int functional, int nspin); +/** Destructor for an initialized functional */ +void xc_func_end(xc_func_type *p); +/** Frees a dynamically allocated functional */ +void xc_func_free(xc_func_type *p); +/** Get information on a functional */ +const xc_func_info_type *xc_func_get_info(const xc_func_type *p); + +/** Sets the density threshold for a functional */ +void xc_func_set_dens_threshold(xc_func_type *p, double t_dens); +/** Sets the spin polarization threshold for a functional */ +void xc_func_set_zeta_threshold(xc_func_type *p, double t_zeta); +/** Sets the reduced gradient threshold for a functional */ +void xc_func_set_sigma_threshold(xc_func_type *p, double t_sigma); +/** Sets the kinetic energy density threshold for a functional */ +void xc_func_set_tau_threshold(xc_func_type *p, double t_tau); + +/** Sets all external parameters for a functional */ +void xc_func_set_ext_params(xc_func_type *p, const double *ext_params); +/** Gets all external parameters for a functional. Array needs to be preallocated */ +void xc_func_get_ext_params(const xc_func_type *p, double *ext_params); +/** Sets an external parameter by name for a functional */ +void xc_func_set_ext_params_name(xc_func_type *p, const char *name, double par); +/** Gets an external parameter by name for a functional */ +double xc_func_get_ext_params_name(const xc_func_type *p, const char *name); +/** Gets an external parameter by index */ +double xc_func_get_ext_params_value(const xc_func_type *p, int number); + +/** Evaluate an LDA functional */ +void xc_lda (const xc_func_type *p, size_t np, const double *rho, + double *zk LDA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); +/** Evaluate a GGA functional */ +void xc_gga (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); +/** Evaluate a meta-GGA functional */ +void xc_mgga(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl_rho, const double *tau, + double *zk MGGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); + +/** Evaluates the energy density for an LDA functional */ +void xc_lda_exc (const xc_func_type *p, size_t np, const double *rho, double *zk); +/** Evaluates the energy density for a GGA functional */ +void xc_gga_exc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *zk); +/** Evaluates the energy density for a meta-GGA functional */ +void xc_mgga_exc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + double *zk); + +#ifndef XC_DONT_COMPILE_VXC +/** Evaluates the energy density and its first derivative for an LDA functional */ +void xc_lda_exc_vxc (const xc_func_type *p, size_t np, const double *rho, double *zk, double *vrho); +/** Evaluates the energy density and its first derivative for a GGA functional */ +void xc_gga_exc_vxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *zk, double *vrho, double *vsigma); +/** Evaluates the energy density and its first derivative for a meta-GGA functional */ +void xc_mgga_exc_vxc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + double *zk, double *vrho, double *vsigma, double *vlapl, double *vtau); + +/** Evaluates the first derivative of the energy density for an LDA functional */ +void xc_lda_vxc (const xc_func_type *p, size_t np, const double *rho, double *vrho); +/** Evaluates the first derivative of the energy density for a GGA functional */ +void xc_gga_vxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *vrho, double *vsigma); +/** Evaluates the first derivative of the energy density for a meta-GGA functional */ +void xc_mgga_vxc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + double *vrho, double *vsigma, double *vlapl, double *vtau); + +#ifndef XC_DONT_COMPILE_FXC +/** Evaluates the energy density and its first and second derivatives for an LDA functional */ +void xc_lda_exc_vxc_fxc (const xc_func_type *p, size_t np, const double *rho, double *zk, double *vrho, double *v2rho2); +/** Evaluates the energy density and its first and second derivatives for a GGA functional */ +void xc_gga_exc_vxc_fxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *zk, double *vrho, double *vsigma, double *v2rho2, double *v2rhosigma, double *v2sigma2); +/** Evaluates the energy density and its first and second derivatives for a meta-GGA functional */ +void xc_mgga_exc_vxc_fxc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + double *zk, 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); + +/** Evaluates the first and second derivatives for an LDA functional */ +void xc_lda_vxc_fxc (const xc_func_type *p, size_t np, const double *rho, double *vrho, double *v2rho2); +/** Evaluates the first and second derivatives for a GGA functional */ +void xc_gga_vxc_fxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *vrho, double *vsigma, double *v2rho2, double *v2rhosigma, double *v2sigma2); +/** Evaluates the first and second derivatives for a meta-GGA functional */ +void xc_mgga_vxc_fxc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + 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); + +/** Evaluates the second derivative for an LDA functional */ +void xc_lda_fxc (const xc_func_type *p, size_t np, const double *rho, double *v2rho2); +/** Evaluates the second derivative for a GGA functional */ +void xc_gga_fxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *v2rho2, double *v2rhosigma, double *v2sigma2); +/** Evaluates the second derivative for a meta-GGA functional */ +void xc_mgga_fxc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + double *v2rho2, double *v2rhosigma, double *v2rholapl, double *v2rhotau, + double *v2sigma2, double *v2sigmalapl, double *v2sigmatau, double *v2lapl2, + double *v2lapltau, double *v2tau2); + +#ifndef XC_DONT_COMPILE_KXC +/** Evaluates the energy density and its first, second, and third derivatives for an LDA functional */ +void xc_lda_exc_vxc_fxc_kxc (const xc_func_type *p, size_t np, const double *rho, double *zk, double *vrho, double *v2rho2, double *v3rho3); +/** Evaluates the energy density and its first, second, and third derivatives for a GGA functional */ +void xc_gga_exc_vxc_fxc_kxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *zk, double *vrho, double *vsigma, double *v2rho2, double *v2rhosigma, double *v2sigma2, + double *v3rho3, double *v3rho2sigma, double *v3rhosigma2, double *v3sigma3); +/** Evaluates the energy density and its first, second, and third derivatives for a meta-GGA functional */ +void xc_mgga_exc_vxc_fxc_kxc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + double *zk, 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); + +/** Evaluates the first, second, and third derivatives for an LDA functional */ +void xc_lda_vxc_fxc_kxc (const xc_func_type *p, size_t np, const double *rho, double *vrho, double *v2rho2, double *v3rho3); +/** Evaluates the first, second, and third derivatives for a GGA functional */ +void xc_gga_vxc_fxc_kxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *vrho, double *vsigma, double *v2rho2, double *v2rhosigma, double *v2sigma2, + double *v3rho3, double *v3rho2sigma, double *v3rhosigma2, double *v3sigma3); +/** Evaluates the first, second, and third derivatives for a meta-GGA functional */ +void xc_mgga_vxc_fxc_kxc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const double *tau, + 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); + +/** Evaluates the third derivative for an LDA functional */ +void xc_lda_kxc (const xc_func_type *p, size_t np, const double *rho, double *v3rho3); +/** Evaluates the third derivative for a GGA functional */ +void xc_gga_kxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *v3rho3, double *v3rho2sigma, double *v3rhosigma2, double *v3sigma3); +/** Evaluates the third derivative for a meta-GGA functional */ +void xc_mgga_kxc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const 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); + +#ifndef XC_DONT_COMPILE_LXC +/** Evaluates the fourth derivative for an LDA functional */ +void xc_lda_lxc (const xc_func_type *p, size_t np, const double *rho, double *v4rho4); +/** Evaluates the fourth derivative for a GGA functional */ +void xc_gga_lxc (const xc_func_type *p, size_t np, const double *rho, const double *sigma, + double *v4rho4, double *v4rho3sigma, double *v4rho2sigma2, double *v4rhosigma3, + double *v4sigma4); +/** Evaluates the fourth derivative for a meta-GGA functional */ +void xc_mgga_lxc(const xc_func_type *p, size_t np, + const double *rho, const double *sigma, const double *lapl, const 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); +#endif +#endif +#endif +#endif + +/* Calculate asymptotic value of the AK13 potential */ +double xc_gga_ak13_get_asymptotic (double homo); +/* Calculate asymptotic value of the AK13 potential with customized parameter values */ +double xc_gga_ak13_pars_get_asymptotic (double homo, const double *ext_params); + + +/* Returns the hybrid type of a functional */ +int xc_hyb_type(const xc_func_type *p); +/* Returns fraction of Hartree-Fock exchange in a global hybrid functional */ +double xc_hyb_exx_coef(const xc_func_type *p); +/* Returns fraction of Hartee-Fock exchange and short-range exchange in a range-separated hybrid functional */ +void xc_hyb_cam_coef(const xc_func_type *p, double *omega, double *alpha, double *beta); +/* Returns the b and C coefficients for a non-local VV10 correlation kernel */ +void xc_nlc_coef(const xc_func_type *p, double *nlc_b, double *nlc_C); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ref/genxc/gga_x_pbe_genxc.c b/ref/genxc/gga_x_pbe_genxc.c new file mode 100644 index 0000000000000000000000000000000000000000..e32f683ed909cd7b0fbee7400d8f139ae3835325 --- /dev/null +++ b/ref/genxc/gga_x_pbe_genxc.c @@ -0,0 +1,328 @@ +/* + Copyright (C) 2006-2007 M.A.L. Marques + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + + +#include <omp.h> +//--- +#include "../common/util.h" +#include "gga_x_pbe_genxc.h" + + +typedef struct{ + double kappa, mu; + double lambda; /* parameter used in the Odashima & Capelle versions */ +} gga_x_pbe_params; + + +static void +gga_x_pbe_init(xc_func_type *p) +{ + gga_x_pbe_params *params; + + assert(p!=NULL && p->params == NULL); + p->params = libxc_malloc(sizeof(gga_x_pbe_params)); + params = (gga_x_pbe_params *) (p->params); + + /* This has to be explicitly initialized here */ + params->lambda = 0.0; +} + +#define PBE_N_PAR 2 +static const char *pbe_names[PBE_N_PAR] = {"_kappa", "_mu"}; +static const char *pbe_desc[PBE_N_PAR] = { + "Asymptotic value of the enhancement function", + "Coefficient of the 2nd order expansion"}; + +static const double pbe_values[PBE_N_PAR] = + {0.8040, MU_PBE}; +static const double pbe_r_values[PBE_N_PAR] = + {1.245, MU_PBE}; +static const double pbe_sol_values[PBE_N_PAR] = + {0.804, MU_GE}; +static const double pbe_xpbe_values[PBE_N_PAR] = + {0.91954, 0.23214}; +static const double pbe_jsjr_values[PBE_N_PAR] = + {0.8040, 0.046*M_PI*M_PI/3.0}; +static const double pbe_k1_vdw_values[PBE_N_PAR] = + {1.0, MU_PBE}; +static const double pbe_apbe_values[PBE_N_PAR] = + {0.8040, 0.260}; +static const double pbe_tca_values[PBE_N_PAR] = + {1.227, MU_PBE}; +static const double pbe_mol_values[PBE_N_PAR] = + {0.8040, 0.27583}; +static const double pbe_bcgp_values[PBE_N_PAR] = + {0.8040, 0.249}; +static const double pbe_fe_values[PBE_N_PAR] = + {0.437, 0.346}; + +//#include "../libxc/work_gga.h" +//#define work_gga_genxc work_gga +//#include "../libxc/gga_x_pbe.h" +#include "gga_x_pbe_genxc_funcs.h" +#include "work_gga_genxc.h" + + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_genxc = { + XC_GGA_X_PBE_GENXC, + XC_EXCHANGE, + "Perdew, Burke & Ernzerhof", + XC_FAMILY_GGA, + //{&xc_ref_Perdew1996_3865, &xc_ref_Perdew1996_3865_err, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_r_genxc = { + XC_GGA_X_PBE_R_GENXC, + XC_EXCHANGE, + "Revised PBE from Zhang & Yang", + XC_FAMILY_GGA, + //{&xc_ref_Zhang1998_890, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_r_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_sol_genxc = { + XC_GGA_X_PBE_SOL_GENXC, + XC_EXCHANGE, + "Perdew, Burke & Ernzerhof SOL", + XC_FAMILY_GGA, + //{&xc_ref_Perdew2008_136406, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_sol_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_xpbe_genxc = { + XC_GGA_X_XPBE_GENXC, + XC_EXCHANGE, + "Extended PBE by Xu & Goddard III", + XC_FAMILY_GGA, + //{&xc_ref_Xu2004_4068, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_xpbe_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_jsjr_genxc = { + XC_GGA_X_PBE_JSJR_GENXC, + XC_EXCHANGE, + "Reparametrized PBE by Pedroza, Silva & Capelle", + XC_FAMILY_GGA, + //{&xc_ref_Pedroza2009_201106, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_jsjr_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbek1_vdw_genxc = { + XC_GGA_X_PBEK1_VDW_GENXC, + XC_EXCHANGE, + "Reparametrized PBE for vdW", + XC_FAMILY_GGA, + //{&xc_ref_Klimes2010_022201, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_k1_vdw_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_apbe_genxc = { + XC_GGA_X_APBE_GENXC, + XC_EXCHANGE, + "mu fixed from the semiclassical neutral atom", + XC_FAMILY_GGA, + //{&xc_refxc_ref_Constantin2011_186406, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_apbe_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_tca_genxc = { + XC_GGA_X_PBE_TCA_GENXC, + XC_EXCHANGE, + "PBE revised by Tognetti et al", + XC_FAMILY_GGA, + //{&xc_ref_Tognetti2008_536, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_tca_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_mol_genxc = { + XC_GGA_X_PBE_MOL_GENXC, + XC_EXCHANGE, + "Reparametrized PBE by del Campo, Gazquez, Trickey & Vela", + XC_FAMILY_GGA, + //{&xc_ref_delCampo2012_104108, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_mol_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_bcgp_genxc = { + XC_GGA_X_BCGP_GENXC, + XC_EXCHANGE, + "Burke, Cancio, Gould, and Pittalis", + XC_FAMILY_GGA, + //{&xc_ref_Burke2014_4834, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_bcgp_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbefe_genxc = { + XC_GGA_X_PBEFE_GENXC, + XC_EXCHANGE, + "PBE for formation energies", + XC_FAMILY_GGA, + //{&xc_ref_Perez2015_3844, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_fe_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#define PBEL_N_PAR 3 +static const char *pbe_lambda_names[PBEL_N_PAR] = {"_N", "_kappa", "_mu"}; +static const char *pbe_lambda_desc[PBEL_N_PAR] = { + "Number of electrons", + "Asymptotic value of the enhancement function", + "Coefficient of the 2nd order expansion"}; +static const double pbe_lambda_lo_n_values[PBEL_N_PAR] = + {1e23, MU_PBE, 2.273}; +static const double pbe_lambda_ch_n_values[PBEL_N_PAR] = + {1e23, MU_PBE, 2.215}; +static const double pbe_lambda_oc2_n_values[PBEL_N_PAR] = + {1e23, MU_PBE, 2.00}; + +static void +pbe_lambda_set_ext_params(xc_func_type *p, const double *ext_params) +{ + const double lambda_1 = 1.48; + + gga_x_pbe_params *params; + double lambda, N; + + assert(p != NULL && p->params != NULL); + params = (gga_x_pbe_params *) (p->params); + + N = get_ext_param(p, ext_params, 0); + params->mu = get_ext_param(p, ext_params, 1); + params->lambda = get_ext_param(p, ext_params, 2); + + lambda = (1.0 - 1.0/N)*params->lambda + lambda_1/N; + params->kappa = lambda/M_CBRT2 - 1.0; +} + + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_lambda_lo_n_genxc = { + XC_GGA_X_LAMBDA_LO_N_GENXC, + XC_EXCHANGE, + "lambda_LO(N) version of PBE", + XC_FAMILY_GGA, + //{&xc_ref_Odashima2009_798, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBEL_N_PAR, pbe_lambda_names, pbe_lambda_desc, pbe_lambda_lo_n_values, pbe_lambda_set_ext_params}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_lambda_ch_n_genxc = { + XC_GGA_X_LAMBDA_CH_N_GENXC, + XC_EXCHANGE, + "lambda_CH(N) version of PBE", + XC_FAMILY_GGA, + //{&xc_ref_Odashima2009_798, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBEL_N_PAR, pbe_lambda_names, pbe_lambda_desc, pbe_lambda_ch_n_values, pbe_lambda_set_ext_params}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_lambda_oc2_n_genxc = { + XC_GGA_X_LAMBDA_OC2_N_GENXC, + XC_EXCHANGE, + "lambda_OC2(N) version of PBE", + XC_FAMILY_GGA, + //{&xc_ref_Odashima2009_798, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBEL_N_PAR, pbe_lambda_names, pbe_lambda_desc, pbe_lambda_oc2_n_values, pbe_lambda_set_ext_params}, + gga_x_pbe_init, NULL, + NULL, work_gga_genxc, NULL +}; + + diff --git a/ref/genxc/gga_x_pbe_genxc.h b/ref/genxc/gga_x_pbe_genxc.h new file mode 100644 index 0000000000000000000000000000000000000000..a9404263b81b685cd411be01506be925b0d8564c --- /dev/null +++ b/ref/genxc/gga_x_pbe_genxc.h @@ -0,0 +1,14 @@ +#define XC_GGA_X_PBE_GENXC 1101 /* Perdew, Burke & Ernzerhof exchange */ +#define XC_GGA_X_PBE_R_GENXC 1102 /* Perdew, Burke & Ernzerhof exchange (revised) */ +#define XC_GGA_X_PBE_SOL_GENXC 1116 /* Perdew, Burke & Ernzerhof exchange (solids) */ +#define XC_GGA_X_XPBE_GENXC 1123 /* xPBE reparametrization by Xu & Goddard */ +#define XC_GGA_X_PBE_JSJR_GENXC 1126 /* JSJR reparametrization by Pedroza, Silva & Capelle */ +#define XC_GGA_X_PBEK1_VDW_GENXC 1140 /* PBE reparametrization for vdW */ +#define XC_GGA_X_APBE_GENXC 1184 /* mu fixed from the semiclassical neutral atom */ +#define XC_GGA_X_PBE_TCA_GENXC 1059 /* PBE revised by Tognetti et al */ +#define XC_GGA_X_PBE_MOL_GENXC 1049 /* Del Campo, Gazquez, Trickey and Vela (PBE-like) */ +#define XC_GGA_X_LAMBDA_LO_N_GENXC 1045 /* lambda_LO(N) version of PBE */ +#define XC_GGA_X_LAMBDA_CH_N_GENXC 1044 /* lambda_CH(N) version of PBE */ +#define XC_GGA_X_LAMBDA_OC2_N_GENXC 1040 /* lambda_OC2(N) version of PBE */ +#define XC_GGA_X_BCGP_GENXC 1038 /* Burke, Cancio, Gould, and Pittalis */ +#define XC_GGA_X_PBEFE_GENXC 1265 /* PBE for formation energies */ diff --git a/ref/genxc/gga_x_pbe_genxc_funcs.h b/ref/genxc/gga_x_pbe_genxc_funcs.h new file mode 100644 index 0000000000000000000000000000000000000000..2871438baaff36caa682840fd114a161a0494c1c --- /dev/null +++ b/ref/genxc/gga_x_pbe_genxc_funcs.h @@ -0,0 +1,1340 @@ +#define maple2c_order 4 +#define MAPLE2C_FLAGS (XC_FLAGS_I_HAVE_EXC | XC_FLAGS_I_HAVE_VXC | XC_FLAGS_I_HAVE_FXC | XC_FLAGS_I_HAVE_KXC | XC_FLAGS_I_HAVE_LXC) + +void func_unpol( + const xc_func_type *p, int order, const double *my_rho, const double *my_sigma, double *izk, + double *ivrho, double *ivsigma, double *iv2rho2, double *iv2rhosigma, double *iv2sigma2, + double *iv3rho3, double *iv3rho2sigma, double *iv3rhosigma2, double *iv3sigma3, + double *iv4rho4, double *iv4rho3sigma, double *iv4rho2sigma2, double *iv4rhosigma3, double *iv4sigma4) { + +#ifndef XC_DONT_COMPILE_EXC + double t2, t3, t4, t6, t7, t8, t10, t11; + double t13, t15, t17, t18, t20, t22, t23, t24; + double t25, t27, t28, t30, t31, t33, t37, t42; + double t46; + +#ifndef XC_DONT_COMPILE_VXC + double t52, t56, t58, t59, t61, t64, t65, t69; + double t78, t79, t82; + +#ifndef XC_DONT_COMPILE_FXC + double t91, t96, t99, t103, t106, t107, t108, t109; + double t111, t112, t115, t119, t124, t128, t131, t135; + double t138, t145, t148; + +#ifndef XC_DONT_COMPILE_KXC + double t159, t162, t166, t169, t172, t173, t177, t178; + double t179, t180, t181, t182, t184, t188, t196, t200; + double t202, t206, t212, t216, t220, t223, t227, t231; + +#ifndef XC_DONT_COMPILE_LXC + double t253, t268, t269, t270, t276, t297, t316, t333; + double t344; +#endif + +#endif + +#endif + +#endif + +#endif + + + const gga_x_pbe_params *params = p->params; + const double mu = MU_PBE; + const double kappa = 0.8040; + + t2 = my_rho[0] / 0.2e1 <= p->dens_threshold; + t3 = M_CBRT3; + t4 = M_CBRTPI; + t6 = t3 / t4; + t7 = 0.1e1 <= p->zeta_threshold; + t8 = p->zeta_threshold - 0.1e1; + t10 = my_piecewise5(t7, t8, t7, -t8, 0); + t11 = 0.1e1 + t10; + t13 = POW_1_3(p->zeta_threshold); + t15 = POW_1_3(t11); + t17 = my_piecewise3(t11 <= p->zeta_threshold, t13 * p->zeta_threshold, t15 * t11); + t18 = POW_1_3(my_rho[0]); + t20 = M_CBRT6; + t22 = M_PI * M_PI; + t23 = POW_1_3(t22); + t24 = t23 * t23; + t25 = 0.1e1 / t24; + t27 = M_CBRT2; + t28 = t27 * t27; + t30 = my_rho[0] * my_rho[0]; + t31 = t18 * t18; + t33 = 0.1e1 / t31 / t30; + t37 = kappa + mu * t20 * t25 * my_sigma[0] * t28 * t33 / 0.24e2; + t42 = 0.1e1 + kappa * (0.1e1 - kappa / t37); + t46 = my_piecewise3(t2, 0, -0.3e1 / 0.8e1 * t6 * t17 * t18 * t42); + if(izk != NULL && (p->info->flags & XC_FLAGS_HAVE_EXC)) + izk[0] = 0.2e1 * t46; + +#ifndef XC_DONT_COMPILE_VXC + + if(order < 1) return; + + + t52 = t30 * my_rho[0]; + t56 = kappa * kappa; + t58 = t6 * t17 / t18 / t52 * t56; + t59 = t37 * t37; + t61 = 0.1e1 / t59 * mu; + t64 = t25 * my_sigma[0] * t28; + t65 = t61 * t20 * t64; + t69 = my_piecewise3(t2, 0, -t6 * t17 / t31 * t42 / 0.8e1 + t58 * t65 / 0.24e2); + if(ivrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + ivrho[0] = 0.2e1 * my_rho[0] * t69 + 0.2e1 * t46; + + t78 = t20 * t25 * t28; + t79 = t61 * t78; + t82 = my_piecewise3(t2, 0, -t6 * t17 / t18 / t30 * t56 * t79 / 0.64e2); + if(ivrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + ivsigma[0] = 0.2e1 * my_rho[0] * t82; + +#ifndef XC_DONT_COMPILE_FXC + + if(order < 2) return; + + + t91 = t30 * t30; + t96 = t6 * t17 / t18 / t91 * t56; + t99 = t91 * t52; + t103 = t6 * t17 / t99 * t56; + t106 = mu * mu; + t107 = 0.1e1 / t59 / t37 * t106; + t108 = t20 * t20; + t109 = t107 * t108; + t111 = 0.1e1 / t23 / t22; + t112 = my_sigma[0] * my_sigma[0]; + t115 = t109 * t111 * t112 * t27; + t119 = my_piecewise3(t2, 0, t6 * t17 / t31 / my_rho[0] * t42 / 0.12e2 - t96 * t65 / 0.8e1 + t103 * t115 / 0.54e2); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rho2[0] = 0.2e1 * my_rho[0] * t119 + 0.4e1 * t69; + + t124 = t91 * t30; + t128 = t6 * t17 / t124 * t56; + t131 = t109 * t111 * t27 * my_sigma[0]; + t135 = my_piecewise3(t2, 0, 0.7e1 / 0.192e3 * t58 * t79 - t128 * t131 / 0.144e3); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rhosigma[0] = 0.2e1 * my_rho[0] * t135 + 0.2e1 * t82; + + t138 = t91 * my_rho[0]; + t145 = t107 * t108 * t111 * t27; + t148 = my_piecewise3(t2, 0, t6 * t17 / t138 * t56 * t145 / 0.384e3); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2sigma2[0] = 0.2e1 * my_rho[0] * t148; + +#ifndef XC_DONT_COMPILE_KXC + + if(order < 3) return; + + + t159 = t6 * t17 / t18 / t138 * t56; + t162 = t91 * t91; + t166 = t6 * t17 / t162 * t56; + t169 = t22 * t22; + t172 = t3 / t4 / t169; + t173 = t162 * t30; + t177 = t172 * t17 / t31 / t173; + t178 = t59 * t59; + t179 = 0.1e1 / t178; + t180 = t56 * t179; + t181 = t106 * mu; + t182 = t112 * my_sigma[0]; + t184 = t180 * t181 * t182; + t188 = my_piecewise3(t2, 0, -0.5e1 / 0.36e2 * t6 * t17 * t33 * t42 + 0.115e3 / 0.216e3 * t159 * t65 - 0.5e1 / 0.27e2 * t166 * t115 + 0.2e1 / 0.27e2 * t177 * t184); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho3[0] = 0.2e1 * my_rho[0] * t188 + 0.6e1 * t119; + + t196 = t162 * my_rho[0]; + t200 = t172 * t17 / t31 / t196; + t202 = t180 * t181 * t112; + t206 = my_piecewise3(t2, 0, -0.35e2 / 0.288e3 * t96 * t79 + 0.25e2 / 0.432e3 * t103 * t131 - t200 * t202 / 0.36e2); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[0] = 0.2e1 * my_rho[0] * t206 + 0.4e1 * t135; + + t212 = 0.1e1 / t31 / t162; + t216 = t180 * t181 * my_sigma[0]; + t220 = my_piecewise3(t2, 0, -0.5e1 / 0.384e3 * t128 * t145 + t172 * t17 * t212 * t216 / 0.96e2); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[0] = 0.2e1 * my_rho[0] * t220 + 0.2e1 * t148; + + t223 = t172 * t17; + t227 = t179 * t181; + t231 = my_piecewise3(t2, 0, -t223 / t31 / t99 * t56 * t227 / 0.256e3); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[0] = 0.2e1 * my_rho[0] * t231; + +#ifndef XC_DONT_COMPILE_LXC + + if(order < 4) return; + + + t253 = t162 * t52; + t268 = t106 * t106; + t269 = 0.1e1 / t178 / t37 * t268; + t270 = t112 * t112; + t276 = my_piecewise3(t2, 0, 0.10e2 / 0.27e2 * t6 * t17 / t31 / t52 * t42 - 0.305e3 / 0.108e3 * t6 * t17 / t18 / t124 * t56 * t65 + 0.835e3 / 0.486e3 * t6 * t17 / t196 * t56 * t115 - 0.124e3 / 0.81e2 * t172 * t17 / t31 / t253 * t184 + 0.8e1 / 0.243e3 * t172 * t17 / t18 / t162 / t124 * t56 * t269 * t270 * t78); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho4[0] = 0.2e1 * my_rho[0] * t276 + 0.8e1 * t188; + + t297 = my_piecewise3(t2, 0, 0.455e3 / 0.864e3 * t159 * t79 - 0.595e3 / 0.1296e4 * t166 * t131 + t177 * t202 / 0.2e1 - t172 * t17 / t18 / t162 / t138 * t56 * t269 * t182 * t78 / 0.81e2); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[0] = 0.2e1 * my_rho[0] * t297 + 0.6e1 * t206; + + t316 = my_piecewise3(t2, 0, 0.5e1 / 0.64e2 * t103 * t145 - 0.41e2 / 0.288e3 * t200 * t216 + t172 * t17 / t18 / t162 / t91 * t56 * t269 * t112 * t78 / 0.216e3); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[0] = 0.2e1 * my_rho[0] * t316 + 0.4e1 * t220; + + t333 = my_piecewise3(t2, 0, 0.23e2 / 0.768e3 * t223 * t212 * t56 * t227 - t172 * t17 / t18 / t253 * t56 * t269 * t20 * t64 / 0.576e3); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[0] = 0.2e1 * my_rho[0] * t333 + 0.2e1 * t231; + + t344 = my_piecewise3(t2, 0, t172 * t17 / t18 / t173 * t56 * t269 * t78 / 0.1536e4); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[0] = 0.2e1 * my_rho[0] * t344; + +#ifndef XC_DONT_COMPILE_MXC + + if(order < 5) return; + + +#endif + +#endif + +#endif + +#endif + +#endif +} + +void func_pol( + const xc_func_type *p, int order, const double *my_rho, const double *my_sigma, double *izk, + double *ivrho, double *ivsigma, double *iv2rho2, double *iv2rhosigma, double *iv2sigma2, + double *iv3rho3, double *iv3rho2sigma, double *iv3rhosigma2, double *iv3sigma3, + double *iv4rho4, double *iv4rho3sigma, double *iv4rho2sigma2, double *iv4rhosigma3, double *iv4sigma4) { + +#ifndef XC_DONT_COMPILE_EXC + double t1, t2, t3, t5, t6, t7, t10, t11; + double t14, t15, t16, t18, t19, t20, t21, t22; + double t23, t25, t26, t27, t28, t29, t30, t31; + double t32, t33, t34, t35, t36, t37, t39, t43; + double t48, t52, t53, t54, t56, t57, t58, t59; + double t61, t62, t63, t64, t65, t66, t68, t72; + double t77, t81; + +#ifndef XC_DONT_COMPILE_VXC + double t82, t83, t84, t86, t89, t90, t94, t95; + double t96, t99, t100, t101, t102, t103, t105, t106; + double t107, t109, t111, t115, t116, t118, t121, t122; + double t126, t129, t131, t135, t138, t139, t144, t146; + double t149, t150, t154, t155, t156, t158, t159, t160; + double t162, t164, t168, t171, t173, t176, t178, t181; + +#ifndef XC_DONT_COMPILE_FXC + double t184, t185, t186, t189, t190, t191, t194, t198; + double t199, t203, t205, t208, t212, t213, t216, t218; + double t219, t223, t224, t225, t226, t228, t229, t230; + double t231, t234, t236, t240, t242, t246, t247, t248; + double t249, t252, t255, t259, t260, t264, t266, t268; + double t271, t273, t276, t280, t284, t285, t289, t291; + double t294, t300, t301, t305, t309, t310, t314, t316; + double t320, t324, t325, t328, t333, t338, t342, t343; + double t349, t350, t355, t359, t360, t366, t372, t373; + double t374, t375, t376, t379, t381, t385, t387, t391; + double t397, t398, t400, t403, t407, t411, t416, t418; + double t423, t427, t429, t432, t436, t440, t442, t443; + double t447, t450, t451, t455, t458; + +#ifndef XC_DONT_COMPILE_KXC + double t462, t464, t467, t469, t471, t473, t478, t481; + double t485, t486, t491, t492, t494, t496, t498, t500; + double t503, t504, t507, t509, t510, t513, t516, t517; + double t518, t521, t525, t526, t530, t533, t534, t535; + double t537, t538, t539, t540, t541, t542, t544, t547; + double t548, t550, t551, t554, t557, t560, t564, t565; + double t569, t571, t573, t575, t577, t580, t582, t585; + double t586, t587, t590, t595, t596, t598, t602, t603; + double t607, t610, t612, t615, t617, t620, t622, t633; + double t634, t635, t638, t643, t645, t649, t650, t654; + double t657, t658, t660, t665, t669, t671, t673, t674; + double t677, t680, t685, t689, t693, t694, t698, t700; + double t703, t710, t711, t716, t720, t724, t725, t729; + double t731, t735, t739, t740, t746, t750, t752, t753; + double t758, t765, t769, t770, t777, t778, t785, t789; + double t790, t794, t796, t798, t802, t804, t816, t821; + double t822, t824, t825, t826, t827, t828, t830, t833; + double t834, t840, t847, t848, t850, t852, t854, t856; + double t861, t865, t869, t874, t877, t879, t883, t893; + double t897, t902, t906, t909, t916, t928, t930, t932; + double t937, t941, t945, t950, t951, t953, t955, t959; + double t963, t968, t970, t975, t979, t981, t983, t987; + double t991, t995, t998, t1001, t1004; + +#ifndef XC_DONT_COMPILE_LXC + double t1009, t1013, t1016, t1020, t1023, t1025, t1027, t1028; + double t1034, t1040, t1041, t1044, t1048, t1053, t1059, t1060; + double t1062, t1066, t1067, t1070, t1071, t1073, t1076, t1077; + double t1079, t1086, t1088, t1090, t1093, t1094, t1095, t1109; + double t1112, t1125, t1127, t1129, t1131, t1132, t1134, t1135; + double t1141, t1146, t1149, t1153, t1160, t1164, t1168, t1173; + double t1175, t1182, t1186, t1187, t1190, t1208, t1209, t1211; + double t1215, t1224, t1227, t1230, t1234, t1235, t1239, t1241; + double t1242, t1243, t1253, t1261, t1263, t1280, t1282, t1286; + double t1293, t1297, t1298, t1301, t1307, t1311, t1312, t1315; + double t1316, t1317, t1319, t1320, t1322, t1323, t1331, t1335; + double t1336, t1343, t1347, t1363, t1376, t1380, t1394, t1396; + double t1402, t1408, t1412, t1427, t1440, t1444, t1449, t1451; + double t1453, t1455, t1458, t1459, t1462, t1463, t1468, t1470; + double t1491, t1495, t1502, t1505, t1514, t1515, t1518, t1536; + double t1540, t1549, t1550, t1552, t1560, t1565, t1568, t1570; + double t1573, t1574, t1576, t1578, t1587, t1589, t1594, t1599; + double t1606, t1610, t1619, t1620, t1625, t1632, t1636, t1645; + double t1651, t1657, t1664, t1684, t1687, t1688, t1702, t1704; + double t1715, t1731, t1732, t1734, t1736, t1738, t1740, t1742; + double t1746, t1761, t1763, t1764, t1769, t1771, t1774, t1776; + double t1778, t1785, t1790, t1793, t1795, t1808, t1809, t1811; + double t1815, t1816, t1823, t1824, t1829, t1830, t1832, t1833; + double t1837, t1847, t1848, t1852, t1857, t1861, t1868, t1872; + double t1876, t1878, t1879, t1887, t1934, t1935, t1940, t1947; + double t1948, t1950, t1969, t1974, t1977, t1979, t1983, t1993; + double t1997, t2002, t2006, t2009, t2016, t2045, t2050, t2062; + double t2067, t2069, t2074, t2089, t2098, t2106; +#endif + +#endif + +#endif + +#endif + +#endif + + + const gga_x_pbe_params *params = (gga_x_pbe_params * )(p->params); + const double mu = 0.249; + const double kappa = 0.8040; + //const double mu = params->mu; + //const double kappa = params->kappa; + + t1 = my_rho[0] <= p->dens_threshold; + t2 = M_CBRT3; + t3 = M_CBRTPI; + t5 = t2 / t3; + t6 = my_rho[0] + my_rho[1]; + t7 = 0.1e1 / t6; + t10 = 0.2e1 * my_rho[0] * t7 <= p->zeta_threshold; + t11 = p->zeta_threshold - 0.1e1; + t14 = 0.2e1 * my_rho[1] * t7 <= p->zeta_threshold; + t15 = -t11; + t16 = my_rho[0] - my_rho[1]; + t18 = my_piecewise5(t10, t11, t14, t15, t16 * t7); + t19 = 0.1e1 + t18; + t20 = t19 <= p->zeta_threshold; + t21 = POW_1_3(p->zeta_threshold); + t22 = t21 * p->zeta_threshold; + t23 = POW_1_3(t19); + t25 = my_piecewise3(t20, t22, t23 * t19); + t26 = POW_1_3(t6); + t27 = t25 * t26; + t28 = M_CBRT6; + t29 = mu * t28; + t30 = M_PI * M_PI; + t31 = POW_1_3(t30); + t32 = t31 * t31; + t33 = 0.1e1 / t32; + t34 = t33 * my_sigma[0]; + t35 = my_rho[0] * my_rho[0]; + t36 = POW_1_3(my_rho[0]); + t37 = t36 * t36; + t39 = 0.1e1 / t37 / t35; + t43 = kappa + t29 * t34 * t39 / 0.24e2; + t48 = 0.1e1 + kappa * (0.1e1 - kappa / t43); + t52 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t27 * t48); + t53 = my_rho[1] <= p->dens_threshold; + t54 = -t16; + t56 = my_piecewise5(t14, t11, t10, t15, t54 * t7); + t57 = 0.1e1 + t56; + t58 = t57 <= p->zeta_threshold; + t59 = POW_1_3(t57); + t61 = my_piecewise3(t58, t22, t59 * t57); + t62 = t61 * t26; + t63 = t33 * my_sigma[2]; + t64 = my_rho[1] * my_rho[1]; + t65 = POW_1_3(my_rho[1]); + t66 = t65 * t65; + t68 = 0.1e1 / t66 / t64; + t72 = kappa + t29 * t63 * t68 / 0.24e2; + t77 = 0.1e1 + kappa * (0.1e1 - kappa / t72); + t81 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t62 * t77); + if(izk != NULL && (p->info->flags & XC_FLAGS_HAVE_EXC)) + izk[0] = t52 + t81; + +#ifndef XC_DONT_COMPILE_VXC + + if(order < 1) return; + + + t82 = t6 * t6; + t83 = 0.1e1 / t82; + t84 = t16 * t83; + t86 = my_piecewise5(t10, 0, t14, 0, t7 - t84); + t89 = my_piecewise3(t20, 0, 0.4e1 / 0.3e1 * t23 * t86); + t90 = t89 * t26; + t94 = t26 * t26; + t95 = 0.1e1 / t94; + t96 = t25 * t95; + t99 = t5 * t96 * t48 / 0.8e1; + t100 = kappa * kappa; + t101 = t27 * t100; + t102 = t5 * t101; + t103 = t43 * t43; + t105 = 0.1e1 / t103 * mu; + t106 = t105 * t28; + t107 = t35 * my_rho[0]; + t109 = 0.1e1 / t37 / t107; + t111 = t106 * t34 * t109; + t115 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t90 * t48 - t99 + t102 * t111 / 0.24e2); + t116 = t54 * t83; + t118 = my_piecewise5(t14, 0, t10, 0, -t7 - t116); + t121 = my_piecewise3(t58, 0, 0.4e1 / 0.3e1 * t59 * t118); + t122 = t121 * t26; + t126 = t61 * t95; + t129 = t5 * t126 * t77 / 0.8e1; + t131 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t122 * t77 - t129); + if(ivrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + ivrho[0] = t52 + t81 + t6 * (t115 + t131); + + t135 = my_piecewise5(t10, 0, t14, 0, -t7 - t84); + t138 = my_piecewise3(t20, 0, 0.4e1 / 0.3e1 * t23 * t135); + t139 = t138 * t26; + t144 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t139 * t48 - t99); + t146 = my_piecewise5(t14, 0, t10, 0, t7 - t116); + t149 = my_piecewise3(t58, 0, 0.4e1 / 0.3e1 * t59 * t146); + t150 = t149 * t26; + t154 = t62 * t100; + t155 = t5 * t154; + t156 = t72 * t72; + t158 = 0.1e1 / t156 * mu; + t159 = t158 * t28; + t160 = t64 * my_rho[1]; + t162 = 0.1e1 / t66 / t160; + t164 = t159 * t63 * t162; + t168 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t150 * t77 - t129 + t155 * t164 / 0.24e2); + if(ivrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + ivrho[1] = t52 + t81 + t6 * (t144 + t168); + + t171 = t28 * t33; + t173 = t105 * t171 * t39; + t176 = my_piecewise3(t1, 0, -t102 * t173 / 0.64e2); + if(ivrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + ivsigma[0] = t6 * t176; + + if(ivrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + ivsigma[1] = 0.0e0; + + t178 = t158 * t171 * t68; + t181 = my_piecewise3(t53, 0, -t155 * t178 / 0.64e2); + if(ivrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + ivsigma[2] = t6 * t181; + +#ifndef XC_DONT_COMPILE_FXC + + if(order < 2) return; + + + t184 = t23 * t23; + t185 = 0.1e1 / t184; + t186 = t86 * t86; + t189 = t82 * t6; + t190 = 0.1e1 / t189; + t191 = t16 * t190; + t194 = my_piecewise5(t10, 0, t14, 0, -0.2e1 * t83 + 0.2e1 * t191); + t198 = my_piecewise3(t20, 0, 0.4e1 / 0.9e1 * t185 * t186 + 0.4e1 / 0.3e1 * t23 * t194); + t199 = t198 * t26; + t203 = t89 * t95; + t205 = t5 * t203 * t48; + t208 = t5 * t90 * t100; + t212 = 0.1e1 / t94 / t6; + t213 = t25 * t212; + t216 = t5 * t213 * t48 / 0.12e2; + t218 = t5 * t96 * t100; + t219 = t218 * t111; + t223 = mu * mu; + t224 = 0.1e1 / t103 / t43 * t223; + t225 = t28 * t28; + t226 = t224 * t225; + t228 = 0.1e1 / t31 / t30; + t229 = my_sigma[0] * my_sigma[0]; + t230 = t228 * t229; + t231 = t35 * t35; + t234 = 0.1e1 / t36 / t231 / t107; + t236 = t226 * t230 * t234; + t240 = 0.1e1 / t37 / t231; + t242 = t106 * t34 * t240; + t246 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t199 * t48 - t205 / 0.4e1 + t208 * t111 / 0.12e2 + t216 + t219 / 0.36e2 + t102 * t236 / 0.108e3 - 0.11e2 / 0.72e2 * t102 * t242); + t247 = t59 * t59; + t248 = 0.1e1 / t247; + t249 = t118 * t118; + t252 = t54 * t190; + t255 = my_piecewise5(t14, 0, t10, 0, 0.2e1 * t83 + 0.2e1 * t252); + t259 = my_piecewise3(t58, 0, 0.4e1 / 0.9e1 * t248 * t249 + 0.4e1 / 0.3e1 * t59 * t255); + t260 = t259 * t26; + t264 = t121 * t95; + t266 = t5 * t264 * t77; + t268 = t61 * t212; + t271 = t5 * t268 * t77 / 0.12e2; + t273 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t260 * t77 - t266 / 0.4e1 + t271); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rho2[0] = 0.2e1 * t115 + 0.2e1 * t131 + t6 * (t246 + t273); + + t276 = t185 * t135; + t280 = my_piecewise5(t10, 0, t14, 0, 0.2e1 * t191); + t284 = my_piecewise3(t20, 0, 0.4e1 / 0.9e1 * t276 * t86 + 0.4e1 / 0.3e1 * t23 * t280); + t285 = t284 * t26; + t289 = t138 * t95; + t291 = t5 * t289 * t48; + t294 = t5 * t139 * t100; + t300 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t285 * t48 - t291 / 0.8e1 + t294 * t111 / 0.24e2 - t205 / 0.8e1 + t216 + t219 / 0.72e2); + t301 = t248 * t146; + t305 = my_piecewise5(t14, 0, t10, 0, 0.2e1 * t252); + t309 = my_piecewise3(t58, 0, 0.4e1 / 0.9e1 * t301 * t118 + 0.4e1 / 0.3e1 * t59 * t305); + t310 = t309 * t26; + t314 = t149 * t95; + t316 = t5 * t314 * t77; + t320 = t5 * t122 * t100; + t324 = t5 * t126 * t100; + t325 = t324 * t164; + t328 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t310 * t77 - t316 / 0.8e1 - t266 / 0.8e1 + t271 + t320 * t164 / 0.24e2 + t325 / 0.72e2); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rho2[1] = t115 + t131 + t144 + t168 + t6 * (t300 + t328); + + t333 = t135 * t135; + t338 = my_piecewise5(t10, 0, t14, 0, 0.2e1 * t83 + 0.2e1 * t191); + t342 = my_piecewise3(t20, 0, 0.4e1 / 0.9e1 * t185 * t333 + 0.4e1 / 0.3e1 * t23 * t338); + t343 = t342 * t26; + t349 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t343 * t48 - t291 / 0.4e1 + t216); + t350 = t146 * t146; + t355 = my_piecewise5(t14, 0, t10, 0, -0.2e1 * t83 + 0.2e1 * t252); + t359 = my_piecewise3(t58, 0, 0.4e1 / 0.9e1 * t248 * t350 + 0.4e1 / 0.3e1 * t59 * t355); + t360 = t359 * t26; + t366 = t5 * t150 * t100; + t372 = 0.1e1 / t156 / t72 * t223; + t373 = t372 * t225; + t374 = my_sigma[2] * my_sigma[2]; + t375 = t228 * t374; + t376 = t64 * t64; + t379 = 0.1e1 / t65 / t376 / t160; + t381 = t373 * t375 * t379; + t385 = 0.1e1 / t66 / t376; + t387 = t159 * t63 * t385; + t391 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t360 * t77 - t316 / 0.4e1 + t366 * t164 / 0.12e2 + t271 + t325 / 0.36e2 + t155 * t381 / 0.108e3 - 0.11e2 / 0.72e2 * t155 * t387); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rho2[2] = 0.2e1 * t144 + 0.2e1 * t168 + t6 * (t349 + t391); + + t397 = t218 * t173 / 0.192e3; + t398 = t231 * t35; + t400 = 0.1e1 / t36 / t398; + t403 = t226 * t228 * t400 * my_sigma[0]; + t407 = t105 * t171 * t109; + t411 = my_piecewise3(t1, 0, -t208 * t173 / 0.64e2 - t397 - t102 * t403 / 0.288e3 + t102 * t407 / 0.24e2); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rhosigma[0] = t6 * t411 + t176; + + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rhosigma[1] = 0.0e0; + + t416 = t324 * t178 / 0.192e3; + t418 = my_piecewise3(t53, 0, -t320 * t178 / 0.64e2 - t416); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rhosigma[2] = t6 * t418 + t181; + + t423 = my_piecewise3(t1, 0, -t294 * t173 / 0.64e2 - t397); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rhosigma[3] = t6 * t423 + t176; + + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rhosigma[4] = 0.0e0; + + t427 = t376 * t64; + t429 = 0.1e1 / t65 / t427; + t432 = t373 * t228 * t429 * my_sigma[2]; + t436 = t158 * t171 * t162; + t440 = my_piecewise3(t53, 0, -t366 * t178 / 0.64e2 - t416 - t155 * t432 / 0.288e3 + t155 * t436 / 0.24e2); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2rhosigma[5] = t6 * t440 + t181; + + t442 = t225 * t228; + t443 = t231 * my_rho[0]; + t447 = t224 * t442 / t36 / t443; + t450 = my_piecewise3(t1, 0, t102 * t447 / 0.768e3); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2sigma2[0] = t6 * t450; + + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2sigma2[1] = 0.0e0; + + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2sigma2[2] = 0.0e0; + + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2sigma2[3] = 0.0e0; + + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2sigma2[4] = 0.0e0; + + t451 = t376 * my_rho[1]; + t455 = t372 * t442 / t65 / t451; + t458 = my_piecewise3(t53, 0, t155 * t455 / 0.768e3); + if(iv2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + iv2sigma2[5] = t6 * t458; + +#ifndef XC_DONT_COMPILE_KXC + + if(order < 3) return; + + + t462 = 0.1e1 / t37 / t443; + t464 = t106 * t34 * t462; + t467 = t218 * t242; + t469 = t231 * t231; + t471 = 0.1e1 / t36 / t469; + t473 = t226 * t230 * t471; + t478 = t218 * t236; + t481 = t5 * t199 * t100; + t485 = t5 * t203 * t100; + t486 = t485 * t111; + t491 = t5 * t213 * t100; + t492 = t491 * t111; + t494 = t198 * t95; + t496 = t5 * t494 * t48; + t498 = t89 * t212; + t500 = t5 * t498 * t48; + t503 = 0.1e1 / t94 / t82; + t504 = t25 * t503; + t507 = 0.5e1 / 0.36e2 * t5 * t504 * t48; + t509 = 0.1e1 / t184 / t19; + t510 = t186 * t86; + t513 = t185 * t86; + t516 = t82 * t82; + t517 = 0.1e1 / t516; + t518 = t16 * t517; + t521 = my_piecewise5(t10, 0, t14, 0, 0.6e1 * t190 - 0.6e1 * t518); + t525 = my_piecewise3(t20, 0, -0.8e1 / 0.27e2 * t509 * t510 + 0.4e1 / 0.3e1 * t513 * t194 + 0.4e1 / 0.3e1 * t23 * t521); + t526 = t525 * t26; + t530 = t30 * t30; + t533 = t2 / t3 / t530; + t534 = t533 * t27; + t535 = t103 * t103; + t537 = t100 / t535; + t538 = t223 * mu; + t539 = t229 * my_sigma[0]; + t540 = t538 * t539; + t541 = t469 * t107; + t542 = 0.1e1 / t541; + t544 = t537 * t540 * t542; + t547 = 0.77e2 / 0.108e3 * t102 * t464 - 0.11e2 / 0.72e2 * t467 - 0.11e2 / 0.108e3 * t102 * t473 - 0.11e2 / 0.24e2 * t208 * t242 + t478 / 0.108e3 + t481 * t111 / 0.8e1 + t486 / 0.12e2 + t208 * t236 / 0.36e2 - t492 / 0.36e2 - 0.3e1 / 0.8e1 * t496 + t500 / 0.4e1 - t507 - 0.3e1 / 0.8e1 * t5 * t526 * t48 + t534 * t544 / 0.54e2; + t548 = my_piecewise3(t1, 0, t547); + t550 = 0.1e1 / t247 / t57; + t551 = t249 * t118; + t554 = t248 * t118; + t557 = t54 * t517; + t560 = my_piecewise5(t14, 0, t10, 0, -0.6e1 * t190 - 0.6e1 * t557); + t564 = my_piecewise3(t58, 0, -0.8e1 / 0.27e2 * t550 * t551 + 0.4e1 / 0.3e1 * t554 * t255 + 0.4e1 / 0.3e1 * t59 * t560); + t565 = t564 * t26; + t569 = t259 * t95; + t571 = t5 * t569 * t77; + t573 = t121 * t212; + t575 = t5 * t573 * t77; + t577 = t61 * t503; + t580 = 0.5e1 / 0.36e2 * t5 * t577 * t77; + t582 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t565 * t77 - 0.3e1 / 0.8e1 * t571 + t575 / 0.4e1 - t580); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho3[0] = 0.3e1 * t246 + 0.3e1 * t273 + t6 * (t548 + t582); + + t585 = 0.2e1 * t300; + t586 = 0.2e1 * t328; + t587 = t509 * t135; + t590 = t185 * t280; + t595 = 0.2e1 * t190; + t596 = 0.6e1 * t518; + t598 = my_piecewise5(t10, 0, t14, 0, t595 - t596); + t602 = my_piecewise3(t20, 0, -0.8e1 / 0.27e2 * t587 * t186 + 0.8e1 / 0.9e1 * t590 * t86 + 0.4e1 / 0.9e1 * t276 * t194 + 0.4e1 / 0.3e1 * t23 * t598); + t603 = t602 * t26; + t607 = t284 * t95; + t610 = t5 * t607 * t48 / 0.4e1; + t612 = t5 * t285 * t100; + t615 = t138 * t212; + t617 = t5 * t615 * t48; + t620 = t5 * t289 * t100; + t622 = t620 * t111 / 0.36e2; + t633 = -0.3e1 / 0.8e1 * t5 * t603 * t48 - t610 + t612 * t111 / 0.12e2 + t617 / 0.12e2 + t622 + t294 * t236 / 0.108e3 - 0.11e2 / 0.72e2 * t294 * t242 - t496 / 0.8e1 + t500 / 0.6e1 + t486 / 0.36e2 - t507 - t492 / 0.54e2 + t478 / 0.324e3 - 0.11e2 / 0.216e3 * t467; + t634 = my_piecewise3(t1, 0, t633); + t635 = t550 * t146; + t638 = t248 * t305; + t643 = 0.6e1 * t557; + t645 = my_piecewise5(t14, 0, t10, 0, -t595 - t643); + t649 = my_piecewise3(t58, 0, -0.8e1 / 0.27e2 * t635 * t249 + 0.8e1 / 0.9e1 * t638 * t118 + 0.4e1 / 0.9e1 * t301 * t255 + 0.4e1 / 0.3e1 * t59 * t645); + t650 = t649 * t26; + t654 = t309 * t95; + t657 = t5 * t654 * t77 / 0.4e1; + t658 = t149 * t212; + t660 = t5 * t658 * t77; + t665 = t5 * t260 * t100; + t669 = t5 * t264 * t100; + t671 = t669 * t164 / 0.36e2; + t673 = t5 * t268 * t100; + t674 = t673 * t164; + t677 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t650 * t77 - t657 + t660 / 0.12e2 - t571 / 0.8e1 + t575 / 0.6e1 - t580 + t665 * t164 / 0.24e2 + t671 - t674 / 0.108e3); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho3[1] = t246 + t273 + t585 + t586 + t6 * (t634 + t677); + + t680 = t509 * t333; + t685 = t185 * t338; + t689 = my_piecewise5(t10, 0, t14, 0, -t595 - t596); + t693 = my_piecewise3(t20, 0, -0.8e1 / 0.27e2 * t680 * t86 + 0.8e1 / 0.9e1 * t276 * t280 + 0.4e1 / 0.9e1 * t685 * t86 + 0.4e1 / 0.3e1 * t23 * t689); + t694 = t693 * t26; + t698 = t342 * t95; + t700 = t5 * t698 * t48; + t703 = t5 * t343 * t100; + t710 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t694 * t48 - t700 / 0.8e1 + t703 * t111 / 0.24e2 - t610 + t617 / 0.6e1 + t622 + t500 / 0.12e2 - t507 - t492 / 0.108e3); + t711 = t550 * t350; + t716 = t248 * t355; + t720 = my_piecewise5(t14, 0, t10, 0, t595 - t643); + t724 = my_piecewise3(t58, 0, -0.8e1 / 0.27e2 * t711 * t118 + 0.8e1 / 0.9e1 * t301 * t305 + 0.4e1 / 0.9e1 * t716 * t118 + 0.4e1 / 0.3e1 * t59 * t720); + t725 = t724 * t26; + t729 = t359 * t95; + t731 = t5 * t729 * t77; + t735 = t5 * t310 * t100; + t739 = t5 * t314 * t100; + t740 = t739 * t164; + t746 = t324 * t381; + t750 = t324 * t387; + t752 = -0.3e1 / 0.8e1 * t5 * t725 * t77 - t731 / 0.8e1 - t657 + t660 / 0.6e1 + t735 * t164 / 0.12e2 + t740 / 0.36e2 + t575 / 0.12e2 - t580 + t671 - t674 / 0.54e2 + t320 * t381 / 0.108e3 + t746 / 0.324e3 - 0.11e2 / 0.72e2 * t320 * t387 - 0.11e2 / 0.216e3 * t750; + t753 = my_piecewise3(t53, 0, t752); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho3[2] = t585 + t586 + t349 + t391 + t6 * (t710 + t753); + + t758 = t333 * t135; + t765 = my_piecewise5(t10, 0, t14, 0, -0.6e1 * t190 - 0.6e1 * t518); + t769 = my_piecewise3(t20, 0, -0.8e1 / 0.27e2 * t509 * t758 + 0.4e1 / 0.3e1 * t276 * t338 + 0.4e1 / 0.3e1 * t23 * t765); + t770 = t769 * t26; + t777 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t770 * t48 - 0.3e1 / 0.8e1 * t700 + t617 / 0.4e1 - t507); + t778 = t350 * t146; + t785 = my_piecewise5(t14, 0, t10, 0, 0.6e1 * t190 - 0.6e1 * t557); + t789 = my_piecewise3(t58, 0, -0.8e1 / 0.27e2 * t550 * t778 + 0.4e1 / 0.3e1 * t301 * t355 + 0.4e1 / 0.3e1 * t59 * t785); + t790 = t789 * t26; + t794 = t376 * t376; + t796 = 0.1e1 / t65 / t794; + t798 = t373 * t375 * t796; + t802 = 0.1e1 / t66 / t451; + t804 = t159 * t63 * t802; + t816 = t5 * t360 * t100; + t821 = t533 * t62; + t822 = t156 * t156; + t824 = t100 / t822; + t825 = t374 * my_sigma[2]; + t826 = t538 * t825; + t827 = t794 * t160; + t828 = 0.1e1 / t827; + t830 = t824 * t826 * t828; + t833 = -0.3e1 / 0.8e1 * t5 * t790 * t77 - 0.11e2 / 0.108e3 * t155 * t798 + 0.77e2 / 0.108e3 * t155 * t804 - 0.11e2 / 0.24e2 * t366 * t387 + t746 / 0.108e3 - 0.11e2 / 0.72e2 * t750 - t674 / 0.36e2 + t740 / 0.12e2 + t366 * t381 / 0.36e2 + t816 * t164 / 0.8e1 + t660 / 0.4e1 - 0.3e1 / 0.8e1 * t731 - t580 + t821 * t830 / 0.54e2; + t834 = my_piecewise3(t53, 0, t833); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho3[3] = 0.3e1 * t349 + 0.3e1 * t391 + t6 * (t777 + t834); + + t840 = t485 * t173; + t847 = t491 * t173 / 0.288e3; + t848 = t218 * t403; + t850 = t218 * t407; + t852 = t469 * t35; + t854 = t538 / t852; + t856 = t537 * t854 * t229; + t861 = t226 * t228 * t234 * my_sigma[0]; + t865 = t105 * t171 * t240; + t869 = my_piecewise3(t1, 0, -t481 * t173 / 0.64e2 - t840 / 0.96e2 - t208 * t403 / 0.144e3 + t208 * t407 / 0.12e2 + t847 - t848 / 0.432e3 + t850 / 0.36e2 - t534 * t856 / 0.144e3 + t102 * t861 / 0.32e2 - 0.11e2 / 0.72e2 * t102 * t865); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[0] = t6 * t869 + 0.2e1 * t411; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[1] = 0.0e0; + + t874 = t669 * t178; + t877 = t673 * t178 / 0.288e3; + t879 = my_piecewise3(t53, 0, -t665 * t178 / 0.64e2 - t874 / 0.96e2 + t877); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[2] = t6 * t879 + 0.2e1 * t418; + + t883 = t620 * t173; + t893 = my_piecewise3(t1, 0, -t612 * t173 / 0.64e2 - t883 / 0.192e3 - t294 * t403 / 0.288e3 + t294 * t407 / 0.24e2 - t840 / 0.192e3 + t847 - t848 / 0.864e3 + t850 / 0.72e2); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[3] = t6 * t893 + t411 + t423; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[4] = 0.0e0; + + t897 = t739 * t178; + t902 = t324 * t432; + t906 = t324 * t436; + t909 = my_piecewise3(t53, 0, -t735 * t178 / 0.64e2 - t897 / 0.192e3 - t874 / 0.192e3 + t877 - t320 * t432 / 0.288e3 - t902 / 0.864e3 + t320 * t436 / 0.24e2 + t906 / 0.72e2); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[5] = t6 * t909 + t418 + t440; + + t916 = my_piecewise3(t1, 0, -t703 * t173 / 0.64e2 - t883 / 0.96e2 + t847); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[6] = t6 * t916 + 0.2e1 * t423; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[7] = 0.0e0; + + t928 = t794 * t64; + t930 = t538 / t928; + t932 = t824 * t930 * t374; + t937 = t373 * t228 * t379 * my_sigma[2]; + t941 = t158 * t171 * t385; + t945 = my_piecewise3(t53, 0, -t816 * t178 / 0.64e2 - t897 / 0.96e2 - t366 * t432 / 0.144e3 + t366 * t436 / 0.12e2 + t877 - t902 / 0.432e3 + t906 / 0.36e2 - t821 * t932 / 0.144e3 + t155 * t937 / 0.32e2 - 0.11e2 / 0.72e2 * t155 * t941); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rho2sigma[8] = t6 * t945 + 0.2e1 * t440; + + t950 = t218 * t447 / 0.2304e4; + t951 = t469 * my_rho[0]; + t953 = t538 / t951; + t955 = t537 * t953 * my_sigma[0]; + t959 = t224 * t442 * t400; + t963 = my_piecewise3(t1, 0, t208 * t447 / 0.768e3 + t950 + t534 * t955 / 0.384e3 - t102 * t959 / 0.144e3); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[0] = t6 * t963 + t450; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[1] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[2] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[3] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[4] = 0.0e0; + + t968 = t324 * t455 / 0.2304e4; + t970 = my_piecewise3(t53, 0, t320 * t455 / 0.768e3 + t968); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[5] = t6 * t970 + t458; + + t975 = my_piecewise3(t1, 0, t294 * t447 / 0.768e3 + t950); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[6] = t6 * t975 + t450; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[7] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[8] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[9] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[10] = 0.0e0; + + t979 = t794 * my_rho[1]; + t981 = t538 / t979; + t983 = t824 * t981 * my_sigma[2]; + t987 = t372 * t442 * t429; + t991 = my_piecewise3(t53, 0, t366 * t455 / 0.768e3 + t968 + t821 * t983 / 0.384e3 - t155 * t987 / 0.144e3); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3rhosigma2[11] = t6 * t991 + t458; + + t995 = t537 * t538 / t469; + t998 = my_piecewise3(t1, 0, -t534 * t995 / 0.1024e4); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[0] = t6 * t998; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[1] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[2] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[3] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[4] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[5] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[6] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[7] = 0.0e0; + + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[8] = 0.0e0; + + t1001 = t824 * t538 / t794; + t1004 = my_piecewise3(t53, 0, -t821 * t1001 / 0.1024e4); + if(iv3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + iv3sigma3[9] = t6 * t1004; + +#ifndef XC_DONT_COMPILE_LXC + + if(order < 4) return; + + + t1009 = t5 * t198 * t212 * t48; + t1013 = t5 * t89 * t503 * t48; + t1016 = 0.1e1 / t94 / t189; + t1020 = 0.10e2 / 0.27e2 * t5 * t25 * t1016 * t48; + t1023 = t5 * t525 * t95 * t48; + t1025 = t19 * t19; + t1027 = 0.1e1 / t184 / t1025; + t1028 = t186 * t186; + t1034 = t194 * t194; + t1040 = 0.1e1 / t516 / t6; + t1041 = t16 * t1040; + t1044 = my_piecewise5(t10, 0, t14, 0, -0.24e2 * t517 + 0.24e2 * t1041); + t1048 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t1028 - 0.16e2 / 0.9e1 * t509 * t186 * t194 + 0.4e1 / 0.3e1 * t185 * t1034 + 0.16e2 / 0.9e1 * t513 * t521 + 0.4e1 / 0.3e1 * t23 * t1044); + t1053 = t469 * t231; + t1059 = t533 * t96; + t1060 = t1059 * t544; + t1062 = t533 * t90; + t1066 = t5 * t504 * t100; + t1067 = t1066 * t111; + t1070 = t5 * t498 * t100; + t1071 = t1070 * t111; + t1073 = t491 * t236; + t1076 = t5 * t494 * t100; + t1077 = t1076 * t111; + t1079 = t1009 / 0.2e1 - 0.5e1 / 0.9e1 * t1013 + t1020 - t1023 / 0.2e1 - 0.3e1 / 0.8e1 * t5 * t1048 * t26 * t48 - 0.11e2 / 0.27e2 * t534 * t537 * t540 / t1053 + 0.2e1 / 0.81e2 * t1060 + 0.2e1 / 0.27e2 * t1062 * t544 + 0.5e1 / 0.81e2 * t1067 - t1071 / 0.9e1 - t1073 / 0.81e2 + t1077 / 0.6e1; + t1086 = t491 * t242; + t1088 = t218 * t464; + t1090 = t533 * t101; + t1093 = t223 * t223; + t1094 = 0.1e1 / t535 / t43 * t1093; + t1095 = t229 * t229; + t1109 = t485 * t236; + t1112 = t5 * t526 * t100; + t1125 = t485 * t242; + t1127 = t218 * t473; + t1129 = -0.1309e4 / 0.324e3 * t102 * t106 * t34 / t37 / t398 + 0.11e2 / 0.54e2 * t1086 + 0.77e2 / 0.81e2 * t1088 + 0.2e1 / 0.243e3 * t1090 * t1094 * t1095 / t37 / t469 / t398 * t28 * t33 - 0.11e2 / 0.27e2 * t208 * t473 - 0.11e2 / 0.12e2 * t481 * t242 + t1109 / 0.27e2 + t1112 * t111 / 0.6e1 + t481 * t236 / 0.18e2 + 0.77e2 / 0.27e2 * t208 * t464 + 0.979e3 / 0.972e3 * t102 * t226 * t230 / t36 / t951 - 0.11e2 / 0.18e2 * t1125 - 0.11e2 / 0.81e2 * t1127; + t1131 = my_piecewise3(t1, 0, t1079 + t1129); + t1132 = t57 * t57; + t1134 = 0.1e1 / t247 / t1132; + t1135 = t249 * t249; + t1141 = t255 * t255; + t1146 = t54 * t1040; + t1149 = my_piecewise5(t14, 0, t10, 0, 0.24e2 * t517 + 0.24e2 * t1146); + t1153 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t1135 - 0.16e2 / 0.9e1 * t550 * t249 * t255 + 0.4e1 / 0.3e1 * t248 * t1141 + 0.16e2 / 0.9e1 * t554 * t560 + 0.4e1 / 0.3e1 * t59 * t1149); + t1160 = t5 * t564 * t95 * t77; + t1164 = t5 * t259 * t212 * t77; + t1168 = t5 * t121 * t503 * t77; + t1173 = 0.10e2 / 0.27e2 * t5 * t61 * t1016 * t77; + t1175 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t1153 * t26 * t77 - t1160 / 0.2e1 + t1164 / 0.2e1 - 0.5e1 / 0.9e1 * t1168 + t1173); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho4[0] = 0.4e1 * t548 + 0.4e1 * t582 + t6 * (t1131 + t1175); + + t1182 = t5 * t602 * t95 * t48; + t1186 = t5 * t284 * t212 * t48; + t1187 = t1186 / 0.4e1; + t1190 = t5 * t138 * t503 * t48; + t1208 = 0.12e2 * t517; + t1209 = 0.24e2 * t1041; + t1211 = my_piecewise5(t10, 0, t14, 0, -t1208 + t1209); + t1215 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t135 * t510 - 0.8e1 / 0.9e1 * t509 * t280 * t186 - 0.8e1 / 0.9e1 * t587 * t86 * t194 + 0.4e1 / 0.3e1 * t185 * t598 * t86 + 0.4e1 / 0.3e1 * t590 * t194 + 0.4e1 / 0.9e1 * t276 * t521 + 0.4e1 / 0.3e1 * t23 * t1211); + t1224 = t533 * t139; + t1227 = t620 * t242; + t1230 = t5 * t603 * t100; + t1234 = t5 * t607 * t100; + t1235 = t1234 * t111; + t1239 = -0.3e1 / 0.8e1 * t1182 + t1187 - 0.5e1 / 0.36e2 * t1190 - 0.3e1 / 0.8e1 * t5 * t1215 * t26 * t48 + t1009 / 0.4e1 - 0.5e1 / 0.12e2 * t1013 + t1020 - t1023 / 0.8e1 + t1060 / 0.162e3 + t1224 * t544 / 0.54e2 - 0.11e2 / 0.72e2 * t1227 + t1230 * t111 / 0.8e1 + t1235 / 0.12e2 + t612 * t236 / 0.36e2; + t1241 = t5 * t615 * t100; + t1242 = t1241 * t111; + t1243 = t1242 / 0.36e2; + t1253 = t620 * t236; + t1261 = -t1243 + 0.5e1 / 0.108e3 * t1067 - t1071 / 0.18e2 - t1073 / 0.162e3 + t1077 / 0.24e2 + 0.11e2 / 0.108e3 * t1086 + 0.77e2 / 0.324e3 * t1088 + t1109 / 0.108e3 - 0.11e2 / 0.72e2 * t1125 - 0.11e2 / 0.324e3 * t1127 + t1253 / 0.108e3 - 0.11e2 / 0.108e3 * t294 * t473 + 0.77e2 / 0.108e3 * t294 * t464 - 0.11e2 / 0.24e2 * t612 * t242; + t1263 = my_piecewise3(t1, 0, t1239 + t1261); + t1280 = 0.24e2 * t1146; + t1282 = my_piecewise5(t14, 0, t10, 0, t1208 + t1280); + t1286 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t146 * t551 - 0.8e1 / 0.9e1 * t550 * t305 * t249 - 0.8e1 / 0.9e1 * t635 * t118 * t255 + 0.4e1 / 0.3e1 * t248 * t645 * t118 + 0.4e1 / 0.3e1 * t638 * t255 + 0.4e1 / 0.9e1 * t301 * t560 + 0.4e1 / 0.3e1 * t59 * t1282); + t1293 = t5 * t649 * t95 * t77; + t1297 = t5 * t309 * t212 * t77; + t1298 = t1297 / 0.4e1; + t1301 = t5 * t149 * t503 * t77; + t1307 = t5 * t565 * t100; + t1311 = t5 * t569 * t100; + t1312 = t1311 * t164; + t1315 = t5 * t573 * t100; + t1316 = t1315 * t164; + t1317 = t1316 / 0.36e2; + t1319 = t5 * t577 * t100; + t1320 = t1319 * t164; + t1322 = -0.3e1 / 0.8e1 * t5 * t1286 * t26 * t77 - 0.3e1 / 0.8e1 * t1293 + t1298 - 0.5e1 / 0.36e2 * t1301 - t1160 / 0.8e1 + t1164 / 0.4e1 - 0.5e1 / 0.12e2 * t1168 + t1173 + t1307 * t164 / 0.24e2 + t1312 / 0.24e2 - t1317 + 0.5e1 / 0.324e3 * t1320; + t1323 = my_piecewise3(t53, 0, t1322); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho4[1] = t548 + t582 + 0.3e1 * t634 + 0.3e1 * t677 + t6 * (t1263 + t1323); + + t1331 = t5 * t694 * t100; + t1335 = t5 * t698 * t100; + t1336 = t1335 * t111; + t1343 = t5 * t693 * t95 * t48; + t1347 = t5 * t342 * t212 * t48; + t1363 = t280 * t280; + t1376 = my_piecewise5(t10, 0, t14, 0, t1209); + t1380 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t333 * t186 - 0.32e2 / 0.27e2 * t587 * t86 * t280 - 0.8e1 / 0.27e2 * t680 * t194 + 0.8e1 / 0.9e1 * t185 * t1363 + 0.8e1 / 0.9e1 * t276 * t598 - 0.8e1 / 0.27e2 * t509 * t338 * t186 + 0.8e1 / 0.9e1 * t185 * t689 * t86 + 0.4e1 / 0.9e1 * t685 * t194 + 0.4e1 / 0.3e1 * t23 * t1376); + t1394 = -0.5e1 / 0.18e2 * t1013 + t1020 - 0.3e1 / 0.8e1 * t5 * t1380 * t26 * t48 - 0.11e2 / 0.72e2 * t703 * t242 - 0.11e2 / 0.108e3 * t1227 + 0.5e1 / 0.162e3 * t1067 - t1071 / 0.54e2 - t1073 / 0.486e3 + 0.11e2 / 0.324e3 * t1086 + t1235 / 0.18e2 - t1242 / 0.27e2; + t1396 = my_piecewise3(t1, 0, t1331 * t111 / 0.12e2 + t1336 / 0.36e2 + t703 * t236 / 0.108e3 + t1253 / 0.162e3 - t1343 / 0.4e1 + t1347 / 0.12e2 - t1182 / 0.4e1 + t1186 / 0.3e1 - 0.5e1 / 0.18e2 * t1190 + t1009 / 0.12e2 + t1394); + t1402 = t5 * t650 * t100; + t1408 = t5 * t724 * t95 * t77; + t1412 = t5 * t359 * t212 * t77; + t1427 = t305 * t305; + t1440 = my_piecewise5(t14, 0, t10, 0, t1280); + t1444 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t350 * t249 - 0.32e2 / 0.27e2 * t635 * t118 * t305 - 0.8e1 / 0.27e2 * t711 * t255 + 0.8e1 / 0.9e1 * t248 * t1427 + 0.8e1 / 0.9e1 * t301 * t645 - 0.8e1 / 0.27e2 * t550 * t355 * t249 + 0.8e1 / 0.9e1 * t248 * t720 * t118 + 0.4e1 / 0.9e1 * t716 * t255 + 0.4e1 / 0.3e1 * t59 * t1440); + t1449 = t669 * t387; + t1451 = t673 * t387; + t1453 = t669 * t381; + t1455 = t673 * t381; + t1458 = t5 * t654 * t100; + t1459 = t1458 * t164; + t1462 = t5 * t658 * t100; + t1463 = t1462 * t164; + t1468 = t1164 / 0.12e2 - 0.3e1 / 0.8e1 * t5 * t1444 * t26 * t77 - 0.11e2 / 0.108e3 * t1449 + 0.11e2 / 0.324e3 * t1451 + t1453 / 0.162e3 - t1455 / 0.486e3 + t1459 / 0.18e2 - t1463 / 0.54e2 - t1316 / 0.27e2 + 0.5e1 / 0.162e3 * t1320 + t1312 / 0.36e2; + t1470 = my_piecewise3(t53, 0, t665 * t381 / 0.108e3 - 0.11e2 / 0.72e2 * t665 * t387 + t1402 * t164 / 0.12e2 - 0.5e1 / 0.18e2 * t1301 - t1408 / 0.4e1 + t1412 / 0.12e2 - 0.5e1 / 0.18e2 * t1168 + t1173 - t1293 / 0.4e1 + t1297 / 0.3e1 + t1468); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho4[2] = 0.2e1 * t634 + 0.2e1 * t677 + 0.2e1 * t710 + 0.2e1 * t753 + t6 * (t1396 + t1470); + + t1491 = my_piecewise5(t10, 0, t14, 0, t1208 + t1209); + t1495 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t758 * t86 - 0.8e1 / 0.9e1 * t680 * t280 - 0.8e1 / 0.9e1 * t587 * t338 * t86 + 0.4e1 / 0.3e1 * t590 * t338 + 0.4e1 / 0.3e1 * t276 * t689 + 0.4e1 / 0.9e1 * t185 * t765 * t86 + 0.4e1 / 0.3e1 * t23 * t1491); + t1502 = t5 * t769 * t95 * t48; + t1505 = t5 * t770 * t100; + t1514 = -0.3e1 / 0.8e1 * t5 * t1495 * t26 * t48 - t1502 / 0.8e1 + t1505 * t111 / 0.24e2 - 0.3e1 / 0.8e1 * t1343 + t1347 / 0.4e1 + t1336 / 0.24e2 + t1187 - 0.5e1 / 0.12e2 * t1190 - t1243 - 0.5e1 / 0.36e2 * t1013 + t1020 + 0.5e1 / 0.324e3 * t1067; + t1515 = my_piecewise3(t1, 0, t1514); + t1518 = t5 * t789 * t95 * t77; + t1536 = my_piecewise5(t14, 0, t10, 0, -t1208 + t1280); + t1540 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t778 * t118 - 0.8e1 / 0.9e1 * t711 * t305 - 0.8e1 / 0.9e1 * t635 * t355 * t118 + 0.4e1 / 0.3e1 * t638 * t355 + 0.4e1 / 0.3e1 * t301 * t720 + 0.4e1 / 0.9e1 * t248 * t785 * t118 + 0.4e1 / 0.3e1 * t59 * t1536); + t1549 = t533 * t126; + t1550 = t1549 * t830; + t1552 = t533 * t122; + t1560 = t5 * t725 * t100; + t1565 = -t1518 / 0.8e1 - 0.3e1 / 0.8e1 * t5 * t1540 * t26 * t77 - 0.3e1 / 0.8e1 * t1408 + t1412 / 0.4e1 + t1298 - 0.5e1 / 0.12e2 * t1301 - 0.5e1 / 0.36e2 * t1168 + t1173 + t1550 / 0.162e3 + t1552 * t830 / 0.54e2 - 0.11e2 / 0.24e2 * t735 * t387 + t735 * t381 / 0.36e2 + t1560 * t164 / 0.8e1 - 0.11e2 / 0.108e3 * t320 * t798; + t1568 = t739 * t387; + t1570 = t739 * t381; + t1573 = t5 * t729 * t100; + t1574 = t1573 * t164; + t1576 = t324 * t798; + t1578 = t324 * t804; + t1587 = 0.77e2 / 0.108e3 * t320 * t804 - 0.11e2 / 0.72e2 * t1568 + t1570 / 0.108e3 + t1574 / 0.24e2 - 0.11e2 / 0.324e3 * t1576 + 0.77e2 / 0.324e3 * t1578 - 0.11e2 / 0.72e2 * t1449 + 0.11e2 / 0.108e3 * t1451 + t1453 / 0.108e3 - t1455 / 0.162e3 + t1459 / 0.12e2 - t1463 / 0.18e2 - t1317 + 0.5e1 / 0.108e3 * t1320; + t1589 = my_piecewise3(t53, 0, t1565 + t1587); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho4[3] = 0.3e1 * t710 + 0.3e1 * t753 + t777 + t834 + t6 * (t1515 + t1589); + + t1594 = t333 * t333; + t1599 = t338 * t338; + t1606 = my_piecewise5(t10, 0, t14, 0, 0.24e2 * t517 + 0.24e2 * t1041); + t1610 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t1594 - 0.16e2 / 0.9e1 * t680 * t338 + 0.4e1 / 0.3e1 * t185 * t1599 + 0.16e2 / 0.9e1 * t276 * t765 + 0.4e1 / 0.3e1 * t23 * t1606); + t1619 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t1610 * t26 * t48 - t1502 / 0.2e1 + t1347 / 0.2e1 - 0.5e1 / 0.9e1 * t1190 + t1020); + t1620 = t350 * t350; + t1625 = t355 * t355; + t1632 = my_piecewise5(t14, 0, t10, 0, -0.24e2 * t517 + 0.24e2 * t1146); + t1636 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t1620 - 0.16e2 / 0.9e1 * t711 * t355 + 0.4e1 / 0.3e1 * t248 * t1625 + 0.16e2 / 0.9e1 * t301 * t785 + 0.4e1 / 0.3e1 * t59 * t1632); + t1645 = t794 * t376; + t1651 = t533 * t150; + t1657 = t5 * t790 * t100; + t1664 = -0.3e1 / 0.8e1 * t5 * t1636 * t26 * t77 - t1518 / 0.2e1 + t1412 / 0.2e1 - 0.5e1 / 0.9e1 * t1301 + t1173 + 0.2e1 / 0.81e2 * t1550 - 0.11e2 / 0.27e2 * t821 * t824 * t826 / t1645 + 0.2e1 / 0.27e2 * t1651 * t830 + t816 * t381 / 0.18e2 + t1657 * t164 / 0.6e1 - 0.11e2 / 0.27e2 * t366 * t798 + 0.77e2 / 0.27e2 * t366 * t804; + t1684 = t533 * t154; + t1687 = 0.1e1 / t822 / t72 * t1093; + t1688 = t374 * t374; + t1702 = -0.11e2 / 0.12e2 * t816 * t387 + 0.979e3 / 0.972e3 * t155 * t373 * t375 / t65 / t979 - 0.11e2 / 0.18e2 * t1568 + t1570 / 0.27e2 + t1574 / 0.6e1 - 0.11e2 / 0.81e2 * t1576 + 0.77e2 / 0.81e2 * t1578 - 0.1309e4 / 0.324e3 * t155 * t159 * t63 / t66 / t427 + 0.2e1 / 0.243e3 * t1684 * t1687 * t1688 / t66 / t794 / t427 * t28 * t33 + 0.11e2 / 0.54e2 * t1451 - t1455 / 0.81e2 - t1463 / 0.9e1 + 0.5e1 / 0.81e2 * t1320; + t1704 = my_piecewise3(t53, 0, t1664 + t1702); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho4[4] = 0.4e1 * t777 + 0.4e1 * t834 + t6 * (t1619 + t1704); + + t1715 = t218 * t861; + t1731 = 0.5e1 / 0.864e3 * t1066 * t173; + t1732 = t491 * t407; + t1734 = t491 * t403; + t1736 = t218 * t865; + t1738 = t1070 * t173; + t1740 = t485 * t407; + t1742 = t485 * t403; + t1746 = t1076 * t173; + t1761 = t1059 * t856; + t1763 = -0.341e3 / 0.1296e4 * t102 * t226 * t228 * t471 * my_sigma[0] + 0.3e1 / 0.32e2 * t208 * t861 + t1715 / 0.32e2 - t1090 * t1094 / t37 / t469 / t443 * t539 * t28 * t33 / 0.324e3 + 0.77e2 / 0.108e3 * t102 * t105 * t171 * t462 - t1731 - t1732 / 0.36e2 + t1734 / 0.432e3 - 0.11e2 / 0.72e2 * t1736 + t1738 / 0.96e2 + t1740 / 0.12e2 - t1742 / 0.144e3 - 0.11e2 / 0.24e2 * t208 * t865 - t1746 / 0.64e2 + t481 * t407 / 0.8e1 - t481 * t403 / 0.96e2 + 0.19e2 / 0.144e3 * t534 * t537 * t538 * t542 * t229 - t1112 * t173 / 0.64e2 - t1062 * t856 / 0.48e2 - t1761 / 0.144e3; + t1764 = my_piecewise3(t1, 0, t1763); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[0] = t6 * t1764 + 0.3e1 * t869; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[1] = 0.0e0; + + t1769 = t1311 * t178; + t1771 = t1315 * t178; + t1774 = 0.5e1 / 0.864e3 * t1319 * t178; + t1776 = my_piecewise3(t53, 0, -t1307 * t178 / 0.64e2 - t1769 / 0.64e2 + t1771 / 0.96e2 - t1774); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[2] = t6 * t1776 + 0.3e1 * t879; + + t1778 = 0.2e1 * t893; + t1785 = t1234 * t173 / 0.96e2; + t1790 = t1241 * t173; + t1793 = t620 * t407 / 0.36e2; + t1795 = t620 * t403 / 0.432e3; + t1808 = t294 * t861 / 0.32e2 + t1715 / 0.96e2 - 0.11e2 / 0.72e2 * t294 * t865 - t1785 + t612 * t407 / 0.12e2 - t612 * t403 / 0.144e3 + t1790 / 0.288e3 + t1793 - t1795 - t1731 - t1732 / 0.54e2 + t1734 / 0.648e3 - 0.11e2 / 0.216e3 * t1736 + t1738 / 0.144e3 + t1740 / 0.36e2 - t1742 / 0.432e3 - t1746 / 0.192e3 - t1230 * t173 / 0.64e2 - t1761 / 0.432e3 - t1224 * t856 / 0.144e3; + t1809 = my_piecewise3(t1, 0, t1808); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[3] = t6 * t1809 + t1778 + t869; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[4] = 0.0e0; + + t1811 = 0.2e1 * t909; + t1815 = t1458 * t178 / 0.96e2; + t1816 = t1462 * t178; + t1823 = t669 * t432 / 0.432e3; + t1824 = t673 * t432; + t1829 = t669 * t436 / 0.36e2; + t1830 = t673 * t436; + t1832 = -t1402 * t178 / 0.64e2 - t1815 + t1816 / 0.288e3 - t1769 / 0.192e3 + t1771 / 0.144e3 - t1774 - t665 * t432 / 0.288e3 - t1823 + t1824 / 0.1296e4 + t665 * t436 / 0.24e2 + t1829 - t1830 / 0.108e3; + t1833 = my_piecewise3(t53, 0, t1832); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[5] = t6 * t1833 + t1811 + t879; + + t1837 = t1335 * t173; + t1847 = -t1331 * t173 / 0.64e2 - t1837 / 0.192e3 - t703 * t403 / 0.288e3 + t703 * t407 / 0.24e2 - t1785 + t1790 / 0.144e3 - t1795 + t1793 + t1738 / 0.288e3 - t1731 + t1734 / 0.1296e4 - t1732 / 0.108e3; + t1848 = my_piecewise3(t1, 0, t1847); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[6] = t6 * t1848 + t1778 + t916; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[7] = 0.0e0; + + t1852 = t1573 * t178; + t1857 = t739 * t432; + t1861 = t739 * t436; + t1868 = t1549 * t932; + t1872 = t324 * t937; + t1876 = t324 * t941; + t1878 = -t1560 * t178 / 0.64e2 - t1852 / 0.192e3 - t1815 + t1816 / 0.144e3 - t735 * t432 / 0.144e3 - t1857 / 0.432e3 + t735 * t436 / 0.12e2 + t1861 / 0.36e2 + t1771 / 0.288e3 - t1774 - t1823 + t1824 / 0.648e3 + t1829 - t1830 / 0.54e2 - t1552 * t932 / 0.144e3 - t1868 / 0.432e3 + t320 * t937 / 0.32e2 + t1872 / 0.96e2 - 0.11e2 / 0.72e2 * t320 * t941 - 0.11e2 / 0.216e3 * t1876; + t1879 = my_piecewise3(t53, 0, t1878); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[8] = t6 * t1879 + t1811 + t945; + + t1887 = my_piecewise3(t1, 0, -t1505 * t173 / 0.64e2 - t1837 / 0.64e2 + t1790 / 0.96e2 - t1731); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[9] = t6 * t1887 + 0.3e1 * t916; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[10] = 0.0e0; + + t1934 = -0.341e3 / 0.1296e4 * t155 * t373 * t228 * t796 * my_sigma[2] + 0.3e1 / 0.32e2 * t366 * t937 + t1872 / 0.32e2 - t1857 / 0.144e3 + t1824 / 0.432e3 - t1684 * t1687 / t66 / t794 / t451 * t825 * t28 * t33 / 0.324e3 + 0.77e2 / 0.108e3 * t155 * t158 * t171 * t802 + t816 * t436 / 0.8e1 - t816 * t432 / 0.96e2 - 0.11e2 / 0.24e2 * t366 * t941 - 0.11e2 / 0.72e2 * t1876 - t1852 / 0.64e2 + t1861 / 0.12e2 - t1830 / 0.36e2 + t1816 / 0.96e2 - t1774 + 0.19e2 / 0.144e3 * t821 * t824 * t538 * t828 * t374 - t1657 * t178 / 0.64e2 - t1868 / 0.144e3 - t1651 * t932 / 0.48e2; + t1935 = my_piecewise3(t53, 0, t1934); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho3sigma[11] = t6 * t1935 + 0.3e1 * t945; + + t1940 = t485 * t447; + t1947 = t491 * t447 / 0.3456e4; + t1948 = t1059 * t955; + t1950 = t218 * t959; + t1969 = my_piecewise3(t1, 0, t481 * t447 / 0.768e3 + t1940 / 0.1152e4 + t1062 * t955 / 0.192e3 - t208 * t959 / 0.72e2 - t1947 + t1948 / 0.576e3 - t1950 / 0.216e3 + t1090 * t1094 / t37 / t1053 * t229 * t28 * t33 / 0.864e3 - 0.43e2 / 0.1152e4 * t534 * t537 * t854 * my_sigma[0] + 0.19e2 / 0.432e3 * t102 * t224 * t442 * t234); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[0] = t6 * t1969 + 0.2e1 * t963; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[1] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[2] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[3] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[4] = 0.0e0; + + t1974 = t669 * t455; + t1977 = t673 * t455 / 0.3456e4; + t1979 = my_piecewise3(t53, 0, t665 * t455 / 0.768e3 + t1974 / 0.1152e4 - t1977); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[5] = t6 * t1979 + 0.2e1 * t970; + + t1983 = t620 * t447; + t1993 = my_piecewise3(t1, 0, t612 * t447 / 0.768e3 + t1983 / 0.2304e4 + t1224 * t955 / 0.384e3 - t294 * t959 / 0.144e3 + t1940 / 0.2304e4 - t1947 + t1948 / 0.1152e4 - t1950 / 0.432e3); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[6] = t6 * t1993 + t963 + t975; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[7] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[8] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[9] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[10] = 0.0e0; + + t1997 = t739 * t455; + t2002 = t1549 * t983; + t2006 = t324 * t987; + t2009 = my_piecewise3(t53, 0, t735 * t455 / 0.768e3 + t1997 / 0.2304e4 + t1974 / 0.2304e4 - t1977 + t1552 * t983 / 0.384e3 + t2002 / 0.1152e4 - t320 * t987 / 0.144e3 - t2006 / 0.432e3); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[11] = t6 * t2009 + t970 + t991; + + t2016 = my_piecewise3(t1, 0, t703 * t447 / 0.768e3 + t1983 / 0.1152e4 - t1947); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[12] = t6 * t2016 + 0.2e1 * t975; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[13] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[14] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[15] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[16] = 0.0e0; + + t2045 = my_piecewise3(t53, 0, t816 * t455 / 0.768e3 + t1997 / 0.1152e4 + t1651 * t983 / 0.192e3 - t366 * t987 / 0.72e2 - t1977 + t2002 / 0.576e3 - t2006 / 0.216e3 + t1684 * t1687 / t66 / t1645 * t374 * t28 * t33 / 0.864e3 - 0.43e2 / 0.1152e4 * t821 * t824 * t930 * my_sigma[2] + 0.19e2 / 0.432e3 * t155 * t372 * t442 * t379); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rho2sigma2[17] = t6 * t2045 + 0.2e1 * t991; + + t2050 = t1059 * t995 / 0.3072e4; + t2062 = my_piecewise3(t1, 0, -t1062 * t995 / 0.1024e4 - t2050 - t1090 * t1094 / t37 / t541 * t171 * my_sigma[0] / 0.2304e4 + t534 * t537 * t953 / 0.128e3); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[0] = t6 * t2062 + t998; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[1] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[2] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[3] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[4] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[5] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[6] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[7] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[8] = 0.0e0; + + t2067 = t1549 * t1001 / 0.3072e4; + t2069 = my_piecewise3(t53, 0, -t1552 * t1001 / 0.1024e4 - t2067); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[9] = t6 * t2069 + t1004; + + t2074 = my_piecewise3(t1, 0, -t1224 * t995 / 0.1024e4 - t2050); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[10] = t6 * t2074 + t998; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[11] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[12] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[13] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[14] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[15] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[16] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[17] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[18] = 0.0e0; + + t2089 = my_piecewise3(t53, 0, -t1651 * t1001 / 0.1024e4 - t2067 - t1684 * t1687 / t66 / t827 * t171 * my_sigma[2] / 0.2304e4 + t821 * t824 * t981 / 0.128e3); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4rhosigma3[19] = t6 * t2089 + t1004; + + t2098 = my_piecewise3(t1, 0, t1090 * t1094 / t37 / t852 * t28 * t33 / 0.6144e4); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[0] = t6 * t2098; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[1] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[2] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[3] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[4] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[5] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[6] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[7] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[8] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[9] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[10] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[11] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[12] = 0.0e0; + + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[13] = 0.0e0; + + t2106 = my_piecewise3(t53, 0, t1684 * t1687 / t66 / t928 * t28 * t33 / 0.6144e4); + if(iv4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + iv4sigma4[14] = t6 * t2106; + +#ifndef XC_DONT_COMPILE_MXC + + if(order < 5) return; + + +#endif + +#endif + +#endif + +#endif + +#endif +} diff --git a/ref/genxc/work_gga_genxc.h b/ref/genxc/work_gga_genxc.h new file mode 100644 index 0000000000000000000000000000000000000000..fa62e7fa41d536631fca41ede7ac75f94f5141d8 --- /dev/null +++ b/ref/genxc/work_gga_genxc.h @@ -0,0 +1,168 @@ +/* + Copyright (C) 2006-2018 M.A.L. Marques + Copyright (C) 2019 X. Andrade + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +/** + * @file work_gga.c + * @brief This file is to be included in GGA functionals. + */ + +#ifdef XC_DEBUG +#define __USE_GNU +#include <fenv.h> +#endif +#include <omp.h> + +//#define USE_INTERNAL_COUNTERS + +/** + * @param[in,out] func_type: pointer to functional structure + */ +static void +work_gga_genxc(const XC(func_type) *p, size_t np, +#ifdef USE_INTERNAL_COUNTERS + const double *irho, const double *isigma, double *izk, + double *ivrho, double *ivsigma, double *iv2rho2, double *iv2rhosigma, double *iv2sigma2, + double *iv3rho3, double *iv3rho2sigma, double *iv3rhosigma2, double *iv3sigma3, + double *iv4rho4, double *iv4rho3sigma, double *iv4rho2sigma2, double *iv4rhosigma3, double *iv4sigma4 +#else + const double *rho, const double *sigma, double *zk, + 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 +#endif +) { + + int order = -1; +#ifdef USE_INTERNAL_COUNTERS + if(izk != NULL) order = 0; + if(ivrho != NULL) order = 1; + if(iv2rho2 != NULL) order = 2; + if(iv3rho3 != NULL) order = 3; + if(iv4rho4 != NULL) order = 4; +#else + if(zk != NULL) order = 0; + if(vrho != NULL) order = 1; + if(v2rho2 != NULL) order = 2; + if(v3rho3 != NULL) order = 3; + if(v4rho4 != NULL) order = 4; +#endif + if(order < 0) return; + + size_t ip; + double dens; + double my_rho[2] = {0.0, 0.0}; + double my_sigma[3] = {0.0, 0.0, 0.0}; + + if(p->nspin == XC_POLARIZED) { + #pragma omp parallel for private(ip, my_rho, my_sigma, dens) + for(ip = 0; ip < np; ip++){ + +#ifndef USE_INTERNAL_COUNTERS + const xc_dimensions *dim = &(p->dim); + const int pos = ip; + const double *irho = &rho[pos * dim->rho]; + const double *isigma = &sigma[pos * dim->sigma]; + double *izk = &zk[pos * dim->zk]; + double *ivrho = &vrho[pos * dim->vrho]; + double *ivsigma = &vsigma[pos * dim->vsigma]; + double *iv2rho2 = &v2rho2[pos * dim->v2rho2]; + double *iv2rhosigma = &v2rhosigma[pos * dim->v2rhosigma]; + double *iv2sigma2 = &v2sigma2[pos * dim->v2sigma2]; + double *iv3rho3 = NULL; + double *iv3rho2sigma = NULL; + double *iv3rhosigma2 = NULL; + double *iv3sigma3 = NULL; + if(v3rho3 != NULL) { + iv3rho3 = &v3rho3[pos * dim->v3rho3]; + iv3rho2sigma = &v3rho2sigma[pos * dim->v3rho2sigma]; + iv3rhosigma2 = &v3rhosigma2[pos * dim->v3rhosigma2]; + iv3sigma3 = &v3sigma3[pos * dim->v3sigma3]; + } + double *iv4rho4 = NULL; + double *iv4rho3sigma = NULL; + double *iv4rho2sigma2 = NULL; + double *iv4rhosigma3 = NULL; + double *iv4sigma4 = NULL; + if(v4rho4 != NULL) { + iv4rho4 = &v4rho4[pos * dim->v4rho4]; + iv4rho3sigma = &v4rho3sigma[pos * dim->v4rho3sigma]; + iv4rho2sigma2 = &v4rho2sigma2[pos * dim->v4rho2sigma2]; + iv4rhosigma3 = &v4rhosigma3[pos * dim->v4rhosigma3]; + iv4sigma4 = &v4sigma4[pos * dim->v4sigma4]; + } +#endif // USE_INTERNAL_COUNTERS + + dens = irho[0] + irho[1]; + if(dens >= p->dens_threshold) { + my_rho[0] = m_max(p->dens_threshold, irho[0]); + my_sigma[0] = m_max(p->sigma_threshold * p->sigma_threshold, isigma[0]); + double s_ave; + my_rho[1] = m_max(p->dens_threshold, irho[1]); + my_sigma[2] = m_max(p->sigma_threshold * p->sigma_threshold, isigma[2]); + my_sigma[1] = isigma[1]; + s_ave = 0.5*(my_sigma[0] + my_sigma[2]); + my_sigma[1] = (my_sigma[1] >= -s_ave ? my_sigma[1] : -s_ave); + my_sigma[1] = (my_sigma[1] <= +s_ave ? my_sigma[1] : +s_ave); + func_pol(p, order, my_rho, my_sigma, izk, ivrho, ivsigma, iv2rho2, iv2rhosigma, iv2sigma2, iv3rho3, iv3rho2sigma, iv3rhosigma2, iv3sigma3, iv4rho4, iv4rho3sigma, iv4rho2sigma2, iv4rhosigma3, iv4sigma4); + } +#ifdef USE_INTERNAL_COUNTERS + internal_counters_gga_next(&(p->dim), 0, &irho, &isigma, &izk, &ivrho, &ivsigma, &iv2rho2, &iv2rhosigma, &iv2sigma2, &iv3rho3, &iv3rho2sigma, &iv3rhosigma2, &iv3sigma3, &iv4rho4, &iv4rho3sigma, &iv4rho2sigma2, &iv4rhosigma3, &iv4sigma4); +#endif + } + } else { + #pragma omp parallel for + for(ip = 0; ip < np; ip++){ +#ifndef USE_INTERNAL_COUNTERS + const xc_dimensions *dim = &(p->dim); + const int pos = ip; + const double *irho = &rho[pos * dim->rho]; + const double *isigma = &sigma[pos * dim->sigma]; + double *izk = &zk[pos * dim->zk]; + double *ivrho = &vrho[pos * dim->vrho]; + double *ivsigma = &vsigma[pos * dim->vsigma]; + double *iv2rho2 = &v2rho2[pos * dim->v2rho2]; + double *iv2rhosigma = &v2rhosigma[pos * dim->v2rhosigma]; + double *iv2sigma2 = &v2sigma2[pos * dim->v2sigma2]; + double *iv3rho3 = NULL; + double *iv3rho2sigma = NULL; + double *iv3rhosigma2 = NULL; + double *iv3sigma3 = NULL; + if(v3rho3 != NULL) { + iv3rho3 = &v3rho3[pos * dim->v3rho3]; + iv3rho2sigma = &v3rho2sigma[pos * dim->v3rho2sigma]; + iv3rhosigma2 = &v3rhosigma2[pos * dim->v3rhosigma2]; + iv3sigma3 = &v3sigma3[pos * dim->v3sigma3]; + } + double *iv4rho4 = NULL; + double *iv4rho3sigma = NULL; + double *iv4rho2sigma2 = NULL; + double *iv4rhosigma3 = NULL; + double *iv4sigma4 = NULL; + if(v4rho4 != NULL) { + iv4rho4 = &v4rho4[pos * dim->v4rho4]; + iv4rho3sigma = &v4rho3sigma[pos * dim->v4rho3sigma]; + iv4rho2sigma2 = &v4rho2sigma2[pos * dim->v4rho2sigma2]; + iv4rhosigma3 = &v4rhosigma3[pos * dim->v4rhosigma3]; + iv4sigma4 = &v4sigma4[pos * dim->v4sigma4]; + } +#endif // USE_INTERNAL_COUNTERS + + dens = irho[0]; + if(dens >= p->dens_threshold) { + my_rho[0] = m_max(p->dens_threshold, irho[0]); + my_sigma[0] = m_max(p->sigma_threshold * p->sigma_threshold, isigma[0]); + func_unpol(p, order, my_rho, my_sigma, izk, ivrho, ivsigma, iv2rho2, iv2rhosigma, iv2sigma2, iv3rho3, iv3rho2sigma, iv3rhosigma2, iv3sigma3, iv4rho4, iv4rho3sigma, iv4rho2sigma2, iv4rhosigma3, iv4sigma4); + } + +#ifdef USE_INTERNAL_COUNTERS + internal_counters_gga_next(&(p->dim), 0, &irho, &isigma, &izk, &ivrho, &ivsigma, &iv2rho2, &iv2rhosigma, &iv2sigma2, &iv3rho3, &iv3rho2sigma, &iv3rhosigma2, &iv3sigma3, &iv4rho4, &iv4rho3sigma, &iv4rho2sigma2, &iv4rhosigma3, &iv4sigma4); +#endif + } + } +} diff --git a/ref/libxc/gga_x_pbe.c b/ref/libxc/gga_x_pbe.c new file mode 100644 index 0000000000000000000000000000000000000000..2bc3cac53bae7e0c2a025ac551b8fb69139b07ea --- /dev/null +++ b/ref/libxc/gga_x_pbe.c @@ -0,0 +1,318 @@ +/* + Copyright (C) 2006-2007 M.A.L. Marques + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#include "../common/util.h" +#include "gga_x_pbe.h" + +typedef struct{ + double kappa, mu; + double lambda; /* parameter used in the Odashima & Capelle versions */ +} gga_x_pbe_params; + + +static void +gga_x_pbe_init(xc_func_type *p) +{ + gga_x_pbe_params *params; + + assert(p!=NULL && p->params == NULL); + p->params = libxc_malloc(sizeof(gga_x_pbe_params)); + params = (gga_x_pbe_params *) (p->params); + + /* This has to be explicitly initialized here */ + params->lambda = 0.0; +} + +#define PBE_N_PAR 2 +static const char *pbe_names[PBE_N_PAR] = {"_kappa", "_mu"}; +static const char *pbe_desc[PBE_N_PAR] = { + "Asymptotic value of the enhancement function", + "Coefficient of the 2nd order expansion"}; + +static const double pbe_values[PBE_N_PAR] = + {0.8040, MU_PBE}; +static const double pbe_r_values[PBE_N_PAR] = + {1.245, MU_PBE}; +static const double pbe_sol_values[PBE_N_PAR] = + {0.804, MU_GE}; +static const double pbe_xpbe_values[PBE_N_PAR] = + {0.91954, 0.23214}; +static const double pbe_jsjr_values[PBE_N_PAR] = + {0.8040, 0.046*M_PI*M_PI/3.0}; +static const double pbe_k1_vdw_values[PBE_N_PAR] = + {1.0, MU_PBE}; +static const double pbe_apbe_values[PBE_N_PAR] = + {0.8040, 0.260}; +static const double pbe_tca_values[PBE_N_PAR] = + {1.227, MU_PBE}; +static const double pbe_mol_values[PBE_N_PAR] = + {0.8040, 0.27583}; +static const double pbe_bcgp_values[PBE_N_PAR] = + {0.8040, 0.249}; +static const double pbe_fe_values[PBE_N_PAR] = + {0.437, 0.346}; + +#include "gga_x_pbe_funcs.h" +#include "work_gga.h" + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe = { + XC_GGA_X_PBE, + XC_EXCHANGE, + "Perdew, Burke & Ernzerhof", + XC_FAMILY_GGA, + //{&xc_ref_Perdew1996_3865, &xc_ref_Perdew1996_3865_err, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_r = { + XC_GGA_X_PBE_R, + XC_EXCHANGE, + "Revised PBE from Zhang & Yang", + XC_FAMILY_GGA, + //{&xc_ref_Zhang1998_890, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_r_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_sol = { + XC_GGA_X_PBE_SOL, + XC_EXCHANGE, + "Perdew, Burke & Ernzerhof SOL", + XC_FAMILY_GGA, + //{&xc_ref_Perdew2008_136406, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_sol_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_xpbe = { + XC_GGA_X_XPBE, + XC_EXCHANGE, + "Extended PBE by Xu & Goddard III", + XC_FAMILY_GGA, + //{&xc_ref_Xu2004_4068, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_xpbe_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_jsjr = { + XC_GGA_X_PBE_JSJR, + XC_EXCHANGE, + "Reparametrized PBE by Pedroza, Silva & Capelle", + XC_FAMILY_GGA, + //{&xc_ref_Pedroza2009_201106, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_jsjr_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbek1_vdw = { + XC_GGA_X_PBEK1_VDW, + XC_EXCHANGE, + "Reparametrized PBE for vdW", + XC_FAMILY_GGA, + //{&xc_ref_Klimes2010_022201, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_k1_vdw_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_apbe = { + XC_GGA_X_APBE, + XC_EXCHANGE, + "mu fixed from the semiclassical neutral atom", + XC_FAMILY_GGA, + //{&xc_ref_Constantin2011_186406, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_apbe_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_tca = { + XC_GGA_X_PBE_TCA, + XC_EXCHANGE, + "PBE revised by Tognetti et al", + XC_FAMILY_GGA, + //{&xc_ref_Tognetti2008_536, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_tca_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbe_mol = { + XC_GGA_X_PBE_MOL, + XC_EXCHANGE, + "Reparametrized PBE by del Campo, Gazquez, Trickey & Vela", + XC_FAMILY_GGA, + //{&xc_ref_delCampo2012_104108, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_mol_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_bcgp = { + XC_GGA_X_BCGP, + XC_EXCHANGE, + "Burke, Cancio, Gould, and Pittalis", + XC_FAMILY_GGA, + //{&xc_ref_Burke2014_4834, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_bcgp_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_pbefe = { + XC_GGA_X_PBEFE, + XC_EXCHANGE, + "PBE for formation energies", + XC_FAMILY_GGA, + //{&xc_ref_Perez2015_3844, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBE_N_PAR, pbe_names, pbe_desc, pbe_fe_values, set_ext_params_cpy}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#define PBEL_N_PAR 3 +static const char *pbe_lambda_names[PBEL_N_PAR] = {"_N", "_kappa", "_mu"}; +static const char *pbe_lambda_desc[PBEL_N_PAR] = { + "Number of electrons", + "Asymptotic value of the enhancement function", + "Coefficient of the 2nd order expansion"}; +static const double pbe_lambda_lo_n_values[PBEL_N_PAR] = + {1e23, MU_PBE, 2.273}; +static const double pbe_lambda_ch_n_values[PBEL_N_PAR] = + {1e23, MU_PBE, 2.215}; +static const double pbe_lambda_oc2_n_values[PBEL_N_PAR] = + {1e23, MU_PBE, 2.00}; + +static void +pbe_lambda_set_ext_params(xc_func_type *p, const double *ext_params) +{ + const double lambda_1 = 1.48; + + gga_x_pbe_params *params; + double lambda, N; + + assert(p != NULL && p->params != NULL); + params = (gga_x_pbe_params *) (p->params); + + N = get_ext_param(p, ext_params, 0); + params->mu = get_ext_param(p, ext_params, 1); + params->lambda = get_ext_param(p, ext_params, 2); + + lambda = (1.0 - 1.0/N)*params->lambda + lambda_1/N; + params->kappa = lambda/M_CBRT2 - 1.0; +} + + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_lambda_lo_n = { + XC_GGA_X_LAMBDA_LO_N, + XC_EXCHANGE, + "lambda_LO(N) version of PBE", + XC_FAMILY_GGA, + //{&xc_ref_Odashima2009_798, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBEL_N_PAR, pbe_lambda_names, pbe_lambda_desc, pbe_lambda_lo_n_values, pbe_lambda_set_ext_params}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_lambda_ch_n = { + XC_GGA_X_LAMBDA_CH_N, + XC_EXCHANGE, + "lambda_CH(N) version of PBE", + XC_FAMILY_GGA, + //{&xc_ref_Odashima2009_798, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBEL_N_PAR, pbe_lambda_names, pbe_lambda_desc, pbe_lambda_ch_n_values, pbe_lambda_set_ext_params}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; + +#ifdef __cplusplus +extern "C" +#endif +const xc_func_info_type xc_func_info_gga_x_lambda_oc2_n = { + XC_GGA_X_LAMBDA_OC2_N, + XC_EXCHANGE, + "lambda_OC2(N) version of PBE", + XC_FAMILY_GGA, + //{&xc_ref_Odashima2009_798, NULL, NULL, NULL, NULL}, + XC_FLAGS_3D | MAPLE2C_FLAGS, + 1e-15, + {PBEL_N_PAR, pbe_lambda_names, pbe_lambda_desc, pbe_lambda_oc2_n_values, pbe_lambda_set_ext_params}, + gga_x_pbe_init, NULL, + NULL, work_gga, NULL +}; diff --git a/ref/libxc/gga_x_pbe.h b/ref/libxc/gga_x_pbe.h new file mode 100644 index 0000000000000000000000000000000000000000..6444fc91c8a79a3bca8eb7ce140a54b24f90a604 --- /dev/null +++ b/ref/libxc/gga_x_pbe.h @@ -0,0 +1,14 @@ +#define XC_GGA_X_PBE 101 /* Perdew, Burke & Ernzerhof exchange */ +#define XC_GGA_X_PBE_R 102 /* Perdew, Burke & Ernzerhof exchange (revised) */ +#define XC_GGA_X_PBE_SOL 116 /* Perdew, Burke & Ernzerhof exchange (solids) */ +#define XC_GGA_X_XPBE 123 /* xPBE reparametrization by Xu & Goddard */ +#define XC_GGA_X_PBE_JSJR 126 /* JSJR reparametrization by Pedroza, Silva & Capelle */ +#define XC_GGA_X_PBEK1_VDW 140 /* PBE reparametrization for vdW */ +#define XC_GGA_X_APBE 184 /* mu fixed from the semiclassical neutral atom */ +#define XC_GGA_X_PBE_TCA 59 /* PBE revised by Tognetti et al */ +#define XC_GGA_X_PBE_MOL 49 /* Del Campo, Gazquez, Trickey and Vela (PBE-like) */ +#define XC_GGA_X_LAMBDA_LO_N 45 /* lambda_LO(N) version of PBE */ +#define XC_GGA_X_LAMBDA_CH_N 44 /* lambda_CH(N) version of PBE */ +#define XC_GGA_X_LAMBDA_OC2_N 40 /* lambda_OC2(N) version of PBE */ +#define XC_GGA_X_BCGP 38 /* Burke, Cancio, Gould, and Pittalis */ +#define XC_GGA_X_PBEFE 265 /* PBE for formation energies */ diff --git a/ref/libxc/gga_x_pbe_funcs.h b/ref/libxc/gga_x_pbe_funcs.h new file mode 100644 index 0000000000000000000000000000000000000000..3c681913e174f87434d8dbe2f7f14bb38403b9d2 --- /dev/null +++ b/ref/libxc/gga_x_pbe_funcs.h @@ -0,0 +1,1356 @@ +/* + This file was generated automatically with ./scripts/maple2c.pl. + Do not edit this file directly as it can be overwritten!! + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + Maple version : Maple 2020 (X86 64 LINUX) + Maple source : ./maple/gga_exc/gga_x_pbe.mpl + Type of functional: gga_exc +*/ + +#define maple2c_order 4 +#define MAPLE2C_FLAGS (XC_FLAGS_I_HAVE_EXC | XC_FLAGS_I_HAVE_VXC | XC_FLAGS_I_HAVE_FXC | XC_FLAGS_I_HAVE_KXC | XC_FLAGS_I_HAVE_LXC) + + +static inline void +func_unpol(const xc_func_type *p, int order, const double *rho, const double *sigma , double *zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )) +{ + +#ifndef XC_DONT_COMPILE_EXC + double t2, t3, t4, t6, t7, t8, t10, t11; + double t13, t15, t17, t18, t20, t22, t23, t24; + double t25, t27, t28, t30, t31, t33, t37, t42; + double t46; + +#ifndef XC_DONT_COMPILE_VXC + double t52, t56, t58, t59, t61, t64, t65, t69; + double t78, t79, t82; + +#ifndef XC_DONT_COMPILE_FXC + double t91, t96, t99, t103, t106, t107, t108, t109; + double t111, t112, t115, t119, t124, t128, t131, t135; + double t138, t145, t148; + +#ifndef XC_DONT_COMPILE_KXC + double t159, t162, t166, t169, t172, t173, t177, t178; + double t179, t180, t181, t182, t184, t188, t196, t200; + double t202, t206, t212, t216, t220, t223, t227, t231; + +#ifndef XC_DONT_COMPILE_LXC + double t253, t268, t269, t270, t276, t297, t316, t333; + double t344; +#endif + +#endif + +#endif + +#endif + +#endif + + + gga_x_pbe_params *params; + + assert(p->params != NULL); + params = (gga_x_pbe_params * )(p->params); + + t2 = rho[0] / 0.2e1 <= p->dens_threshold; + t3 = M_CBRT3; + t4 = M_CBRTPI; + t6 = t3 / t4; + t7 = 0.1e1 <= p->zeta_threshold; + t8 = p->zeta_threshold - 0.1e1; + t10 = my_piecewise5(t7, t8, t7, -t8, 0); + t11 = 0.1e1 + t10; + t13 = POW_1_3(p->zeta_threshold); + t15 = POW_1_3(t11); + t17 = my_piecewise3(t11 <= p->zeta_threshold, t13 * p->zeta_threshold, t15 * t11); + t18 = POW_1_3(rho[0]); + t20 = M_CBRT6; + t22 = M_PI * M_PI; + t23 = POW_1_3(t22); + t24 = t23 * t23; + t25 = 0.1e1 / t24; + t27 = M_CBRT2; + t28 = t27 * t27; + t30 = rho[0] * rho[0]; + t31 = t18 * t18; + t33 = 0.1e1 / t31 / t30; + t37 = params->kappa + params->mu * t20 * t25 * sigma[0] * t28 * t33 / 0.24e2; + t42 = 0.1e1 + params->kappa * (0.1e1 - params->kappa / t37); + t46 = my_piecewise3(t2, 0, -0.3e1 / 0.8e1 * t6 * t17 * t18 * t42); + if(zk != NULL && (p->info->flags & XC_FLAGS_HAVE_EXC)) + zk[0] = 0.2e1 * t46; + +#ifndef XC_DONT_COMPILE_VXC + + if(order < 1) return; + + + t52 = t30 * rho[0]; + t56 = params->kappa * params->kappa; + t58 = t6 * t17 / t18 / t52 * t56; + t59 = t37 * t37; + t61 = 0.1e1 / t59 * params->mu; + t64 = t25 * sigma[0] * t28; + t65 = t61 * t20 * t64; + t69 = my_piecewise3(t2, 0, -t6 * t17 / t31 * t42 / 0.8e1 + t58 * t65 / 0.24e2); + if(vrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + vrho[0] = 0.2e1 * rho[0] * t69 + 0.2e1 * t46; + + t78 = t20 * t25 * t28; + t79 = t61 * t78; + t82 = my_piecewise3(t2, 0, -t6 * t17 / t18 / t30 * t56 * t79 / 0.64e2); + if(vrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + vsigma[0] = 0.2e1 * rho[0] * t82; + +#ifndef XC_DONT_COMPILE_FXC + + if(order < 2) return; + + + t91 = t30 * t30; + t96 = t6 * t17 / t18 / t91 * t56; + t99 = t91 * t52; + t103 = t6 * t17 / t99 * t56; + t106 = params->mu * params->mu; + t107 = 0.1e1 / t59 / t37 * t106; + t108 = t20 * t20; + t109 = t107 * t108; + t111 = 0.1e1 / t23 / t22; + t112 = sigma[0] * sigma[0]; + t115 = t109 * t111 * t112 * t27; + t119 = my_piecewise3(t2, 0, t6 * t17 / t31 / rho[0] * t42 / 0.12e2 - t96 * t65 / 0.8e1 + t103 * t115 / 0.54e2); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rho2[0] = 0.2e1 * rho[0] * t119 + 0.4e1 * t69; + + t124 = t91 * t30; + t128 = t6 * t17 / t124 * t56; + t131 = t109 * t111 * t27 * sigma[0]; + t135 = my_piecewise3(t2, 0, 0.7e1 / 0.192e3 * t58 * t79 - t128 * t131 / 0.144e3); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rhosigma[0] = 0.2e1 * rho[0] * t135 + 0.2e1 * t82; + + t138 = t91 * rho[0]; + t145 = t107 * t108 * t111 * t27; + t148 = my_piecewise3(t2, 0, t6 * t17 / t138 * t56 * t145 / 0.384e3); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2sigma2[0] = 0.2e1 * rho[0] * t148; + +#ifndef XC_DONT_COMPILE_KXC + + if(order < 3) return; + + + t159 = t6 * t17 / t18 / t138 * t56; + t162 = t91 * t91; + t166 = t6 * t17 / t162 * t56; + t169 = t22 * t22; + t172 = t3 / t4 / t169; + t173 = t162 * t30; + t177 = t172 * t17 / t31 / t173; + t178 = t59 * t59; + t179 = 0.1e1 / t178; + t180 = t56 * t179; + t181 = t106 * params->mu; + t182 = t112 * sigma[0]; + t184 = t180 * t181 * t182; + t188 = my_piecewise3(t2, 0, -0.5e1 / 0.36e2 * t6 * t17 * t33 * t42 + 0.115e3 / 0.216e3 * t159 * t65 - 0.5e1 / 0.27e2 * t166 * t115 + 0.2e1 / 0.27e2 * t177 * t184); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho3[0] = 0.2e1 * rho[0] * t188 + 0.6e1 * t119; + + t196 = t162 * rho[0]; + t200 = t172 * t17 / t31 / t196; + t202 = t180 * t181 * t112; + t206 = my_piecewise3(t2, 0, -0.35e2 / 0.288e3 * t96 * t79 + 0.25e2 / 0.432e3 * t103 * t131 - t200 * t202 / 0.36e2); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[0] = 0.2e1 * rho[0] * t206 + 0.4e1 * t135; + + t212 = 0.1e1 / t31 / t162; + t216 = t180 * t181 * sigma[0]; + t220 = my_piecewise3(t2, 0, -0.5e1 / 0.384e3 * t128 * t145 + t172 * t17 * t212 * t216 / 0.96e2); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[0] = 0.2e1 * rho[0] * t220 + 0.2e1 * t148; + + t223 = t172 * t17; + t227 = t179 * t181; + t231 = my_piecewise3(t2, 0, -t223 / t31 / t99 * t56 * t227 / 0.256e3); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[0] = 0.2e1 * rho[0] * t231; + +#ifndef XC_DONT_COMPILE_LXC + + if(order < 4) return; + + + t253 = t162 * t52; + t268 = t106 * t106; + t269 = 0.1e1 / t178 / t37 * t268; + t270 = t112 * t112; + t276 = my_piecewise3(t2, 0, 0.10e2 / 0.27e2 * t6 * t17 / t31 / t52 * t42 - 0.305e3 / 0.108e3 * t6 * t17 / t18 / t124 * t56 * t65 + 0.835e3 / 0.486e3 * t6 * t17 / t196 * t56 * t115 - 0.124e3 / 0.81e2 * t172 * t17 / t31 / t253 * t184 + 0.8e1 / 0.243e3 * t172 * t17 / t18 / t162 / t124 * t56 * t269 * t270 * t78); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho4[0] = 0.2e1 * rho[0] * t276 + 0.8e1 * t188; + + t297 = my_piecewise3(t2, 0, 0.455e3 / 0.864e3 * t159 * t79 - 0.595e3 / 0.1296e4 * t166 * t131 + t177 * t202 / 0.2e1 - t172 * t17 / t18 / t162 / t138 * t56 * t269 * t182 * t78 / 0.81e2); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[0] = 0.2e1 * rho[0] * t297 + 0.6e1 * t206; + + t316 = my_piecewise3(t2, 0, 0.5e1 / 0.64e2 * t103 * t145 - 0.41e2 / 0.288e3 * t200 * t216 + t172 * t17 / t18 / t162 / t91 * t56 * t269 * t112 * t78 / 0.216e3); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[0] = 0.2e1 * rho[0] * t316 + 0.4e1 * t220; + + t333 = my_piecewise3(t2, 0, 0.23e2 / 0.768e3 * t223 * t212 * t56 * t227 - t172 * t17 / t18 / t253 * t56 * t269 * t20 * t64 / 0.576e3); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[0] = 0.2e1 * rho[0] * t333 + 0.2e1 * t231; + + t344 = my_piecewise3(t2, 0, t172 * t17 / t18 / t173 * t56 * t269 * t78 / 0.1536e4); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[0] = 0.2e1 * rho[0] * t344; + +#ifndef XC_DONT_COMPILE_MXC + + if(order < 5) return; + + +#endif + +#endif + +#endif + +#endif + +#endif + + +} + + +static inline void +func_pol(const xc_func_type *p, int order, const double *rho, const double *sigma , double *zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )) +{ + +#ifndef XC_DONT_COMPILE_EXC + double t1, t2, t3, t5, t6, t7, t10, t11; + double t14, t15, t16, t18, t19, t20, t21, t22; + double t23, t25, t26, t27, t28, t29, t30, t31; + double t32, t33, t34, t35, t36, t37, t39, t43; + double t48, t52, t53, t54, t56, t57, t58, t59; + double t61, t62, t63, t64, t65, t66, t68, t72; + double t77, t81; + +#ifndef XC_DONT_COMPILE_VXC + double t82, t83, t84, t86, t89, t90, t94, t95; + double t96, t99, t100, t101, t102, t103, t105, t106; + double t107, t109, t111, t115, t116, t118, t121, t122; + double t126, t129, t131, t135, t138, t139, t144, t146; + double t149, t150, t154, t155, t156, t158, t159, t160; + double t162, t164, t168, t171, t173, t176, t178, t181; + +#ifndef XC_DONT_COMPILE_FXC + double t184, t185, t186, t189, t190, t191, t194, t198; + double t199, t203, t205, t208, t212, t213, t216, t218; + double t219, t223, t224, t225, t226, t228, t229, t230; + double t231, t234, t236, t240, t242, t246, t247, t248; + double t249, t252, t255, t259, t260, t264, t266, t268; + double t271, t273, t276, t280, t284, t285, t289, t291; + double t294, t300, t301, t305, t309, t310, t314, t316; + double t320, t324, t325, t328, t333, t338, t342, t343; + double t349, t350, t355, t359, t360, t366, t372, t373; + double t374, t375, t376, t379, t381, t385, t387, t391; + double t397, t398, t400, t403, t407, t411, t416, t418; + double t423, t427, t429, t432, t436, t440, t442, t443; + double t447, t450, t451, t455, t458; + +#ifndef XC_DONT_COMPILE_KXC + double t462, t464, t467, t469, t471, t473, t478, t481; + double t485, t486, t491, t492, t494, t496, t498, t500; + double t503, t504, t507, t509, t510, t513, t516, t517; + double t518, t521, t525, t526, t530, t533, t534, t535; + double t537, t538, t539, t540, t541, t542, t544, t547; + double t548, t550, t551, t554, t557, t560, t564, t565; + double t569, t571, t573, t575, t577, t580, t582, t585; + double t586, t587, t590, t595, t596, t598, t602, t603; + double t607, t610, t612, t615, t617, t620, t622, t633; + double t634, t635, t638, t643, t645, t649, t650, t654; + double t657, t658, t660, t665, t669, t671, t673, t674; + double t677, t680, t685, t689, t693, t694, t698, t700; + double t703, t710, t711, t716, t720, t724, t725, t729; + double t731, t735, t739, t740, t746, t750, t752, t753; + double t758, t765, t769, t770, t777, t778, t785, t789; + double t790, t794, t796, t798, t802, t804, t816, t821; + double t822, t824, t825, t826, t827, t828, t830, t833; + double t834, t840, t847, t848, t850, t852, t854, t856; + double t861, t865, t869, t874, t877, t879, t883, t893; + double t897, t902, t906, t909, t916, t928, t930, t932; + double t937, t941, t945, t950, t951, t953, t955, t959; + double t963, t968, t970, t975, t979, t981, t983, t987; + double t991, t995, t998, t1001, t1004; + +#ifndef XC_DONT_COMPILE_LXC + double t1009, t1013, t1016, t1020, t1023, t1025, t1027, t1028; + double t1034, t1040, t1041, t1044, t1048, t1053, t1059, t1060; + double t1062, t1066, t1067, t1070, t1071, t1073, t1076, t1077; + double t1079, t1086, t1088, t1090, t1093, t1094, t1095, t1109; + double t1112, t1125, t1127, t1129, t1131, t1132, t1134, t1135; + double t1141, t1146, t1149, t1153, t1160, t1164, t1168, t1173; + double t1175, t1182, t1186, t1187, t1190, t1208, t1209, t1211; + double t1215, t1224, t1227, t1230, t1234, t1235, t1239, t1241; + double t1242, t1243, t1253, t1261, t1263, t1280, t1282, t1286; + double t1293, t1297, t1298, t1301, t1307, t1311, t1312, t1315; + double t1316, t1317, t1319, t1320, t1322, t1323, t1331, t1335; + double t1336, t1343, t1347, t1363, t1376, t1380, t1394, t1396; + double t1402, t1408, t1412, t1427, t1440, t1444, t1449, t1451; + double t1453, t1455, t1458, t1459, t1462, t1463, t1468, t1470; + double t1491, t1495, t1502, t1505, t1514, t1515, t1518, t1536; + double t1540, t1549, t1550, t1552, t1560, t1565, t1568, t1570; + double t1573, t1574, t1576, t1578, t1587, t1589, t1594, t1599; + double t1606, t1610, t1619, t1620, t1625, t1632, t1636, t1645; + double t1651, t1657, t1664, t1684, t1687, t1688, t1702, t1704; + double t1715, t1731, t1732, t1734, t1736, t1738, t1740, t1742; + double t1746, t1761, t1763, t1764, t1769, t1771, t1774, t1776; + double t1778, t1785, t1790, t1793, t1795, t1808, t1809, t1811; + double t1815, t1816, t1823, t1824, t1829, t1830, t1832, t1833; + double t1837, t1847, t1848, t1852, t1857, t1861, t1868, t1872; + double t1876, t1878, t1879, t1887, t1934, t1935, t1940, t1947; + double t1948, t1950, t1969, t1974, t1977, t1979, t1983, t1993; + double t1997, t2002, t2006, t2009, t2016, t2045, t2050, t2062; + double t2067, t2069, t2074, t2089, t2098, t2106; +#endif + +#endif + +#endif + +#endif + +#endif + + + gga_x_pbe_params *params; + + assert(p->params != NULL); + params = (gga_x_pbe_params * )(p->params); + + t1 = rho[0] <= p->dens_threshold; + t2 = M_CBRT3; + t3 = M_CBRTPI; + t5 = t2 / t3; + t6 = rho[0] + rho[1]; + t7 = 0.1e1 / t6; + t10 = 0.2e1 * rho[0] * t7 <= p->zeta_threshold; + t11 = p->zeta_threshold - 0.1e1; + t14 = 0.2e1 * rho[1] * t7 <= p->zeta_threshold; + t15 = -t11; + t16 = rho[0] - rho[1]; + t18 = my_piecewise5(t10, t11, t14, t15, t16 * t7); + t19 = 0.1e1 + t18; + t20 = t19 <= p->zeta_threshold; + t21 = POW_1_3(p->zeta_threshold); + t22 = t21 * p->zeta_threshold; + t23 = POW_1_3(t19); + t25 = my_piecewise3(t20, t22, t23 * t19); + t26 = POW_1_3(t6); + t27 = t25 * t26; + t28 = M_CBRT6; + t29 = params->mu * t28; + t30 = M_PI * M_PI; + t31 = POW_1_3(t30); + t32 = t31 * t31; + t33 = 0.1e1 / t32; + t34 = t33 * sigma[0]; + t35 = rho[0] * rho[0]; + t36 = POW_1_3(rho[0]); + t37 = t36 * t36; + t39 = 0.1e1 / t37 / t35; + t43 = params->kappa + t29 * t34 * t39 / 0.24e2; + t48 = 0.1e1 + params->kappa * (0.1e1 - params->kappa / t43); + t52 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t27 * t48); + t53 = rho[1] <= p->dens_threshold; + t54 = -t16; + t56 = my_piecewise5(t14, t11, t10, t15, t54 * t7); + t57 = 0.1e1 + t56; + t58 = t57 <= p->zeta_threshold; + t59 = POW_1_3(t57); + t61 = my_piecewise3(t58, t22, t59 * t57); + t62 = t61 * t26; + t63 = t33 * sigma[2]; + t64 = rho[1] * rho[1]; + t65 = POW_1_3(rho[1]); + t66 = t65 * t65; + t68 = 0.1e1 / t66 / t64; + t72 = params->kappa + t29 * t63 * t68 / 0.24e2; + t77 = 0.1e1 + params->kappa * (0.1e1 - params->kappa / t72); + t81 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t62 * t77); + if(zk != NULL && (p->info->flags & XC_FLAGS_HAVE_EXC)) + zk[0] = t52 + t81; + +#ifndef XC_DONT_COMPILE_VXC + + if(order < 1) return; + + + t82 = t6 * t6; + t83 = 0.1e1 / t82; + t84 = t16 * t83; + t86 = my_piecewise5(t10, 0, t14, 0, t7 - t84); + t89 = my_piecewise3(t20, 0, 0.4e1 / 0.3e1 * t23 * t86); + t90 = t89 * t26; + t94 = t26 * t26; + t95 = 0.1e1 / t94; + t96 = t25 * t95; + t99 = t5 * t96 * t48 / 0.8e1; + t100 = params->kappa * params->kappa; + t101 = t27 * t100; + t102 = t5 * t101; + t103 = t43 * t43; + t105 = 0.1e1 / t103 * params->mu; + t106 = t105 * t28; + t107 = t35 * rho[0]; + t109 = 0.1e1 / t37 / t107; + t111 = t106 * t34 * t109; + t115 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t90 * t48 - t99 + t102 * t111 / 0.24e2); + t116 = t54 * t83; + t118 = my_piecewise5(t14, 0, t10, 0, -t7 - t116); + t121 = my_piecewise3(t58, 0, 0.4e1 / 0.3e1 * t59 * t118); + t122 = t121 * t26; + t126 = t61 * t95; + t129 = t5 * t126 * t77 / 0.8e1; + t131 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t122 * t77 - t129); + if(vrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + vrho[0] = t52 + t81 + t6 * (t115 + t131); + + t135 = my_piecewise5(t10, 0, t14, 0, -t7 - t84); + t138 = my_piecewise3(t20, 0, 0.4e1 / 0.3e1 * t23 * t135); + t139 = t138 * t26; + t144 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t139 * t48 - t99); + t146 = my_piecewise5(t14, 0, t10, 0, t7 - t116); + t149 = my_piecewise3(t58, 0, 0.4e1 / 0.3e1 * t59 * t146); + t150 = t149 * t26; + t154 = t62 * t100; + t155 = t5 * t154; + t156 = t72 * t72; + t158 = 0.1e1 / t156 * params->mu; + t159 = t158 * t28; + t160 = t64 * rho[1]; + t162 = 0.1e1 / t66 / t160; + t164 = t159 * t63 * t162; + t168 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t150 * t77 - t129 + t155 * t164 / 0.24e2); + if(vrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + vrho[1] = t52 + t81 + t6 * (t144 + t168); + + t171 = t28 * t33; + t173 = t105 * t171 * t39; + t176 = my_piecewise3(t1, 0, -t102 * t173 / 0.64e2); + if(vrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + vsigma[0] = t6 * t176; + + if(vrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + vsigma[1] = 0.0e0; + + t178 = t158 * t171 * t68; + t181 = my_piecewise3(t53, 0, -t155 * t178 / 0.64e2); + if(vrho != NULL && (p->info->flags & XC_FLAGS_HAVE_VXC)) + vsigma[2] = t6 * t181; + +#ifndef XC_DONT_COMPILE_FXC + + if(order < 2) return; + + + t184 = t23 * t23; + t185 = 0.1e1 / t184; + t186 = t86 * t86; + t189 = t82 * t6; + t190 = 0.1e1 / t189; + t191 = t16 * t190; + t194 = my_piecewise5(t10, 0, t14, 0, -0.2e1 * t83 + 0.2e1 * t191); + t198 = my_piecewise3(t20, 0, 0.4e1 / 0.9e1 * t185 * t186 + 0.4e1 / 0.3e1 * t23 * t194); + t199 = t198 * t26; + t203 = t89 * t95; + t205 = t5 * t203 * t48; + t208 = t5 * t90 * t100; + t212 = 0.1e1 / t94 / t6; + t213 = t25 * t212; + t216 = t5 * t213 * t48 / 0.12e2; + t218 = t5 * t96 * t100; + t219 = t218 * t111; + t223 = params->mu * params->mu; + t224 = 0.1e1 / t103 / t43 * t223; + t225 = t28 * t28; + t226 = t224 * t225; + t228 = 0.1e1 / t31 / t30; + t229 = sigma[0] * sigma[0]; + t230 = t228 * t229; + t231 = t35 * t35; + t234 = 0.1e1 / t36 / t231 / t107; + t236 = t226 * t230 * t234; + t240 = 0.1e1 / t37 / t231; + t242 = t106 * t34 * t240; + t246 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t199 * t48 - t205 / 0.4e1 + t208 * t111 / 0.12e2 + t216 + t219 / 0.36e2 + t102 * t236 / 0.108e3 - 0.11e2 / 0.72e2 * t102 * t242); + t247 = t59 * t59; + t248 = 0.1e1 / t247; + t249 = t118 * t118; + t252 = t54 * t190; + t255 = my_piecewise5(t14, 0, t10, 0, 0.2e1 * t83 + 0.2e1 * t252); + t259 = my_piecewise3(t58, 0, 0.4e1 / 0.9e1 * t248 * t249 + 0.4e1 / 0.3e1 * t59 * t255); + t260 = t259 * t26; + t264 = t121 * t95; + t266 = t5 * t264 * t77; + t268 = t61 * t212; + t271 = t5 * t268 * t77 / 0.12e2; + t273 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t260 * t77 - t266 / 0.4e1 + t271); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rho2[0] = 0.2e1 * t115 + 0.2e1 * t131 + t6 * (t246 + t273); + + t276 = t185 * t135; + t280 = my_piecewise5(t10, 0, t14, 0, 0.2e1 * t191); + t284 = my_piecewise3(t20, 0, 0.4e1 / 0.9e1 * t276 * t86 + 0.4e1 / 0.3e1 * t23 * t280); + t285 = t284 * t26; + t289 = t138 * t95; + t291 = t5 * t289 * t48; + t294 = t5 * t139 * t100; + t300 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t285 * t48 - t291 / 0.8e1 + t294 * t111 / 0.24e2 - t205 / 0.8e1 + t216 + t219 / 0.72e2); + t301 = t248 * t146; + t305 = my_piecewise5(t14, 0, t10, 0, 0.2e1 * t252); + t309 = my_piecewise3(t58, 0, 0.4e1 / 0.9e1 * t301 * t118 + 0.4e1 / 0.3e1 * t59 * t305); + t310 = t309 * t26; + t314 = t149 * t95; + t316 = t5 * t314 * t77; + t320 = t5 * t122 * t100; + t324 = t5 * t126 * t100; + t325 = t324 * t164; + t328 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t310 * t77 - t316 / 0.8e1 - t266 / 0.8e1 + t271 + t320 * t164 / 0.24e2 + t325 / 0.72e2); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rho2[1] = t115 + t131 + t144 + t168 + t6 * (t300 + t328); + + t333 = t135 * t135; + t338 = my_piecewise5(t10, 0, t14, 0, 0.2e1 * t83 + 0.2e1 * t191); + t342 = my_piecewise3(t20, 0, 0.4e1 / 0.9e1 * t185 * t333 + 0.4e1 / 0.3e1 * t23 * t338); + t343 = t342 * t26; + t349 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t343 * t48 - t291 / 0.4e1 + t216); + t350 = t146 * t146; + t355 = my_piecewise5(t14, 0, t10, 0, -0.2e1 * t83 + 0.2e1 * t252); + t359 = my_piecewise3(t58, 0, 0.4e1 / 0.9e1 * t248 * t350 + 0.4e1 / 0.3e1 * t59 * t355); + t360 = t359 * t26; + t366 = t5 * t150 * t100; + t372 = 0.1e1 / t156 / t72 * t223; + t373 = t372 * t225; + t374 = sigma[2] * sigma[2]; + t375 = t228 * t374; + t376 = t64 * t64; + t379 = 0.1e1 / t65 / t376 / t160; + t381 = t373 * t375 * t379; + t385 = 0.1e1 / t66 / t376; + t387 = t159 * t63 * t385; + t391 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t360 * t77 - t316 / 0.4e1 + t366 * t164 / 0.12e2 + t271 + t325 / 0.36e2 + t155 * t381 / 0.108e3 - 0.11e2 / 0.72e2 * t155 * t387); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rho2[2] = 0.2e1 * t144 + 0.2e1 * t168 + t6 * (t349 + t391); + + t397 = t218 * t173 / 0.192e3; + t398 = t231 * t35; + t400 = 0.1e1 / t36 / t398; + t403 = t226 * t228 * t400 * sigma[0]; + t407 = t105 * t171 * t109; + t411 = my_piecewise3(t1, 0, -t208 * t173 / 0.64e2 - t397 - t102 * t403 / 0.288e3 + t102 * t407 / 0.24e2); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rhosigma[0] = t6 * t411 + t176; + + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rhosigma[1] = 0.0e0; + + t416 = t324 * t178 / 0.192e3; + t418 = my_piecewise3(t53, 0, -t320 * t178 / 0.64e2 - t416); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rhosigma[2] = t6 * t418 + t181; + + t423 = my_piecewise3(t1, 0, -t294 * t173 / 0.64e2 - t397); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rhosigma[3] = t6 * t423 + t176; + + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rhosigma[4] = 0.0e0; + + t427 = t376 * t64; + t429 = 0.1e1 / t65 / t427; + t432 = t373 * t228 * t429 * sigma[2]; + t436 = t158 * t171 * t162; + t440 = my_piecewise3(t53, 0, -t366 * t178 / 0.64e2 - t416 - t155 * t432 / 0.288e3 + t155 * t436 / 0.24e2); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2rhosigma[5] = t6 * t440 + t181; + + t442 = t225 * t228; + t443 = t231 * rho[0]; + t447 = t224 * t442 / t36 / t443; + t450 = my_piecewise3(t1, 0, t102 * t447 / 0.768e3); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2sigma2[0] = t6 * t450; + + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2sigma2[1] = 0.0e0; + + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2sigma2[2] = 0.0e0; + + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2sigma2[3] = 0.0e0; + + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2sigma2[4] = 0.0e0; + + t451 = t376 * rho[1]; + t455 = t372 * t442 / t65 / t451; + t458 = my_piecewise3(t53, 0, t155 * t455 / 0.768e3); + if(v2rho2 != NULL && (p->info->flags & XC_FLAGS_HAVE_FXC)) + v2sigma2[5] = t6 * t458; + +#ifndef XC_DONT_COMPILE_KXC + + if(order < 3) return; + + + t462 = 0.1e1 / t37 / t443; + t464 = t106 * t34 * t462; + t467 = t218 * t242; + t469 = t231 * t231; + t471 = 0.1e1 / t36 / t469; + t473 = t226 * t230 * t471; + t478 = t218 * t236; + t481 = t5 * t199 * t100; + t485 = t5 * t203 * t100; + t486 = t485 * t111; + t491 = t5 * t213 * t100; + t492 = t491 * t111; + t494 = t198 * t95; + t496 = t5 * t494 * t48; + t498 = t89 * t212; + t500 = t5 * t498 * t48; + t503 = 0.1e1 / t94 / t82; + t504 = t25 * t503; + t507 = 0.5e1 / 0.36e2 * t5 * t504 * t48; + t509 = 0.1e1 / t184 / t19; + t510 = t186 * t86; + t513 = t185 * t86; + t516 = t82 * t82; + t517 = 0.1e1 / t516; + t518 = t16 * t517; + t521 = my_piecewise5(t10, 0, t14, 0, 0.6e1 * t190 - 0.6e1 * t518); + t525 = my_piecewise3(t20, 0, -0.8e1 / 0.27e2 * t509 * t510 + 0.4e1 / 0.3e1 * t513 * t194 + 0.4e1 / 0.3e1 * t23 * t521); + t526 = t525 * t26; + t530 = t30 * t30; + t533 = t2 / t3 / t530; + t534 = t533 * t27; + t535 = t103 * t103; + t537 = t100 / t535; + t538 = t223 * params->mu; + t539 = t229 * sigma[0]; + t540 = t538 * t539; + t541 = t469 * t107; + t542 = 0.1e1 / t541; + t544 = t537 * t540 * t542; + t547 = 0.77e2 / 0.108e3 * t102 * t464 - 0.11e2 / 0.72e2 * t467 - 0.11e2 / 0.108e3 * t102 * t473 - 0.11e2 / 0.24e2 * t208 * t242 + t478 / 0.108e3 + t481 * t111 / 0.8e1 + t486 / 0.12e2 + t208 * t236 / 0.36e2 - t492 / 0.36e2 - 0.3e1 / 0.8e1 * t496 + t500 / 0.4e1 - t507 - 0.3e1 / 0.8e1 * t5 * t526 * t48 + t534 * t544 / 0.54e2; + t548 = my_piecewise3(t1, 0, t547); + t550 = 0.1e1 / t247 / t57; + t551 = t249 * t118; + t554 = t248 * t118; + t557 = t54 * t517; + t560 = my_piecewise5(t14, 0, t10, 0, -0.6e1 * t190 - 0.6e1 * t557); + t564 = my_piecewise3(t58, 0, -0.8e1 / 0.27e2 * t550 * t551 + 0.4e1 / 0.3e1 * t554 * t255 + 0.4e1 / 0.3e1 * t59 * t560); + t565 = t564 * t26; + t569 = t259 * t95; + t571 = t5 * t569 * t77; + t573 = t121 * t212; + t575 = t5 * t573 * t77; + t577 = t61 * t503; + t580 = 0.5e1 / 0.36e2 * t5 * t577 * t77; + t582 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t565 * t77 - 0.3e1 / 0.8e1 * t571 + t575 / 0.4e1 - t580); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho3[0] = 0.3e1 * t246 + 0.3e1 * t273 + t6 * (t548 + t582); + + t585 = 0.2e1 * t300; + t586 = 0.2e1 * t328; + t587 = t509 * t135; + t590 = t185 * t280; + t595 = 0.2e1 * t190; + t596 = 0.6e1 * t518; + t598 = my_piecewise5(t10, 0, t14, 0, t595 - t596); + t602 = my_piecewise3(t20, 0, -0.8e1 / 0.27e2 * t587 * t186 + 0.8e1 / 0.9e1 * t590 * t86 + 0.4e1 / 0.9e1 * t276 * t194 + 0.4e1 / 0.3e1 * t23 * t598); + t603 = t602 * t26; + t607 = t284 * t95; + t610 = t5 * t607 * t48 / 0.4e1; + t612 = t5 * t285 * t100; + t615 = t138 * t212; + t617 = t5 * t615 * t48; + t620 = t5 * t289 * t100; + t622 = t620 * t111 / 0.36e2; + t633 = -0.3e1 / 0.8e1 * t5 * t603 * t48 - t610 + t612 * t111 / 0.12e2 + t617 / 0.12e2 + t622 + t294 * t236 / 0.108e3 - 0.11e2 / 0.72e2 * t294 * t242 - t496 / 0.8e1 + t500 / 0.6e1 + t486 / 0.36e2 - t507 - t492 / 0.54e2 + t478 / 0.324e3 - 0.11e2 / 0.216e3 * t467; + t634 = my_piecewise3(t1, 0, t633); + t635 = t550 * t146; + t638 = t248 * t305; + t643 = 0.6e1 * t557; + t645 = my_piecewise5(t14, 0, t10, 0, -t595 - t643); + t649 = my_piecewise3(t58, 0, -0.8e1 / 0.27e2 * t635 * t249 + 0.8e1 / 0.9e1 * t638 * t118 + 0.4e1 / 0.9e1 * t301 * t255 + 0.4e1 / 0.3e1 * t59 * t645); + t650 = t649 * t26; + t654 = t309 * t95; + t657 = t5 * t654 * t77 / 0.4e1; + t658 = t149 * t212; + t660 = t5 * t658 * t77; + t665 = t5 * t260 * t100; + t669 = t5 * t264 * t100; + t671 = t669 * t164 / 0.36e2; + t673 = t5 * t268 * t100; + t674 = t673 * t164; + t677 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t650 * t77 - t657 + t660 / 0.12e2 - t571 / 0.8e1 + t575 / 0.6e1 - t580 + t665 * t164 / 0.24e2 + t671 - t674 / 0.108e3); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho3[1] = t246 + t273 + t585 + t586 + t6 * (t634 + t677); + + t680 = t509 * t333; + t685 = t185 * t338; + t689 = my_piecewise5(t10, 0, t14, 0, -t595 - t596); + t693 = my_piecewise3(t20, 0, -0.8e1 / 0.27e2 * t680 * t86 + 0.8e1 / 0.9e1 * t276 * t280 + 0.4e1 / 0.9e1 * t685 * t86 + 0.4e1 / 0.3e1 * t23 * t689); + t694 = t693 * t26; + t698 = t342 * t95; + t700 = t5 * t698 * t48; + t703 = t5 * t343 * t100; + t710 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t694 * t48 - t700 / 0.8e1 + t703 * t111 / 0.24e2 - t610 + t617 / 0.6e1 + t622 + t500 / 0.12e2 - t507 - t492 / 0.108e3); + t711 = t550 * t350; + t716 = t248 * t355; + t720 = my_piecewise5(t14, 0, t10, 0, t595 - t643); + t724 = my_piecewise3(t58, 0, -0.8e1 / 0.27e2 * t711 * t118 + 0.8e1 / 0.9e1 * t301 * t305 + 0.4e1 / 0.9e1 * t716 * t118 + 0.4e1 / 0.3e1 * t59 * t720); + t725 = t724 * t26; + t729 = t359 * t95; + t731 = t5 * t729 * t77; + t735 = t5 * t310 * t100; + t739 = t5 * t314 * t100; + t740 = t739 * t164; + t746 = t324 * t381; + t750 = t324 * t387; + t752 = -0.3e1 / 0.8e1 * t5 * t725 * t77 - t731 / 0.8e1 - t657 + t660 / 0.6e1 + t735 * t164 / 0.12e2 + t740 / 0.36e2 + t575 / 0.12e2 - t580 + t671 - t674 / 0.54e2 + t320 * t381 / 0.108e3 + t746 / 0.324e3 - 0.11e2 / 0.72e2 * t320 * t387 - 0.11e2 / 0.216e3 * t750; + t753 = my_piecewise3(t53, 0, t752); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho3[2] = t585 + t586 + t349 + t391 + t6 * (t710 + t753); + + t758 = t333 * t135; + t765 = my_piecewise5(t10, 0, t14, 0, -0.6e1 * t190 - 0.6e1 * t518); + t769 = my_piecewise3(t20, 0, -0.8e1 / 0.27e2 * t509 * t758 + 0.4e1 / 0.3e1 * t276 * t338 + 0.4e1 / 0.3e1 * t23 * t765); + t770 = t769 * t26; + t777 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t770 * t48 - 0.3e1 / 0.8e1 * t700 + t617 / 0.4e1 - t507); + t778 = t350 * t146; + t785 = my_piecewise5(t14, 0, t10, 0, 0.6e1 * t190 - 0.6e1 * t557); + t789 = my_piecewise3(t58, 0, -0.8e1 / 0.27e2 * t550 * t778 + 0.4e1 / 0.3e1 * t301 * t355 + 0.4e1 / 0.3e1 * t59 * t785); + t790 = t789 * t26; + t794 = t376 * t376; + t796 = 0.1e1 / t65 / t794; + t798 = t373 * t375 * t796; + t802 = 0.1e1 / t66 / t451; + t804 = t159 * t63 * t802; + t816 = t5 * t360 * t100; + t821 = t533 * t62; + t822 = t156 * t156; + t824 = t100 / t822; + t825 = t374 * sigma[2]; + t826 = t538 * t825; + t827 = t794 * t160; + t828 = 0.1e1 / t827; + t830 = t824 * t826 * t828; + t833 = -0.3e1 / 0.8e1 * t5 * t790 * t77 - 0.11e2 / 0.108e3 * t155 * t798 + 0.77e2 / 0.108e3 * t155 * t804 - 0.11e2 / 0.24e2 * t366 * t387 + t746 / 0.108e3 - 0.11e2 / 0.72e2 * t750 - t674 / 0.36e2 + t740 / 0.12e2 + t366 * t381 / 0.36e2 + t816 * t164 / 0.8e1 + t660 / 0.4e1 - 0.3e1 / 0.8e1 * t731 - t580 + t821 * t830 / 0.54e2; + t834 = my_piecewise3(t53, 0, t833); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho3[3] = 0.3e1 * t349 + 0.3e1 * t391 + t6 * (t777 + t834); + + t840 = t485 * t173; + t847 = t491 * t173 / 0.288e3; + t848 = t218 * t403; + t850 = t218 * t407; + t852 = t469 * t35; + t854 = t538 / t852; + t856 = t537 * t854 * t229; + t861 = t226 * t228 * t234 * sigma[0]; + t865 = t105 * t171 * t240; + t869 = my_piecewise3(t1, 0, -t481 * t173 / 0.64e2 - t840 / 0.96e2 - t208 * t403 / 0.144e3 + t208 * t407 / 0.12e2 + t847 - t848 / 0.432e3 + t850 / 0.36e2 - t534 * t856 / 0.144e3 + t102 * t861 / 0.32e2 - 0.11e2 / 0.72e2 * t102 * t865); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[0] = t6 * t869 + 0.2e1 * t411; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[1] = 0.0e0; + + t874 = t669 * t178; + t877 = t673 * t178 / 0.288e3; + t879 = my_piecewise3(t53, 0, -t665 * t178 / 0.64e2 - t874 / 0.96e2 + t877); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[2] = t6 * t879 + 0.2e1 * t418; + + t883 = t620 * t173; + t893 = my_piecewise3(t1, 0, -t612 * t173 / 0.64e2 - t883 / 0.192e3 - t294 * t403 / 0.288e3 + t294 * t407 / 0.24e2 - t840 / 0.192e3 + t847 - t848 / 0.864e3 + t850 / 0.72e2); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[3] = t6 * t893 + t411 + t423; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[4] = 0.0e0; + + t897 = t739 * t178; + t902 = t324 * t432; + t906 = t324 * t436; + t909 = my_piecewise3(t53, 0, -t735 * t178 / 0.64e2 - t897 / 0.192e3 - t874 / 0.192e3 + t877 - t320 * t432 / 0.288e3 - t902 / 0.864e3 + t320 * t436 / 0.24e2 + t906 / 0.72e2); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[5] = t6 * t909 + t418 + t440; + + t916 = my_piecewise3(t1, 0, -t703 * t173 / 0.64e2 - t883 / 0.96e2 + t847); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[6] = t6 * t916 + 0.2e1 * t423; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[7] = 0.0e0; + + t928 = t794 * t64; + t930 = t538 / t928; + t932 = t824 * t930 * t374; + t937 = t373 * t228 * t379 * sigma[2]; + t941 = t158 * t171 * t385; + t945 = my_piecewise3(t53, 0, -t816 * t178 / 0.64e2 - t897 / 0.96e2 - t366 * t432 / 0.144e3 + t366 * t436 / 0.12e2 + t877 - t902 / 0.432e3 + t906 / 0.36e2 - t821 * t932 / 0.144e3 + t155 * t937 / 0.32e2 - 0.11e2 / 0.72e2 * t155 * t941); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rho2sigma[8] = t6 * t945 + 0.2e1 * t440; + + t950 = t218 * t447 / 0.2304e4; + t951 = t469 * rho[0]; + t953 = t538 / t951; + t955 = t537 * t953 * sigma[0]; + t959 = t224 * t442 * t400; + t963 = my_piecewise3(t1, 0, t208 * t447 / 0.768e3 + t950 + t534 * t955 / 0.384e3 - t102 * t959 / 0.144e3); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[0] = t6 * t963 + t450; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[1] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[2] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[3] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[4] = 0.0e0; + + t968 = t324 * t455 / 0.2304e4; + t970 = my_piecewise3(t53, 0, t320 * t455 / 0.768e3 + t968); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[5] = t6 * t970 + t458; + + t975 = my_piecewise3(t1, 0, t294 * t447 / 0.768e3 + t950); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[6] = t6 * t975 + t450; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[7] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[8] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[9] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[10] = 0.0e0; + + t979 = t794 * rho[1]; + t981 = t538 / t979; + t983 = t824 * t981 * sigma[2]; + t987 = t372 * t442 * t429; + t991 = my_piecewise3(t53, 0, t366 * t455 / 0.768e3 + t968 + t821 * t983 / 0.384e3 - t155 * t987 / 0.144e3); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3rhosigma2[11] = t6 * t991 + t458; + + t995 = t537 * t538 / t469; + t998 = my_piecewise3(t1, 0, -t534 * t995 / 0.1024e4); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[0] = t6 * t998; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[1] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[2] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[3] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[4] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[5] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[6] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[7] = 0.0e0; + + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[8] = 0.0e0; + + t1001 = t824 * t538 / t794; + t1004 = my_piecewise3(t53, 0, -t821 * t1001 / 0.1024e4); + if(v3rho3 != NULL && (p->info->flags & XC_FLAGS_HAVE_KXC)) + v3sigma3[9] = t6 * t1004; + +#ifndef XC_DONT_COMPILE_LXC + + if(order < 4) return; + + + t1009 = t5 * t198 * t212 * t48; + t1013 = t5 * t89 * t503 * t48; + t1016 = 0.1e1 / t94 / t189; + t1020 = 0.10e2 / 0.27e2 * t5 * t25 * t1016 * t48; + t1023 = t5 * t525 * t95 * t48; + t1025 = t19 * t19; + t1027 = 0.1e1 / t184 / t1025; + t1028 = t186 * t186; + t1034 = t194 * t194; + t1040 = 0.1e1 / t516 / t6; + t1041 = t16 * t1040; + t1044 = my_piecewise5(t10, 0, t14, 0, -0.24e2 * t517 + 0.24e2 * t1041); + t1048 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t1028 - 0.16e2 / 0.9e1 * t509 * t186 * t194 + 0.4e1 / 0.3e1 * t185 * t1034 + 0.16e2 / 0.9e1 * t513 * t521 + 0.4e1 / 0.3e1 * t23 * t1044); + t1053 = t469 * t231; + t1059 = t533 * t96; + t1060 = t1059 * t544; + t1062 = t533 * t90; + t1066 = t5 * t504 * t100; + t1067 = t1066 * t111; + t1070 = t5 * t498 * t100; + t1071 = t1070 * t111; + t1073 = t491 * t236; + t1076 = t5 * t494 * t100; + t1077 = t1076 * t111; + t1079 = t1009 / 0.2e1 - 0.5e1 / 0.9e1 * t1013 + t1020 - t1023 / 0.2e1 - 0.3e1 / 0.8e1 * t5 * t1048 * t26 * t48 - 0.11e2 / 0.27e2 * t534 * t537 * t540 / t1053 + 0.2e1 / 0.81e2 * t1060 + 0.2e1 / 0.27e2 * t1062 * t544 + 0.5e1 / 0.81e2 * t1067 - t1071 / 0.9e1 - t1073 / 0.81e2 + t1077 / 0.6e1; + t1086 = t491 * t242; + t1088 = t218 * t464; + t1090 = t533 * t101; + t1093 = t223 * t223; + t1094 = 0.1e1 / t535 / t43 * t1093; + t1095 = t229 * t229; + t1109 = t485 * t236; + t1112 = t5 * t526 * t100; + t1125 = t485 * t242; + t1127 = t218 * t473; + t1129 = -0.1309e4 / 0.324e3 * t102 * t106 * t34 / t37 / t398 + 0.11e2 / 0.54e2 * t1086 + 0.77e2 / 0.81e2 * t1088 + 0.2e1 / 0.243e3 * t1090 * t1094 * t1095 / t37 / t469 / t398 * t28 * t33 - 0.11e2 / 0.27e2 * t208 * t473 - 0.11e2 / 0.12e2 * t481 * t242 + t1109 / 0.27e2 + t1112 * t111 / 0.6e1 + t481 * t236 / 0.18e2 + 0.77e2 / 0.27e2 * t208 * t464 + 0.979e3 / 0.972e3 * t102 * t226 * t230 / t36 / t951 - 0.11e2 / 0.18e2 * t1125 - 0.11e2 / 0.81e2 * t1127; + t1131 = my_piecewise3(t1, 0, t1079 + t1129); + t1132 = t57 * t57; + t1134 = 0.1e1 / t247 / t1132; + t1135 = t249 * t249; + t1141 = t255 * t255; + t1146 = t54 * t1040; + t1149 = my_piecewise5(t14, 0, t10, 0, 0.24e2 * t517 + 0.24e2 * t1146); + t1153 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t1135 - 0.16e2 / 0.9e1 * t550 * t249 * t255 + 0.4e1 / 0.3e1 * t248 * t1141 + 0.16e2 / 0.9e1 * t554 * t560 + 0.4e1 / 0.3e1 * t59 * t1149); + t1160 = t5 * t564 * t95 * t77; + t1164 = t5 * t259 * t212 * t77; + t1168 = t5 * t121 * t503 * t77; + t1173 = 0.10e2 / 0.27e2 * t5 * t61 * t1016 * t77; + t1175 = my_piecewise3(t53, 0, -0.3e1 / 0.8e1 * t5 * t1153 * t26 * t77 - t1160 / 0.2e1 + t1164 / 0.2e1 - 0.5e1 / 0.9e1 * t1168 + t1173); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho4[0] = 0.4e1 * t548 + 0.4e1 * t582 + t6 * (t1131 + t1175); + + t1182 = t5 * t602 * t95 * t48; + t1186 = t5 * t284 * t212 * t48; + t1187 = t1186 / 0.4e1; + t1190 = t5 * t138 * t503 * t48; + t1208 = 0.12e2 * t517; + t1209 = 0.24e2 * t1041; + t1211 = my_piecewise5(t10, 0, t14, 0, -t1208 + t1209); + t1215 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t135 * t510 - 0.8e1 / 0.9e1 * t509 * t280 * t186 - 0.8e1 / 0.9e1 * t587 * t86 * t194 + 0.4e1 / 0.3e1 * t185 * t598 * t86 + 0.4e1 / 0.3e1 * t590 * t194 + 0.4e1 / 0.9e1 * t276 * t521 + 0.4e1 / 0.3e1 * t23 * t1211); + t1224 = t533 * t139; + t1227 = t620 * t242; + t1230 = t5 * t603 * t100; + t1234 = t5 * t607 * t100; + t1235 = t1234 * t111; + t1239 = -0.3e1 / 0.8e1 * t1182 + t1187 - 0.5e1 / 0.36e2 * t1190 - 0.3e1 / 0.8e1 * t5 * t1215 * t26 * t48 + t1009 / 0.4e1 - 0.5e1 / 0.12e2 * t1013 + t1020 - t1023 / 0.8e1 + t1060 / 0.162e3 + t1224 * t544 / 0.54e2 - 0.11e2 / 0.72e2 * t1227 + t1230 * t111 / 0.8e1 + t1235 / 0.12e2 + t612 * t236 / 0.36e2; + t1241 = t5 * t615 * t100; + t1242 = t1241 * t111; + t1243 = t1242 / 0.36e2; + t1253 = t620 * t236; + t1261 = -t1243 + 0.5e1 / 0.108e3 * t1067 - t1071 / 0.18e2 - t1073 / 0.162e3 + t1077 / 0.24e2 + 0.11e2 / 0.108e3 * t1086 + 0.77e2 / 0.324e3 * t1088 + t1109 / 0.108e3 - 0.11e2 / 0.72e2 * t1125 - 0.11e2 / 0.324e3 * t1127 + t1253 / 0.108e3 - 0.11e2 / 0.108e3 * t294 * t473 + 0.77e2 / 0.108e3 * t294 * t464 - 0.11e2 / 0.24e2 * t612 * t242; + t1263 = my_piecewise3(t1, 0, t1239 + t1261); + t1280 = 0.24e2 * t1146; + t1282 = my_piecewise5(t14, 0, t10, 0, t1208 + t1280); + t1286 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t146 * t551 - 0.8e1 / 0.9e1 * t550 * t305 * t249 - 0.8e1 / 0.9e1 * t635 * t118 * t255 + 0.4e1 / 0.3e1 * t248 * t645 * t118 + 0.4e1 / 0.3e1 * t638 * t255 + 0.4e1 / 0.9e1 * t301 * t560 + 0.4e1 / 0.3e1 * t59 * t1282); + t1293 = t5 * t649 * t95 * t77; + t1297 = t5 * t309 * t212 * t77; + t1298 = t1297 / 0.4e1; + t1301 = t5 * t149 * t503 * t77; + t1307 = t5 * t565 * t100; + t1311 = t5 * t569 * t100; + t1312 = t1311 * t164; + t1315 = t5 * t573 * t100; + t1316 = t1315 * t164; + t1317 = t1316 / 0.36e2; + t1319 = t5 * t577 * t100; + t1320 = t1319 * t164; + t1322 = -0.3e1 / 0.8e1 * t5 * t1286 * t26 * t77 - 0.3e1 / 0.8e1 * t1293 + t1298 - 0.5e1 / 0.36e2 * t1301 - t1160 / 0.8e1 + t1164 / 0.4e1 - 0.5e1 / 0.12e2 * t1168 + t1173 + t1307 * t164 / 0.24e2 + t1312 / 0.24e2 - t1317 + 0.5e1 / 0.324e3 * t1320; + t1323 = my_piecewise3(t53, 0, t1322); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho4[1] = t548 + t582 + 0.3e1 * t634 + 0.3e1 * t677 + t6 * (t1263 + t1323); + + t1331 = t5 * t694 * t100; + t1335 = t5 * t698 * t100; + t1336 = t1335 * t111; + t1343 = t5 * t693 * t95 * t48; + t1347 = t5 * t342 * t212 * t48; + t1363 = t280 * t280; + t1376 = my_piecewise5(t10, 0, t14, 0, t1209); + t1380 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t333 * t186 - 0.32e2 / 0.27e2 * t587 * t86 * t280 - 0.8e1 / 0.27e2 * t680 * t194 + 0.8e1 / 0.9e1 * t185 * t1363 + 0.8e1 / 0.9e1 * t276 * t598 - 0.8e1 / 0.27e2 * t509 * t338 * t186 + 0.8e1 / 0.9e1 * t185 * t689 * t86 + 0.4e1 / 0.9e1 * t685 * t194 + 0.4e1 / 0.3e1 * t23 * t1376); + t1394 = -0.5e1 / 0.18e2 * t1013 + t1020 - 0.3e1 / 0.8e1 * t5 * t1380 * t26 * t48 - 0.11e2 / 0.72e2 * t703 * t242 - 0.11e2 / 0.108e3 * t1227 + 0.5e1 / 0.162e3 * t1067 - t1071 / 0.54e2 - t1073 / 0.486e3 + 0.11e2 / 0.324e3 * t1086 + t1235 / 0.18e2 - t1242 / 0.27e2; + t1396 = my_piecewise3(t1, 0, t1331 * t111 / 0.12e2 + t1336 / 0.36e2 + t703 * t236 / 0.108e3 + t1253 / 0.162e3 - t1343 / 0.4e1 + t1347 / 0.12e2 - t1182 / 0.4e1 + t1186 / 0.3e1 - 0.5e1 / 0.18e2 * t1190 + t1009 / 0.12e2 + t1394); + t1402 = t5 * t650 * t100; + t1408 = t5 * t724 * t95 * t77; + t1412 = t5 * t359 * t212 * t77; + t1427 = t305 * t305; + t1440 = my_piecewise5(t14, 0, t10, 0, t1280); + t1444 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t350 * t249 - 0.32e2 / 0.27e2 * t635 * t118 * t305 - 0.8e1 / 0.27e2 * t711 * t255 + 0.8e1 / 0.9e1 * t248 * t1427 + 0.8e1 / 0.9e1 * t301 * t645 - 0.8e1 / 0.27e2 * t550 * t355 * t249 + 0.8e1 / 0.9e1 * t248 * t720 * t118 + 0.4e1 / 0.9e1 * t716 * t255 + 0.4e1 / 0.3e1 * t59 * t1440); + t1449 = t669 * t387; + t1451 = t673 * t387; + t1453 = t669 * t381; + t1455 = t673 * t381; + t1458 = t5 * t654 * t100; + t1459 = t1458 * t164; + t1462 = t5 * t658 * t100; + t1463 = t1462 * t164; + t1468 = t1164 / 0.12e2 - 0.3e1 / 0.8e1 * t5 * t1444 * t26 * t77 - 0.11e2 / 0.108e3 * t1449 + 0.11e2 / 0.324e3 * t1451 + t1453 / 0.162e3 - t1455 / 0.486e3 + t1459 / 0.18e2 - t1463 / 0.54e2 - t1316 / 0.27e2 + 0.5e1 / 0.162e3 * t1320 + t1312 / 0.36e2; + t1470 = my_piecewise3(t53, 0, t665 * t381 / 0.108e3 - 0.11e2 / 0.72e2 * t665 * t387 + t1402 * t164 / 0.12e2 - 0.5e1 / 0.18e2 * t1301 - t1408 / 0.4e1 + t1412 / 0.12e2 - 0.5e1 / 0.18e2 * t1168 + t1173 - t1293 / 0.4e1 + t1297 / 0.3e1 + t1468); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho4[2] = 0.2e1 * t634 + 0.2e1 * t677 + 0.2e1 * t710 + 0.2e1 * t753 + t6 * (t1396 + t1470); + + t1491 = my_piecewise5(t10, 0, t14, 0, t1208 + t1209); + t1495 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t758 * t86 - 0.8e1 / 0.9e1 * t680 * t280 - 0.8e1 / 0.9e1 * t587 * t338 * t86 + 0.4e1 / 0.3e1 * t590 * t338 + 0.4e1 / 0.3e1 * t276 * t689 + 0.4e1 / 0.9e1 * t185 * t765 * t86 + 0.4e1 / 0.3e1 * t23 * t1491); + t1502 = t5 * t769 * t95 * t48; + t1505 = t5 * t770 * t100; + t1514 = -0.3e1 / 0.8e1 * t5 * t1495 * t26 * t48 - t1502 / 0.8e1 + t1505 * t111 / 0.24e2 - 0.3e1 / 0.8e1 * t1343 + t1347 / 0.4e1 + t1336 / 0.24e2 + t1187 - 0.5e1 / 0.12e2 * t1190 - t1243 - 0.5e1 / 0.36e2 * t1013 + t1020 + 0.5e1 / 0.324e3 * t1067; + t1515 = my_piecewise3(t1, 0, t1514); + t1518 = t5 * t789 * t95 * t77; + t1536 = my_piecewise5(t14, 0, t10, 0, -t1208 + t1280); + t1540 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t778 * t118 - 0.8e1 / 0.9e1 * t711 * t305 - 0.8e1 / 0.9e1 * t635 * t355 * t118 + 0.4e1 / 0.3e1 * t638 * t355 + 0.4e1 / 0.3e1 * t301 * t720 + 0.4e1 / 0.9e1 * t248 * t785 * t118 + 0.4e1 / 0.3e1 * t59 * t1536); + t1549 = t533 * t126; + t1550 = t1549 * t830; + t1552 = t533 * t122; + t1560 = t5 * t725 * t100; + t1565 = -t1518 / 0.8e1 - 0.3e1 / 0.8e1 * t5 * t1540 * t26 * t77 - 0.3e1 / 0.8e1 * t1408 + t1412 / 0.4e1 + t1298 - 0.5e1 / 0.12e2 * t1301 - 0.5e1 / 0.36e2 * t1168 + t1173 + t1550 / 0.162e3 + t1552 * t830 / 0.54e2 - 0.11e2 / 0.24e2 * t735 * t387 + t735 * t381 / 0.36e2 + t1560 * t164 / 0.8e1 - 0.11e2 / 0.108e3 * t320 * t798; + t1568 = t739 * t387; + t1570 = t739 * t381; + t1573 = t5 * t729 * t100; + t1574 = t1573 * t164; + t1576 = t324 * t798; + t1578 = t324 * t804; + t1587 = 0.77e2 / 0.108e3 * t320 * t804 - 0.11e2 / 0.72e2 * t1568 + t1570 / 0.108e3 + t1574 / 0.24e2 - 0.11e2 / 0.324e3 * t1576 + 0.77e2 / 0.324e3 * t1578 - 0.11e2 / 0.72e2 * t1449 + 0.11e2 / 0.108e3 * t1451 + t1453 / 0.108e3 - t1455 / 0.162e3 + t1459 / 0.12e2 - t1463 / 0.18e2 - t1317 + 0.5e1 / 0.108e3 * t1320; + t1589 = my_piecewise3(t53, 0, t1565 + t1587); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho4[3] = 0.3e1 * t710 + 0.3e1 * t753 + t777 + t834 + t6 * (t1515 + t1589); + + t1594 = t333 * t333; + t1599 = t338 * t338; + t1606 = my_piecewise5(t10, 0, t14, 0, 0.24e2 * t517 + 0.24e2 * t1041); + t1610 = my_piecewise3(t20, 0, 0.40e2 / 0.81e2 * t1027 * t1594 - 0.16e2 / 0.9e1 * t680 * t338 + 0.4e1 / 0.3e1 * t185 * t1599 + 0.16e2 / 0.9e1 * t276 * t765 + 0.4e1 / 0.3e1 * t23 * t1606); + t1619 = my_piecewise3(t1, 0, -0.3e1 / 0.8e1 * t5 * t1610 * t26 * t48 - t1502 / 0.2e1 + t1347 / 0.2e1 - 0.5e1 / 0.9e1 * t1190 + t1020); + t1620 = t350 * t350; + t1625 = t355 * t355; + t1632 = my_piecewise5(t14, 0, t10, 0, -0.24e2 * t517 + 0.24e2 * t1146); + t1636 = my_piecewise3(t58, 0, 0.40e2 / 0.81e2 * t1134 * t1620 - 0.16e2 / 0.9e1 * t711 * t355 + 0.4e1 / 0.3e1 * t248 * t1625 + 0.16e2 / 0.9e1 * t301 * t785 + 0.4e1 / 0.3e1 * t59 * t1632); + t1645 = t794 * t376; + t1651 = t533 * t150; + t1657 = t5 * t790 * t100; + t1664 = -0.3e1 / 0.8e1 * t5 * t1636 * t26 * t77 - t1518 / 0.2e1 + t1412 / 0.2e1 - 0.5e1 / 0.9e1 * t1301 + t1173 + 0.2e1 / 0.81e2 * t1550 - 0.11e2 / 0.27e2 * t821 * t824 * t826 / t1645 + 0.2e1 / 0.27e2 * t1651 * t830 + t816 * t381 / 0.18e2 + t1657 * t164 / 0.6e1 - 0.11e2 / 0.27e2 * t366 * t798 + 0.77e2 / 0.27e2 * t366 * t804; + t1684 = t533 * t154; + t1687 = 0.1e1 / t822 / t72 * t1093; + t1688 = t374 * t374; + t1702 = -0.11e2 / 0.12e2 * t816 * t387 + 0.979e3 / 0.972e3 * t155 * t373 * t375 / t65 / t979 - 0.11e2 / 0.18e2 * t1568 + t1570 / 0.27e2 + t1574 / 0.6e1 - 0.11e2 / 0.81e2 * t1576 + 0.77e2 / 0.81e2 * t1578 - 0.1309e4 / 0.324e3 * t155 * t159 * t63 / t66 / t427 + 0.2e1 / 0.243e3 * t1684 * t1687 * t1688 / t66 / t794 / t427 * t28 * t33 + 0.11e2 / 0.54e2 * t1451 - t1455 / 0.81e2 - t1463 / 0.9e1 + 0.5e1 / 0.81e2 * t1320; + t1704 = my_piecewise3(t53, 0, t1664 + t1702); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho4[4] = 0.4e1 * t777 + 0.4e1 * t834 + t6 * (t1619 + t1704); + + t1715 = t218 * t861; + t1731 = 0.5e1 / 0.864e3 * t1066 * t173; + t1732 = t491 * t407; + t1734 = t491 * t403; + t1736 = t218 * t865; + t1738 = t1070 * t173; + t1740 = t485 * t407; + t1742 = t485 * t403; + t1746 = t1076 * t173; + t1761 = t1059 * t856; + t1763 = -0.341e3 / 0.1296e4 * t102 * t226 * t228 * t471 * sigma[0] + 0.3e1 / 0.32e2 * t208 * t861 + t1715 / 0.32e2 - t1090 * t1094 / t37 / t469 / t443 * t539 * t28 * t33 / 0.324e3 + 0.77e2 / 0.108e3 * t102 * t105 * t171 * t462 - t1731 - t1732 / 0.36e2 + t1734 / 0.432e3 - 0.11e2 / 0.72e2 * t1736 + t1738 / 0.96e2 + t1740 / 0.12e2 - t1742 / 0.144e3 - 0.11e2 / 0.24e2 * t208 * t865 - t1746 / 0.64e2 + t481 * t407 / 0.8e1 - t481 * t403 / 0.96e2 + 0.19e2 / 0.144e3 * t534 * t537 * t538 * t542 * t229 - t1112 * t173 / 0.64e2 - t1062 * t856 / 0.48e2 - t1761 / 0.144e3; + t1764 = my_piecewise3(t1, 0, t1763); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[0] = t6 * t1764 + 0.3e1 * t869; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[1] = 0.0e0; + + t1769 = t1311 * t178; + t1771 = t1315 * t178; + t1774 = 0.5e1 / 0.864e3 * t1319 * t178; + t1776 = my_piecewise3(t53, 0, -t1307 * t178 / 0.64e2 - t1769 / 0.64e2 + t1771 / 0.96e2 - t1774); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[2] = t6 * t1776 + 0.3e1 * t879; + + t1778 = 0.2e1 * t893; + t1785 = t1234 * t173 / 0.96e2; + t1790 = t1241 * t173; + t1793 = t620 * t407 / 0.36e2; + t1795 = t620 * t403 / 0.432e3; + t1808 = t294 * t861 / 0.32e2 + t1715 / 0.96e2 - 0.11e2 / 0.72e2 * t294 * t865 - t1785 + t612 * t407 / 0.12e2 - t612 * t403 / 0.144e3 + t1790 / 0.288e3 + t1793 - t1795 - t1731 - t1732 / 0.54e2 + t1734 / 0.648e3 - 0.11e2 / 0.216e3 * t1736 + t1738 / 0.144e3 + t1740 / 0.36e2 - t1742 / 0.432e3 - t1746 / 0.192e3 - t1230 * t173 / 0.64e2 - t1761 / 0.432e3 - t1224 * t856 / 0.144e3; + t1809 = my_piecewise3(t1, 0, t1808); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[3] = t6 * t1809 + t1778 + t869; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[4] = 0.0e0; + + t1811 = 0.2e1 * t909; + t1815 = t1458 * t178 / 0.96e2; + t1816 = t1462 * t178; + t1823 = t669 * t432 / 0.432e3; + t1824 = t673 * t432; + t1829 = t669 * t436 / 0.36e2; + t1830 = t673 * t436; + t1832 = -t1402 * t178 / 0.64e2 - t1815 + t1816 / 0.288e3 - t1769 / 0.192e3 + t1771 / 0.144e3 - t1774 - t665 * t432 / 0.288e3 - t1823 + t1824 / 0.1296e4 + t665 * t436 / 0.24e2 + t1829 - t1830 / 0.108e3; + t1833 = my_piecewise3(t53, 0, t1832); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[5] = t6 * t1833 + t1811 + t879; + + t1837 = t1335 * t173; + t1847 = -t1331 * t173 / 0.64e2 - t1837 / 0.192e3 - t703 * t403 / 0.288e3 + t703 * t407 / 0.24e2 - t1785 + t1790 / 0.144e3 - t1795 + t1793 + t1738 / 0.288e3 - t1731 + t1734 / 0.1296e4 - t1732 / 0.108e3; + t1848 = my_piecewise3(t1, 0, t1847); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[6] = t6 * t1848 + t1778 + t916; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[7] = 0.0e0; + + t1852 = t1573 * t178; + t1857 = t739 * t432; + t1861 = t739 * t436; + t1868 = t1549 * t932; + t1872 = t324 * t937; + t1876 = t324 * t941; + t1878 = -t1560 * t178 / 0.64e2 - t1852 / 0.192e3 - t1815 + t1816 / 0.144e3 - t735 * t432 / 0.144e3 - t1857 / 0.432e3 + t735 * t436 / 0.12e2 + t1861 / 0.36e2 + t1771 / 0.288e3 - t1774 - t1823 + t1824 / 0.648e3 + t1829 - t1830 / 0.54e2 - t1552 * t932 / 0.144e3 - t1868 / 0.432e3 + t320 * t937 / 0.32e2 + t1872 / 0.96e2 - 0.11e2 / 0.72e2 * t320 * t941 - 0.11e2 / 0.216e3 * t1876; + t1879 = my_piecewise3(t53, 0, t1878); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[8] = t6 * t1879 + t1811 + t945; + + t1887 = my_piecewise3(t1, 0, -t1505 * t173 / 0.64e2 - t1837 / 0.64e2 + t1790 / 0.96e2 - t1731); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[9] = t6 * t1887 + 0.3e1 * t916; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[10] = 0.0e0; + + t1934 = -0.341e3 / 0.1296e4 * t155 * t373 * t228 * t796 * sigma[2] + 0.3e1 / 0.32e2 * t366 * t937 + t1872 / 0.32e2 - t1857 / 0.144e3 + t1824 / 0.432e3 - t1684 * t1687 / t66 / t794 / t451 * t825 * t28 * t33 / 0.324e3 + 0.77e2 / 0.108e3 * t155 * t158 * t171 * t802 + t816 * t436 / 0.8e1 - t816 * t432 / 0.96e2 - 0.11e2 / 0.24e2 * t366 * t941 - 0.11e2 / 0.72e2 * t1876 - t1852 / 0.64e2 + t1861 / 0.12e2 - t1830 / 0.36e2 + t1816 / 0.96e2 - t1774 + 0.19e2 / 0.144e3 * t821 * t824 * t538 * t828 * t374 - t1657 * t178 / 0.64e2 - t1868 / 0.144e3 - t1651 * t932 / 0.48e2; + t1935 = my_piecewise3(t53, 0, t1934); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho3sigma[11] = t6 * t1935 + 0.3e1 * t945; + + t1940 = t485 * t447; + t1947 = t491 * t447 / 0.3456e4; + t1948 = t1059 * t955; + t1950 = t218 * t959; + t1969 = my_piecewise3(t1, 0, t481 * t447 / 0.768e3 + t1940 / 0.1152e4 + t1062 * t955 / 0.192e3 - t208 * t959 / 0.72e2 - t1947 + t1948 / 0.576e3 - t1950 / 0.216e3 + t1090 * t1094 / t37 / t1053 * t229 * t28 * t33 / 0.864e3 - 0.43e2 / 0.1152e4 * t534 * t537 * t854 * sigma[0] + 0.19e2 / 0.432e3 * t102 * t224 * t442 * t234); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[0] = t6 * t1969 + 0.2e1 * t963; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[1] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[2] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[3] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[4] = 0.0e0; + + t1974 = t669 * t455; + t1977 = t673 * t455 / 0.3456e4; + t1979 = my_piecewise3(t53, 0, t665 * t455 / 0.768e3 + t1974 / 0.1152e4 - t1977); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[5] = t6 * t1979 + 0.2e1 * t970; + + t1983 = t620 * t447; + t1993 = my_piecewise3(t1, 0, t612 * t447 / 0.768e3 + t1983 / 0.2304e4 + t1224 * t955 / 0.384e3 - t294 * t959 / 0.144e3 + t1940 / 0.2304e4 - t1947 + t1948 / 0.1152e4 - t1950 / 0.432e3); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[6] = t6 * t1993 + t963 + t975; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[7] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[8] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[9] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[10] = 0.0e0; + + t1997 = t739 * t455; + t2002 = t1549 * t983; + t2006 = t324 * t987; + t2009 = my_piecewise3(t53, 0, t735 * t455 / 0.768e3 + t1997 / 0.2304e4 + t1974 / 0.2304e4 - t1977 + t1552 * t983 / 0.384e3 + t2002 / 0.1152e4 - t320 * t987 / 0.144e3 - t2006 / 0.432e3); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[11] = t6 * t2009 + t970 + t991; + + t2016 = my_piecewise3(t1, 0, t703 * t447 / 0.768e3 + t1983 / 0.1152e4 - t1947); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[12] = t6 * t2016 + 0.2e1 * t975; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[13] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[14] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[15] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[16] = 0.0e0; + + t2045 = my_piecewise3(t53, 0, t816 * t455 / 0.768e3 + t1997 / 0.1152e4 + t1651 * t983 / 0.192e3 - t366 * t987 / 0.72e2 - t1977 + t2002 / 0.576e3 - t2006 / 0.216e3 + t1684 * t1687 / t66 / t1645 * t374 * t28 * t33 / 0.864e3 - 0.43e2 / 0.1152e4 * t821 * t824 * t930 * sigma[2] + 0.19e2 / 0.432e3 * t155 * t372 * t442 * t379); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rho2sigma2[17] = t6 * t2045 + 0.2e1 * t991; + + t2050 = t1059 * t995 / 0.3072e4; + t2062 = my_piecewise3(t1, 0, -t1062 * t995 / 0.1024e4 - t2050 - t1090 * t1094 / t37 / t541 * t171 * sigma[0] / 0.2304e4 + t534 * t537 * t953 / 0.128e3); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[0] = t6 * t2062 + t998; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[1] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[2] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[3] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[4] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[5] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[6] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[7] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[8] = 0.0e0; + + t2067 = t1549 * t1001 / 0.3072e4; + t2069 = my_piecewise3(t53, 0, -t1552 * t1001 / 0.1024e4 - t2067); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[9] = t6 * t2069 + t1004; + + t2074 = my_piecewise3(t1, 0, -t1224 * t995 / 0.1024e4 - t2050); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[10] = t6 * t2074 + t998; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[11] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[12] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[13] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[14] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[15] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[16] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[17] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[18] = 0.0e0; + + t2089 = my_piecewise3(t53, 0, -t1651 * t1001 / 0.1024e4 - t2067 - t1684 * t1687 / t66 / t827 * t171 * sigma[2] / 0.2304e4 + t821 * t824 * t981 / 0.128e3); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4rhosigma3[19] = t6 * t2089 + t1004; + + t2098 = my_piecewise3(t1, 0, t1090 * t1094 / t37 / t852 * t28 * t33 / 0.6144e4); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[0] = t6 * t2098; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[1] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[2] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[3] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[4] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[5] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[6] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[7] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[8] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[9] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[10] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[11] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[12] = 0.0e0; + + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[13] = 0.0e0; + + t2106 = my_piecewise3(t53, 0, t1684 * t1687 / t66 / t928 * t28 * t33 / 0.6144e4); + if(v4rho4 != NULL && (p->info->flags & XC_FLAGS_HAVE_LXC)) + v4sigma4[14] = t6 * t2106; + +#ifndef XC_DONT_COMPILE_MXC + + if(order < 5) return; + + +#endif + +#endif + +#endif + +#endif + +#endif + + +} + diff --git a/ref/libxc/work_gga.h b/ref/libxc/work_gga.h new file mode 100644 index 0000000000000000000000000000000000000000..7e326d0e574e1df8d2a6a9882da8fc2099028023 --- /dev/null +++ b/ref/libxc/work_gga.h @@ -0,0 +1,188 @@ +/* + Copyright (C) 2006-2018 M.A.L. Marques + Copyright (C) 2019 X. Andrade + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +/** + * @file work_gga.c + * @brief This file is to be included in GGA functionals. + */ + +#ifdef XC_DEBUG +#define __USE_GNU +#include <fenv.h> +#endif + +#include "../common/xc.h" + +/* hack to avoid compiler warnings */ +#define NOARG + +#ifdef XC_NO_EXC +#define OUT_PARAMS GGA_OUT_PARAMS_NO_EXC(XC_COMMA, ) +#else +#define OUT_PARAMS XC_COMMA zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA, ) +#endif + +#ifdef HAVE_CUDA +__global__ static void +work_gga_gpu(const XC(func_type) *p, int order, size_t np, const double *rho, const double *sigma, + double *zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )); +#endif + +/** + * @param[in,out] func_type: pointer to functional structure + */ +static void +work_gga(const XC(func_type) *p, size_t np, + const double *rho, const double *sigma, + double *zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )) +{ + int order = -1; + + if(zk != NULL) order = 0; + if(vrho != NULL) order = 1; + if(v2rho2 != NULL) order = 2; + if(v3rho3 != NULL) order = 3; + if(v4rho4 != NULL) order = 4; + + if(order < 0) return; + +#ifdef XC_DEBUG + /* This throws an exception when floating point errors are encountered */ + /*feenableexcept(FE_DIVBYZERO | FE_INVALID);*/ +#endif + +#ifdef HAVE_CUDA + + //make a copy of 'p' since it might be in host-only memory + XC(func_type) * pcuda = (XC(func_type) *) libxc_malloc(sizeof(XC(func_type))); + + *pcuda = *p; + + size_t nblocks = np/CUDA_BLOCK_SIZE; + if(np != nblocks*CUDA_BLOCK_SIZE) nblocks++; + + work_gga_gpu<<<nblocks, CUDA_BLOCK_SIZE>>>(pcuda, order, np, rho, sigma, + zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA, )); + + libxc_free(pcuda); + +#else + size_t ip; + double dens; + double my_rho[2] = {0.0, 0.0}; + double my_sigma[3] = {0.0, 0.0, 0.0}; + + for(ip = 0; ip < np; ip++){ + /* Screen low density */ + dens = (p->nspin == XC_POLARIZED) ? rho[0] + rho[1] : rho[0]; + if(dens >= p->dens_threshold) { + /* sanity check of input parameters */ + my_rho[0] = m_max(p->dens_threshold, rho[0]); + my_sigma[0] = m_max(p->sigma_threshold * p->sigma_threshold, sigma[0]); + if(p->nspin == XC_POLARIZED){ + double s_ave; + + my_rho[1] = m_max(p->dens_threshold, rho[1]); + my_sigma[2] = m_max(p->sigma_threshold * p->sigma_threshold, sigma[2]); + + my_sigma[1] = sigma[1]; + s_ave = 0.5*(my_sigma[0] + my_sigma[2]); + /* | grad n |^2 = |grad n_up + grad n_down|^2 > 0 */ + my_sigma[1] = (my_sigma[1] >= -s_ave ? my_sigma[1] : -s_ave); + /* Since |grad n_up - grad n_down|^2 > 0 we also have */ + my_sigma[1] = (my_sigma[1] <= +s_ave ? my_sigma[1] : +s_ave); + } + + if(p->nspin == XC_UNPOLARIZED) + func_unpol(p, order, my_rho, my_sigma OUT_PARAMS); + else if(p->nspin == XC_POLARIZED) + func_pol (p, order, my_rho, my_sigma OUT_PARAMS); + } + + /* check for NaNs */ +#ifdef XC_DEBUG + { + size_t ii; + const xc_dimensions *dim = &(p->dim); + int is_OK = 1; + + if(zk != NULL) + is_OK = is_OK & isfinite(*zk); + + if(vrho != NULL){ + for(ii=0; ii < dim->vrho; ii++) + is_OK = is_OK && isfinite(vrho[ii]); + for(ii=0; ii < dim->vsigma; ii++) + is_OK = is_OK && isfinite(vsigma[ii]); + } + + if(!is_OK){ + printf("Problem in the evaluation of the functional\n"); + if(p->nspin == XC_UNPOLARIZED){ + printf("./xc-get_data %d 1 %le 0.0 %le 0.0 0.0 0.0 0.0 0.0 0.0\n", + p->info->number, *rho, *sigma); + }else{ + printf("./xc-get_data %d 2 %le %le %le %le %le 0.0 0.0 0.0 0.0\n", + p->info->number, rho[0], rho[1], sigma[0], sigma[1], sigma[2]); + } + } + } +#endif + + internal_counters_gga_next(&(p->dim), 0, &rho, &sigma, + &zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA &, )); + } /* for(ip) */ + +#endif +} + +#ifdef HAVE_CUDA + +__global__ static void +work_gga_gpu(const XC(func_type) *p, int order, size_t np, const double *rho, const double *sigma, + double *zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA double *, )) +{ + size_t ip = blockIdx.x*blockDim.x + threadIdx.x; + double dens; + double my_rho[2] = {0.0, 0.0}; + double my_sigma[3] = {0.0, 0.0, 0.0}; + + if(ip >= np) return; + + internal_counters_gga_random(&(p->dim), ip, 0, &rho, &sigma, + &zk GGA_OUT_PARAMS_NO_EXC(XC_COMMA &, )); + + /* Density screening */ + dens = (p->nspin == XC_POLARIZED) ? rho[0]+rho[1] : rho[0]; + if(dens >= p->dens_threshold) { + /* sanity check on input parameters */ + my_rho[0] = m_max(p->dens_threshold, rho[0]); + my_sigma[0] = m_max(p->sigma_threshold * p->sigma_threshold, sigma[0]); + if(p->nspin == XC_POLARIZED){ + double s_ave; + + my_rho[1] = m_max(p->dens_threshold, rho[1]); + my_sigma[2] = m_max(p->sigma_threshold * p->sigma_threshold, sigma[2]); + + my_sigma[1] = sigma[1]; + s_ave = 0.5*(my_sigma[0] + my_sigma[2]); + /* | grad n |^2 = |grad n_up + grad n_down|^2 > 0 */ + my_sigma[1] = (my_sigma[1] >= -s_ave ? my_sigma[1] : -s_ave); + /* Since |grad n_up - grad n_down|^2 > 0 we also have */ + my_sigma[1] = (my_sigma[1] <= +s_ave ? my_sigma[1] : +s_ave); + } + + if(p->nspin == XC_UNPOLARIZED) + func_unpol(p, order, my_rho, my_sigma OUT_PARAMS); + else if(p->nspin == XC_POLARIZED) + func_pol (p, order, my_rho, my_sigma OUT_PARAMS); + } +} + +#endif diff --git a/ref/main.c b/ref/main.c new file mode 100644 index 0000000000000000000000000000000000000000..179d4397b8a2b5004be8d9a1582b2956c74fc448 --- /dev/null +++ b/ref/main.c @@ -0,0 +1,159 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <float.h> +#include "common/xc.h" +#include "libxc/gga_x_pbe.h" +#include "genxc/gga_x_pbe_genxc.h" + +// Precision for correctness checking +#define EPSILON 0.00000001 + +int nearlyEqual(double a, double b) { + //double abs_a = abs(a); + //double abs_b = abs(b); + double diff = abs(a - b); + + //if(a == b) { return 1; } + //if(a == 0 || b == 0 || abs_a + abs_b < MIN_NORMAL) { return diff < (EPSILON * MIN_NORMAL); } + //return (diff / min((abs_a + abs_b), DBL_MAX)) < EPSILON; + return diff < EPSILON; +} + +double getTimeStamp() { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (double)ts.tv_sec + (double)ts.tv_nsec * 1.e-9; +} + +int main() { + xc_func_type gga_libxc, gga_genxc; + int i; + int npoints = 10000000; + //int npoints = 100; + double *rho_libxc, *sigma_libxc; + double *rho_genxc, *sigma_genxc; + double *zk_libxc, *vrho_libxc, *vsigma_libxc; + double *zk_genxc, *vrho_genxc, *vsigma_genxc; + double *v2rho2_libxc, *v2rhosigma_libxc, *v2sigma2_libxc; + double *v2rho2_genxc, *v2rhosigma_genxc, *v2sigma2_genxc; + double *v3rho3_libxc, *v3rho2sigma_libxc, *v3rhosigma2_libxc, *v3sigma3_libxc; + double *v3rho3_genxc, *v3rho2sigma_genxc, *v3rhosigma2_genxc, *v3sigma3_genxc; + double *v4rho4_libxc, *v4rho3sigma_libxc, *v4rho2sigma2_libxc, *v4rhosigma3_libxc, *v4sigma4_libxc; + double *v4rho4_genxc, *v4rho3sigma_genxc, *v4rho2sigma2_genxc, *v4rhosigma3_genxc, *v4sigma4_genxc; + double S, E; + + rho_libxc = (double*) malloc( 2*npoints*sizeof(double)); + sigma_libxc = (double*) malloc( 3*npoints*sizeof(double)); + zk_libxc = (double*) malloc( 1*npoints*sizeof(double)); + vrho_libxc = (double*) malloc( 2*npoints*sizeof(double)); + vsigma_libxc = (double*) malloc( 3*npoints*sizeof(double)); + v2rho2_libxc = (double*) malloc( 3*npoints*sizeof(double)); + v2rhosigma_libxc = (double*) malloc( 6*npoints*sizeof(double)); + v2sigma2_libxc = (double*) malloc( 6*npoints*sizeof(double)); + rho_genxc = (double*) malloc( 2*npoints*sizeof(double)); + sigma_genxc = (double*) malloc( 3*npoints*sizeof(double)); + zk_genxc = (double*) malloc( 1*npoints*sizeof(double)); + vrho_genxc = (double*) malloc( 2*npoints*sizeof(double)); + vsigma_genxc = (double*) malloc( 3*npoints*sizeof(double)); + v2rho2_genxc = (double*) malloc( 3*npoints*sizeof(double)); + v2rhosigma_genxc = (double*) malloc( 6*npoints*sizeof(double)); + v2sigma2_genxc = (double*) malloc( 6*npoints*sizeof(double)); + #ifdef KXC + v3rho3_libxc = (double*) malloc( 4*npoints*sizeof(double)); + v3rho2sigma_libxc = (double*) malloc( 9*npoints*sizeof(double)); + v3rhosigma2_libxc = (double*) malloc(12*npoints*sizeof(double)); + v3sigma3_libxc = (double*) malloc(10*npoints*sizeof(double)); + v3rho3_genxc = (double*) malloc( 4*npoints*sizeof(double)); + v3rho2sigma_genxc = (double*) malloc( 9*npoints*sizeof(double)); + v3rhosigma2_genxc = (double*) malloc(12*npoints*sizeof(double)); + v3sigma3_genxc = (double*) malloc(10*npoints*sizeof(double)); + #else + v3rho3_libxc = (double*) NULL; + v3rho2sigma_libxc = (double*) NULL; + v3rhosigma2_libxc = (double*) NULL; + v3sigma3_libxc = (double*) NULL; + v3rho3_genxc = (double*) NULL; + v3rho2sigma_genxc = (double*) NULL; + v3rhosigma2_genxc = (double*) NULL; + v3sigma3_genxc = (double*) NULL; + #endif + #ifdef LXC + v4rho4_libxc = (double*) malloc( 5*npoints*sizeof(double)); + v4rho3sigma_libxc = (double*) malloc(12*npoints*sizeof(double)); + v4rho2sigma2_libxc = (double*) malloc(18*npoints*sizeof(double)); + v4rhosigma3_libxc = (double*) malloc(20*npoints*sizeof(double)); + v4sigma4_libxc = (double*) malloc(15*npoints*sizeof(double)); + v4rho4_genxc = (double*) malloc( 5*npoints*sizeof(double)); + v4rho3sigma_genxc = (double*) malloc(12*npoints*sizeof(double)); + v4rho2sigma2_genxc = (double*) malloc(18*npoints*sizeof(double)); + v4rhosigma3_genxc = (double*) malloc(20*npoints*sizeof(double)); + v4sigma4_genxc = (double*) malloc(15*npoints*sizeof(double)); + #else + v4rho4_libxc = (double*) NULL; + v4rho3sigma_libxc = (double*) NULL; + v4rho2sigma2_libxc = (double*) NULL; + v4rhosigma3_libxc = (double*) NULL; + v4sigma4_libxc = (double*) NULL; + v4rho4_genxc = (double*) NULL; + v4rho3sigma_genxc = (double*) NULL; + v4rho2sigma2_genxc = (double*) NULL; + v4rhosigma3_genxc = (double*) NULL; + v4sigma4_genxc = (double*) NULL; + #endif + + if(xc_func_init(&gga_genxc, XC_GGA_X_BCGP_GENXC, XC_POLARIZED) < 0) { + fprintf(stderr, "XC_GGA_X_BCGP_GENXC not found!\n"); + return -1; + } + + for(i=0; i<npoints; i++){ + rho_genxc[2*i + 0] = 0.048 + i/(double)(npoints); + rho_genxc[2*i + 1] = 0.025; + sigma_genxc[3*i + 0] = 0.0046; + sigma_genxc[3*i + 1] = 0.0044; + sigma_genxc[3*i + 2] = 0.0041; + } + + S = getTimeStamp(); + xc_gga( + &gga_genxc, npoints, rho_genxc, sigma_genxc, zk_genxc, vrho_genxc, vsigma_genxc, v2rho2_genxc, v2rhosigma_genxc, v2sigma2_genxc, + v3rho3_genxc, v3rho2sigma_genxc, v3rhosigma2_genxc, v3sigma3_genxc, v4rho4_genxc, v4rho3sigma_genxc, v4rho2sigma2_genxc, + v4rhosigma3_genxc, v4sigma4_genxc + ); + E = getTimeStamp(); + fprintf(stderr, "GGA_X_PBE_GENXC: %.4fs\n", E-S); + + if(xc_func_init(&gga_libxc, XC_GGA_X_BCGP, XC_POLARIZED) < 0) { + fprintf(stderr, "XC_GGA_X_BCGP not found!\n"); + return -1; + } + + for(i=0; i<npoints; i++){ + rho_libxc[2*i + 0] = 0.048 + i/(double)(npoints); + rho_libxc[2*i + 1] = 0.025; + sigma_libxc[3*i + 0] = 0.0046; + sigma_libxc[3*i + 1] = 0.0044; + sigma_libxc[3*i + 2] = 0.0041; + } + + S = getTimeStamp(); + xc_gga( + &gga_libxc, npoints, rho_libxc, sigma_libxc, zk_libxc, vrho_libxc, vsigma_libxc, v2rho2_libxc, v2rhosigma_libxc, v2sigma2_libxc, + v3rho3_libxc, v3rho2sigma_libxc, v3rhosigma2_libxc, v3sigma3_libxc, v4rho4_libxc, v4rho3sigma_libxc, v4rho2sigma2_libxc, + v4rhosigma3_libxc, v4sigma4_libxc + ); + E = getTimeStamp(); + fprintf(stderr, "GGA_X_PBE: %.4fs\n", E-S); + + #define CHECK_CORRECTNESS(arr1,arr2,i); if(!nearlyEqual(arr1[i], arr2[i])) { fprintf(stderr, "Results differ!\n"); return -1; } + for(i = 0; i < npoints; i++) { + CHECK_CORRECTNESS(rho_libxc, rho_genxc, 2 * i + 0); + CHECK_CORRECTNESS(vrho_libxc, vrho_genxc, 2 * i + 0); + CHECK_CORRECTNESS(v2rho2_libxc, v2rho2_genxc, 3 * i + 0); + } + + xc_func_end(&gga_libxc); + xc_func_end(&gga_genxc); + return 0; +}