-
Notifications
You must be signed in to change notification settings - Fork 0
/
libpaw_libxc.c
330 lines (309 loc) · 13.3 KB
/
libpaw_libxc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/*
* Copyright (C) 2015-2022 ABINIT group (MT)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/* ===============================================================
* Set of C functions interfacing the LibXC library.
* (see http://www.tddft.org/programs/Libxc)
* ===============================================================
*/
#include "libpaw.h"
#include <stdlib.h>
#include <stdio.h>
#if defined LIBPAW_HAVE_LIBXC
#include "xc.h"
#include "xc_version.h"
#include "xc_funcs.h"
/* if version before 4 get config file */
#if ( XC_MAJOR_VERSION < 4 )
# include "xc_config.h"
#else
# define FLOAT double
#endif
/* ===============================================================
* Get the SINGLE_PRECISION constant
* ===============================================================
*/
void libpaw_xc_get_singleprecision_constant(int *xc_cst_singleprecision)
{
if (sizeof(FLOAT)<sizeof(double))
{*xc_cst_singleprecision = 1;}
else
{*xc_cst_singleprecision = 0;}
}
/* ===============================================================
* Get the FAMILY constants
* ===============================================================
*/
void libpaw_xc_get_family_constants(int *xc_cst_family_unknown,
int *xc_cst_family_lda,
int *xc_cst_family_gga,
int *xc_cst_family_mgga,
int *xc_cst_family_lca,
int *xc_cst_family_oep,
int *xc_cst_family_hyb_gga,
int *xc_cst_family_hyb_mgga,
int *xc_cst_family_hyb_lda)
{
*xc_cst_family_unknown = XC_FAMILY_UNKNOWN;
*xc_cst_family_lda = XC_FAMILY_LDA;
*xc_cst_family_gga = XC_FAMILY_GGA;
*xc_cst_family_mgga = XC_FAMILY_MGGA;
*xc_cst_family_lca = XC_FAMILY_LCA;
*xc_cst_family_oep = XC_FAMILY_OEP;
*xc_cst_family_hyb_gga = XC_FAMILY_HYB_GGA;
*xc_cst_family_hyb_mgga = XC_FAMILY_HYB_MGGA;
#if ( XC_MAJOR_VERSION > 5 )
/* ==== libXC v6.0 and later ==== */
*xc_cst_family_hyb_lda = XC_FAMILY_HYB_LDA;
#else
/* ==== Before libXC v6.0 ==== */
*xc_cst_family_hyb_lda = -11;
#endif
}
/* ===============================================================
* Get the FLAGS constants
* ===============================================================
*/
void libpaw_xc_get_flags_constants(int *xc_cst_flags_have_exc,
int *xc_cst_flags_have_vxc,
int *xc_cst_flags_have_fxc,
int *xc_cst_flags_have_kxc,
int *xc_cst_flags_have_lxc,
int *xc_cst_flags_needs_laplacian)
{
*xc_cst_flags_have_exc = XC_FLAGS_HAVE_EXC;
*xc_cst_flags_have_vxc = XC_FLAGS_HAVE_VXC;
*xc_cst_flags_have_fxc = XC_FLAGS_HAVE_FXC;
*xc_cst_flags_have_kxc = XC_FLAGS_HAVE_KXC;
*xc_cst_flags_have_lxc = XC_FLAGS_HAVE_LXC;
#if ( XC_MAJOR_VERSION > 3 )
*xc_cst_flags_needs_laplacian = XC_FLAGS_NEEDS_LAPLACIAN;
#else
*xc_cst_flags_needs_laplacian = 1;
#endif
}
/* ===============================================================
* Get the KIND constants
* ===============================================================
*/
void libpaw_xc_get_kind_constants(int *xc_cst_exchange,
int *xc_cst_correlation,
int *xc_cst_exchange_correlation,
int *xc_cst_kinetic)
{
*xc_cst_exchange = XC_EXCHANGE;
*xc_cst_correlation = XC_CORRELATION;
*xc_cst_exchange_correlation = XC_EXCHANGE_CORRELATION;
*xc_cst_kinetic = XC_KINETIC;
}
/* ===============================================================
* Allocate/free xc_func_type pointer
* ===============================================================
*/
XC(func_type) * libpaw_xc_func_type_malloc()
{return (XC(func_type) *) malloc(sizeof(XC(func_type)));}
void libpaw_xc_func_type_free(XC(func_type) **xc_func)
{free(*xc_func);*xc_func = NULL;}
/* ===============================================================
* Wrappers to the LDA/GGA/MGGA functionals
* ===============================================================
*/
/* ---------------------------------------------------------------
----- LDA ----- */
void libpaw_xc_get_lda(const XC(func_type) *xc_func, int np, const double *rho,
double *zk, double *vrho, double *v2rho2, double *v3rho3)
#if ( XC_MAJOR_VERSION > 4 )
/* ==== libXC v5.0 and later ==== */
{xc_lda(xc_func, np, rho, zk, vrho, v2rho2, v3rho3, NULL);}
#else
/* ==== Before libXC v5.0 ==== */
{xc_lda(xc_func, np, rho, zk, vrho, v2rho2, v3rho3);}
#endif
/* ---------------------------------------------------------------
----- GGA ----- */
void libpaw_xc_get_gga(const XC(func_type) *xc_func, int 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)
#if ( XC_MAJOR_VERSION > 4 )
/* ==== libXC v5.0 and later ==== */
{xc_gga(xc_func, np, rho, sigma, zk, vrho, vsigma, v2rho2, v2rhosigma, v2sigma2,
v3rho3, v3rho2sigma, v3rhosigma2, v3sigma3,
NULL, NULL, NULL, NULL, NULL);}
#else
/* ==== Before libXC v5.0 ==== */
{xc_gga(xc_func, np, rho, sigma, zk, vrho, vsigma, v2rho2, v2rhosigma, v2sigma2,
v3rho3, v3rho2sigma, v3rhosigma2, v3sigma3);}
#endif
/* ---------------------------------------------------------------
----- meta-GGA ----- */
void libpaw_xc_get_mgga(const XC(func_type) *xc_func, int 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)
#if ( XC_MAJOR_VERSION > 4 )
/* ==== libXC v5.0 and later ==== */
{xc_mgga(xc_func, np, rho, sigma, lapl, tau, zk, vrho, vsigma, vlapl, vtau,
v2rho2, v2rhosigma, v2rholapl, v2rhotau, v2sigma2,
v2sigmalapl, v2sigmatau, v2lapl2, v2lapltau, v2tau2,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
#else
/* ==== Before libXC v5.0 ==== */
{xc_mgga(xc_func, np, rho, sigma, lapl, tau, zk, vrho, vsigma, vlapl, vtau,
v2rho2, v2sigma2, v2lapl2, v2tau2, v2rhosigma, v2rholapl, v2rhotau,
v2sigmalapl, v2sigmatau, v2lapltau);}
#endif
/* ===============================================================
* Get properties from a xc_func_info_type pointer
* These accessors where not provided before libXC v3
* ===============================================================
*/
#if ( XC_MAJOR_VERSION > 3 )
/* ==== libXC v4.0 and later ==== */
char const *libpaw_xc_get_info_name(XC(func_type) *xc_func)
{return xc_func_info_get_name(xc_func->info);}
int libpaw_xc_get_info_flags(XC(func_type) *xc_func)
{return xc_func_info_get_flags(xc_func->info);}
int libpaw_xc_get_info_kind(XC(func_type) *xc_func)
{return xc_func_info_get_kind(xc_func->info);}
char const *libpaw_xc_get_info_refs(XC(func_type) *xc_func, const int *number)
{if (*number>=0&&*number<XC_MAX_REFERENCES)
{if (xc_func_info_get_references(xc_func->info,*number) != NULL)
{return xc_func_info_get_references(xc_func->info,*number)->ref;}}
else {return NULL;}
return NULL;}
#elif ( XC_MAJOR_VERSION > 2 )
/* ==== libXC v3.0 ==== */
char const *libpaw_xc_get_info_name(XC(func_type) *xc_func)
{return xc_func_info_get_name(xc_func->info);}
int libpaw_xc_get_info_flags(XC(func_type) *xc_func)
{return xc_func_info_get_flags(xc_func->info);}
int libpaw_xc_get_info_kind(XC(func_type) *xc_func)
{return xc_func_info_get_kind(xc_func->info);}
char const *libpaw_xc_get_info_refs(XC(func_type) *xc_func, const int *number)
{if (*number>=0&&*number<=4)
{if (xc_func_info_get_ref(xc_func->info,*number) != NULL)
{return xc_func_info_get_ref(xc_func->info,*number);}}
else {return NULL;}
return NULL;}
#else
/* ==== Before libXC v3.0 ==== */
char const *libpaw_xc_get_info_name(XC(func_type) *xc_func)
{return xc_func->info->name;}
int libpaw_xc_get_info_flags(XC(func_type) *xc_func)
{return xc_func->info->flags;}
int libpaw_xc_get_info_kind(XC(func_type) *xc_func)
{return xc_func->info->kind;}
char const *libpaw_xc_get_info_refs(XC(func_type) *xc_func, const int *number)
{if (*number==0) {return xc_func->info->refs;} else {return NULL;}
return NULL;}
#endif
/* ===============================================================
* Wrapper to xc_func_set_ext_params for backward compatibility
* Allows to change the parameters of a XC functional
* ===============================================================
*/
void libpaw_xc_func_set_params(XC(func_type) *xc_func, double *ext_params, int n_ext_params)
#if ( XC_MAJOR_VERSION > 4 )
/* ==== libXC v5.0 and later ==== */
{if (n_ext_params == xc_func->info->ext_params.n)
{xc_func_set_ext_params(xc_func, ext_params);}
#elif ( XC_MAJOR_VERSION > 3 )
/* ==== libXC v4.0 ==== */
{if (xc_func->info->number == XC_HYB_GGA_XC_PBEH && n_ext_params == 1)
/* set_ext_params function is missing for PBE0 */
{xc_func->cam_alpha=ext_params[0];xc_func->mix_coef[0]=1.0-ext_params[0];}
else if (xc_func->info->number == XC_MGGA_X_TB09 && n_ext_params >=1)
/* XC_MGGA_X_TB09 has only one parameter */
{XC(func_set_ext_params)(xc_func, ext_params);}
else if (n_ext_params == xc_func->info->n_ext_params)
{XC(func_set_ext_params)(xc_func, ext_params);}
#else
/* ==== Before libXC v4.0 ==== */
{if (xc_func->info->number == XC_LDA_C_XALPHA && n_ext_params == 1)
{XC(lda_c_xalpha_set_params)(xc_func, *ext_params);}
else if (xc_func->info->number == XC_MGGA_X_TB09 && n_ext_params >= 1)
{XC(mgga_x_tb09_set_params)(xc_func, ext_params[0]);}
#if ( XC_MAJOR_VERSION > 2 || ( XC_MAJOR_VERSION > 1 && XC_MINOR_VERSION > 0 ) )
else if (xc_func->info->number == XC_HYB_GGA_XC_PBEH && n_ext_params == 1)
{XC(hyb_gga_xc_pbeh_set_params)(xc_func, *ext_params);}
else if (xc_func->info->number == XC_HYB_GGA_XC_HSE03 && n_ext_params == 3)
{XC(hyb_gga_xc_hse_set_params)(xc_func, ext_params[0], ext_params[2]);
xc_func->cam_omega=ext_params[1];}
else if (xc_func->info->number == XC_HYB_GGA_XC_HSE06 && n_ext_params == 3)
{XC(hyb_gga_xc_hse_set_params)(xc_func, ext_params[0], ext_params[2]);
xc_func->cam_omega=ext_params[1];}
#else
else if (xc_func->info->number == XC_HYB_GGA_XC_HSE03 && n_ext_params == 3)
{XC(hyb_gga_xc_hse_set_params)(xc_func, ext_params[2]);
xc_func->cam_omega=ext_params[1];}
else if (xc_func->info->number == XC_HYB_GGA_XC_HSE06 && n_ext_params == 3)
{XC(hyb_gga_xc_hse_set_params)(xc_func, ext_params[2]);
xc_func->cam_omega=ext_params[1];}
#endif
#endif
else
{fprintf(stderr, "BUG: invalid entry in set_params!\n");abort();}
}
/* ===============================================================
* Wrapper to xc_func_set_dens_threshold
* and xc_func_set_sigma_threshold for backward compatibility
* Allows to change the zero-density (zero-gradient) threshold
* of a XC functional
* Only available from libXC v4
* ===============================================================
*/
void libpaw_xc_func_set_density_threshold(XC(func_type) *xc_func, double *dens_threshold)
#if ( XC_MAJOR_VERSION > 3 )
/* ==== libXC v4.0 and later ==== */
{XC(func_set_dens_threshold)(xc_func, *dens_threshold);}
#else
{fprintf(stderr, "WARNING: setting density threshold not available for libXC<4.0!\n");}
#endif
void libpaw_xc_func_set_sig_threshold(XC(func_type) *xc_func, double *sigma_threshold)
#if ( XC_MAJOR_VERSION > 4 )
/* ==== libXC v5.0 and later ==== */
{XC(func_set_sigma_threshold)(xc_func, *sigma_threshold);}
#else
{fprintf(stderr, "WARNING: setting sigma threshold not available for libXC<4.0!\n");}
#endif
/* ===============================================================
* Missing function:
* Return 1 if the functional is hybrid, from its id
* ===============================================================
*/
int libpaw_xc_func_is_hybrid_from_id(int func_id)
{int family; family=xc_family_from_id(func_id, NULL, NULL);
#if ( XC_MAJOR_VERSION > 5 )
/* ==== libXC v6.0 and later ==== */
if (family==XC_FAMILY_HYB_GGA || family==XC_FAMILY_HYB_MGGA || family==XC_FAMILY_HYB_LDA)
{return 1;}
else
{return 0;}
#else
/* ==== Before libXC v6.0 ==== */
if (family==XC_FAMILY_HYB_GGA || family==XC_FAMILY_HYB_MGGA )
{return 1;}
else
{return 0;}
#endif
}
#endif