(git:98357aa)
Loading...
Searching...
No Matches
xc_libxc_wrap.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Includes all necessary routines, functions and parameters from
10!> libxc. Provides CP2K routines/functions where the LibXC calling list
11!> is version dependent (>=4.0.3). The naming convention for such
12!> routines/functions is xc_f03_XXX --> 'xc_libxc_wrap_XXX'. All version
13!> independent routines/functions are just bypassed to higher level
14!> module file 'xc_libxc'.
15!>
16!> \par History
17!> 08.2015 created [A. Gloess (agloess)]
18!> 01.2018 refactoring [A. Gloess (agloess)]
19!> 10.2018/04.2019 added hyb_mgga [S. Simko, included by F. Stein]
20!> \author A. Gloess (agloess)
21! **************************************************************************************************
23#if defined (__LIBXC)
24#include <xc_version.h>
25! check for LibXC version
26#if (XC_MAJOR_VERSION < 5 || (XC_MAJOR_VERSION == 5 && XC_MINOR_VERSION < 1))
27 this version of cp2k only works with libxc versions 5.1.0 and above.
28 furthermore, -i${libxc_dir}/include needs to be added to fcflags.
29#else
30 ! Functionals which require parameters
32 USE kinds, ONLY: dp
33 USE xc_f03_lib_m, ONLY: xc_f03_func_end, &
34 xc_f03_func_init, &
35 xc_f03_functional_get_name, &
36 xc_f03_func_set_ext_params, &
37 xc_f03_functional_get_number, &
38 xc_f03_available_functional_numbers, &
39 xc_f03_available_functional_names, &
40 xc_f03_maximum_name_length, &
41 xc_f03_number_of_functionals, &
42 !
43 xc_f03_gga_exc, &
44 xc_f03_gga_exc_vxc, &
45 xc_f03_gga_exc_vxc_fxc, &
46 xc_f03_gga_fxc, &
47 xc_f03_gga_vxc, &
48 xc_f03_gga_vxc_fxc, &
49 !
50 xc_f03_func_get_info, &
51 xc_f03_func_info_get_family, &
52 xc_f03_func_info_get_kind, &
53 xc_f03_func_info_get_name, &
54 xc_f03_func_info_get_references, &
55 xc_f03_func_info_get_flags, &
56 xc_f03_func_info_get_n_ext_params, &
57 xc_f03_func_info_get_ext_params_name, &
58 xc_f03_func_info_get_ext_params_default_value, &
59 xc_f03_func_info_get_ext_params_description, &
60 !
61 xc_f03_func_reference_get_ref, &
62 xc_f03_func_reference_get_doi, &
63 !
64 xc_f03_lda => xc_f03_lda_exc_vxc_fxc_kxc, &
65 xc_f03_lda_exc, &
66 xc_f03_lda_exc_vxc, &
67 xc_f03_lda_exc_vxc_fxc, &
68 xc_f03_lda_fxc, &
69 xc_f03_lda_kxc, &
70 xc_f03_lda_vxc, &
71 !
72 xc_f03_mgga => xc_f03_mgga_exc_vxc_fxc, &
73 xc_f03_mgga_exc, &
74 xc_f03_mgga_exc_vxc, &
75 xc_f03_mgga_fxc, &
76 xc_f03_mgga_vxc, &
77 xc_f03_mgga_vxc_fxc, &
78 !
79 xc_f03_func_t, &
80 xc_f03_func_info_t, &
81 xc_f03_func_reference_t, &
82 !
83 xc_family_lda, &
84 xc_family_gga, &
85 xc_family_mgga, &
86 xc_family_hyb_lda, &
87 xc_family_hyb_gga, &
88 xc_family_hyb_mgga, &
89 !
90 xc_unpolarized, &
91 xc_polarized, &
92 !
93 xc_exchange, &
94 xc_correlation, &
95 xc_exchange_correlation, &
96 xc_kinetic, &
97 !
98 xc_flags_needs_laplacian, &
99 xc_flags_have_exc, &
100 xc_flags_development
101
107#include "../base/base_uses.f90"
108#endif
109 IMPLICIT NONE
110 PRIVATE
111#if defined (__LIBXC)
112
113 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_libxc_wrap'
114
115 CHARACTER(LEN=*), PARAMETER, PUBLIC :: libxc_version = xc_version
116
117 PUBLIC :: xc_f03_func_t, xc_f03_func_info_t
118 PUBLIC :: xc_f03_func_init, xc_f03_func_end
119 PUBLIC :: xc_f03_functional_get_name, xc_f03_available_functional_numbers, xc_f03_maximum_name_length, &
120 xc_f03_number_of_functionals, xc_f03_available_functional_names
121 PUBLIC :: xc_f03_func_get_info, xc_f03_func_info_get_family, xc_f03_func_info_get_kind, &
122 xc_f03_func_info_get_name, xc_f03_func_info_get_ext_params_name, &
123 xc_f03_func_info_get_ext_params_description, xc_f03_func_info_get_ext_params_default_value, &
124 xc_f03_func_info_get_n_ext_params
125 PUBLIC :: xc_f03_gga_exc, xc_f03_gga_exc_vxc, xc_f03_gga_exc_vxc_fxc, xc_f03_gga_fxc, &
126 xc_f03_gga_vxc, xc_f03_gga_vxc_fxc
127 PUBLIC :: xc_f03_lda, &
128 xc_f03_lda_exc, xc_f03_lda_exc_vxc, xc_f03_lda_exc_vxc_fxc, &
129 xc_f03_lda_fxc, xc_f03_lda_kxc, xc_f03_lda_vxc
130 PUBLIC :: xc_f03_mgga, xc_f03_mgga_exc, xc_f03_mgga_exc_vxc, xc_f03_mgga_fxc, &
131 xc_f03_mgga_vxc, xc_f03_mgga_vxc_fxc
132
133 PUBLIC :: xc_family_lda, xc_family_gga, xc_family_mgga, &
134 xc_family_hyb_lda, xc_family_hyb_gga, xc_family_hyb_mgga
135
136 PUBLIC :: xc_unpolarized, xc_polarized
137
138 PUBLIC :: xc_exchange, xc_correlation, xc_exchange_correlation, xc_kinetic
139
140! wrappers for routines
141 PUBLIC :: xc_libxc_wrap_info_refs, &
142 xc_libxc_wrap_version, &
143 xc_libxc_wrap_functional_get_number, &
144 xc_libxc_wrap_needs_laplace, &
145 xc_libxc_wrap_functional_set_params, &
146 xc_libxc_wrap_is_under_development, &
147 xc_libxc_get_reference_length, &
148 xc_libxc_check_functional
149
150CONTAINS
151
152! **************************************************************************************************
153!> \brief Provides the reference(s) for this functional.
154!> \param xc_info func_info object of the functional
155!> \return upper bound for the length of the reference string
156!> \author F. Stein
157! **************************************************************************************************
158 FUNCTION xc_libxc_get_reference_length(xc_info) RESULT(length)
159
160 TYPE(xc_f03_func_info_t), INTENT(IN) :: xc_info
161 INTEGER :: length
162
163 CHARACTER(LEN=*), PARAMETER :: routineN = 'xc_libxc_get_reference_length'
164 INTEGER, PARAMETER :: maxlen = 67
165
166 CHARACTER(LEN=128) :: descr_string
167 CHARACTER(LEN=1024) :: doi_string, ref_string
168 INTEGER :: i, i_ref, i_ref_old, n_params, handle
169 TYPE(xc_f03_func_reference_t) :: xc_ref
170
171 CALL timeset(routinen, handle)
172
173 ! We are counting the number of necessary lines by carrying out a dry run of xc_libxc_wrap_info_refs
174 i_ref = 0
175 i_ref_old = -1
176 length = 0
177 DO WHILE (i_ref >= 0 .AND. i_ref /= i_ref_old)
178 ! information about functional references
179 xc_ref = xc_f03_func_info_get_references(xc_info, i_ref)
180 ref_string = xc_f03_func_reference_get_ref(xc_ref)
181 doi_string = xc_f03_func_reference_get_doi(xc_ref)
182 length = length + len_trim(ref_string) + len_trim(doi_string) + 11
183 IF (mod(length, maxlen) /= 0) length = length + maxlen - mod(length, maxlen)
184 ! information about (optional) external parameters
185 n_params = xc_f03_func_info_get_n_ext_params(xc_info)
186 IF (n_params > 0) THEN
187 length = length + maxlen
188 END IF
189 DO i = 1, n_params
190 descr_string = xc_f03_func_info_get_ext_params_description(xc_info, i - 1)
191 length = length + len_trim(descr_string) + 3
192 IF (mod(length, maxlen) /= 0) length = length + maxlen - mod(length, maxlen)
193 END DO
194 i_ref_old = i_ref
195 END DO
196 ! two additional lines for spin polarization, scaling factor and buffer
197 length = length + 2*maxlen
198
199 CALL timestop(handle)
200
201 END FUNCTION xc_libxc_get_reference_length
202
203! **************************************************************************************************
204!> \brief Provides the reference(s) for this functional.
205!> \param xc_info ...
206!> \param polarized ...
207!> \param sc ...
208!> \param reference ...
209!>
210!> \author A. Gloess (agloess)
211! **************************************************************************************************
212 SUBROUTINE xc_libxc_wrap_info_refs(xc_info, polarized, sc, reference)
213 TYPE(xc_f03_func_info_t), INTENT(IN) :: xc_info
214 INTEGER, INTENT(IN) :: polarized
215 REAL(KIND=dp), INTENT(IN) :: sc
216 CHARACTER(LEN=*), INTENT(OUT) :: reference
217
218 CHARACTER(LEN=*), PARAMETER :: routineN = 'xc_libxc_wrap_info_refs'
219 INTEGER, PARAMETER :: maxlen = 67
220
221 CHARACTER(LEN=128) :: descr_string
222 CHARACTER(LEN=1028) :: doi_string, ref_string
223 ! conservative estimate of the necessary length: 2*1028+11=2067
224 CHARACTER(LEN=2067) :: tmp_string
225 INTEGER :: empty, first, handle, i, i_ref, i_ref_old, idx, &
226 last, n_params
227 TYPE(xc_f03_func_reference_t) :: xc_ref
228
229 CALL timeset(routinen, handle)
230
231 i_ref = 0
232 i_ref_old = -1
233 idx = 1
234 first = 1
235 DO WHILE (i_ref >= 0 .AND. i_ref /= i_ref_old)
236 ! information about functional references
237 xc_ref = xc_f03_func_info_get_references(xc_info, i_ref)
238 ref_string = xc_f03_func_reference_get_ref(xc_ref)
239 doi_string = xc_f03_func_reference_get_doi(xc_ref)
240 WRITE (tmp_string, '(a1,i1,a2,a,a7,a)') '[', idx, '] ', &
241 trim(ref_string), ', doi: ', trim(doi_string)
242 last = first + len_trim(tmp_string) - 1
243 reference(first:last) = trim(tmp_string)
244 first = last + 1
245 empty = last + (maxlen - 1) - mod(last - 1, maxlen)
246 ! fill up line with 'spaces'
247 IF (empty /= last) THEN
248 reference(first:empty) = ' '
249 first = empty + 1
250 END IF
251 ! information about (optional) external parameters
252 n_params = xc_f03_func_info_get_n_ext_params(xc_info)
253 IF (n_params > 0) THEN
254 reference(first:first + maxlen - 1) = 'Optional external parameters:'//repeat(' ', maxlen - 28)
255 first = first + maxlen
256 END IF
257 DO i = 1, n_params
258 descr_string = xc_f03_func_info_get_ext_params_description(xc_info, i - 1)
259 last = first + len_trim(descr_string) - 1 + 3
260 reference(first:last) = ' * '//trim(descr_string)
261 first = last + 1
262 empty = last + (maxlen - 1) - mod(last - 1, maxlen)
263 ! fill up line with 'spaces'
264
265 IF (empty /= last) THEN
266 reference(first:empty) = ' '
267 first = empty + 1
268 END IF
269 END DO
270 idx = idx + 1
271 i_ref_old = i_ref
272 END DO
273 SELECT CASE (polarized)
274 CASE (xc_unpolarized)
275 WRITE (tmp_string, "('{scale=',f5.3,', spin-unpolarized}')") sc
276 CASE (xc_polarized)
277 WRITE (tmp_string, "('{scale=',f5.3,', spin-polarized}')") sc
278 CASE default
279 cpabort("Unsupported value for variable 'polarized'.")
280 END SELECT
281 last = first + len_trim(tmp_string) - 1
282 reference(first:last) = trim(tmp_string)
283 first = last + 1
284 ! fill with 'spaces'
285 reference(first:len(reference)) = ' '
286
287 IF (last > len(reference)) &
288 cpabort("Faulty reference length.")
289
290 CALL timestop(handle)
291
292 END SUBROUTINE xc_libxc_wrap_info_refs
293
294! **************************************************************************************************
295!> \brief Provides a version string.
296!> \param version ...
297!> \author A. Gloess (agloess)
298!>
299! **************************************************************************************************
300 SUBROUTINE xc_libxc_wrap_version(version)
301 CHARACTER(LEN=*), INTENT(OUT) :: version
302
303 CHARACTER(LEN=*), PARAMETER :: routineN = 'xc_libxc_wrap_version'
304
305 INTEGER :: handle
306
307 CALL timeset(routinen, handle)
308
309 version = trim(libxc_version)
310
311 CALL timestop(handle)
312
313 END SUBROUTINE xc_libxc_wrap_version
314
315! **************************************************************************************************
316!> \brief Checks existence of functional in LibXC
317!> \param func_string ...
318!> \return ...
319!> \author F. Stein
320!> \note Remove prefix to keep compatibility, functionals can be specified (in
321!> LIBXC section) as:
322!> GGA_X_... or XC_GGA_X_...
323!> Starting from version 2.2.0 both name conventions are allowed, before
324!> the 'XC_' prefix was necessary.
325!>
326! **************************************************************************************************
327 LOGICAL FUNCTION xc_libxc_check_functional(func_string) RESULT(exists)
328 CHARACTER(LEN=*), INTENT(IN) :: func_string
329
330 CHARACTER(LEN=*), PARAMETER :: routineN = 'xc_libxc_check_functional'
331
332 INTEGER :: func_id, handle
333
334 CALL timeset(routinen, handle)
335
336 IF (func_string(1:3) == "XC_") THEN
337 func_id = xc_f03_functional_get_number(func_string(4:len_trim(func_string)))
338 ELSE
339 func_id = xc_f03_functional_get_number(func_string(1:len_trim(func_string)))
340 END IF
341
342 exists = .true.
343 IF (func_id == -1) exists = .false.
344
345 CALL timestop(handle)
346
347 END FUNCTION xc_libxc_check_functional
348
349! **************************************************************************************************
350!> \brief Provides the functional ID.
351!> \param func_string ...
352!> \return ...
353!> \author A. Gloess (agloess)
354!> \note Remove prefix to keep compatibility, functionals can be specified (in
355!> LIBXC section) as:
356!> GGA_X_... or XC_GGA_X_...
357!> Starting from version 2.2.0 both name conventions are allowed, before
358!> the 'XC_' prefix was necessary.
359!>
360! **************************************************************************************************
361 INTEGER FUNCTION xc_libxc_wrap_functional_get_number(func_string) RESULT(func_id)
362 CHARACTER(LEN=*), INTENT(IN) :: func_string
363
364 CHARACTER(LEN=*), PARAMETER :: routineN = 'xc_libxc_wrap_functional_get_number'
365
366 INTEGER :: handle
367
368 CALL timeset(routinen, handle)
369
370 IF (func_string(1:3) == "XC_") THEN
371 func_id = xc_f03_functional_get_number(func_string(4:len_trim(func_string)))
372 ELSE
373 func_id = xc_f03_functional_get_number(func_string(1:len_trim(func_string)))
374 END IF
375 IF (func_id == -1) THEN
376 cpabort(trim(func_string)//": wrong functional name")
377 END IF
378
379 CALL timestop(handle)
380
381 END FUNCTION xc_libxc_wrap_functional_get_number
382
383! **************************************************************************************************
384!> \brief Wrapper to test wether functional is considered under development in Libxc
385!> \param xc_info ...
386!>
387!> \return ...
388!> \author F. Stein (fstein93)
389! **************************************************************************************************
390 LOGICAL FUNCTION xc_libxc_wrap_is_under_development(xc_info)
391 TYPE(xc_f03_func_info_t) :: xc_info
392
393 IF (iand(xc_f03_func_info_get_flags(xc_info), xc_flags_development) == xc_flags_development) THEN
394 xc_libxc_wrap_is_under_development = .true.
395 ELSE
396 xc_libxc_wrap_is_under_development = .false.
397 END IF
398
399 END FUNCTION xc_libxc_wrap_is_under_development
400
401! **************************************************************************************************
402!> \brief Wrapper for functionals that need the Laplacian, all others can use
403!> a dummy array.
404!> \param func_id ...
405!>
406!> \return ...
407!> \author A. Gloess (agloess)
408! **************************************************************************************************
409 LOGICAL FUNCTION xc_libxc_wrap_needs_laplace(func_id)
410 ! Only some MGGA functionals needs the laplacian
411 INTEGER, INTENT(IN) :: func_id
412
413 CHARACTER(LEN=*), PARAMETER :: routineN = 'xc_libxc_wrap_needs_laplace'
414
415 INTEGER :: handle
416 TYPE(xc_f03_func_info_t) :: xc_info
417 TYPE(xc_f03_func_t) :: xc_func
418
419 CALL timeset(routinen, handle)
420
421 ! Some MGGa need the laplace explicit and some just need an arbitrary array
422 ! of the correct size.
423 !
424 ! Assumption (.true. in v2.1.0 - v4.0.x):
425 ! if
426 ! functional is Laplace-dependent for XC_UNPOLARIZED
427 ! then
428 ! functional will be Laplace-dependent for XC_POLARIZED too.
429 !
430!$OMP CRITICAL(libxc_init)
431 CALL xc_f03_func_init(xc_func, func_id, xc_unpolarized)
432 xc_info = xc_f03_func_get_info(xc_func)
433!$OMP END CRITICAL(libxc_init)
434!$OMP BARRIER
435 IF (iand(xc_f03_func_info_get_flags(xc_info), xc_flags_needs_laplacian) == xc_flags_needs_laplacian) THEN
436 xc_libxc_wrap_needs_laplace = .true.
437 ELSE
438 xc_libxc_wrap_needs_laplace = .false.
439 END IF
440
441 CALL xc_f03_func_end(xc_func)
442
443 CALL timestop(handle)
444
445 END FUNCTION xc_libxc_wrap_needs_laplace
446
447! **************************************************************************************************
448!> \brief Wrapper for functionals that need special parameters.
449!> \param xc_func ...
450!> \param xc_info ...
451!> \param libxc_params ...
452!> \param no_exc ...
453!>
454!> \author A. Gloess (agloess)
455! **************************************************************************************************
456 SUBROUTINE xc_libxc_wrap_functional_set_params(xc_func, xc_info, libxc_params, no_exc)
457 TYPE(xc_f03_func_t), INTENT(INOUT) :: xc_func
458 TYPE(xc_f03_func_info_t), INTENT(IN) :: xc_info
459 TYPE(section_vals_type), POINTER, INTENT(IN) :: libxc_params
460 LOGICAL, INTENT(INOUT) :: no_exc
461
462 CHARACTER(LEN=*), PARAMETER :: routineN = 'xc_libxc_wrap_functional_set_params'
463
464 INTEGER :: handle, i, n_params
465 REAL(KIND=dp), DIMENSION(:), ALLOCATABLE :: params
466 CHARACTER(LEN=128) :: param_name
467
468 CALL timeset(routinen, handle)
469
470 n_params = xc_f03_func_info_get_n_ext_params(xc_info)
471 IF (n_params > 0) THEN
472 ALLOCATE (params(n_params))
473 DO i = 1, n_params
474 param_name = xc_f03_func_info_get_ext_params_name(xc_info, i - 1)
475
476 CALL section_vals_val_get(libxc_params, trim(param_name), r_val=params(i))
477 END DO
478
479 CALL xc_f03_func_set_ext_params(xc_func, params)
480 END IF
481
482 IF (iand(xc_f03_func_info_get_flags(xc_info), xc_flags_have_exc) == xc_flags_have_exc) THEN
483 no_exc = .false.
484 ELSE
485 no_exc = .true.
486 END IF
487
488 CALL timestop(handle)
489
490 END SUBROUTINE xc_libxc_wrap_functional_set_params
491
492#endif
493#endif
494END MODULE xc_libxc_wrap
program cp2k
Main program of CP2K.
Definition cp2k.F:42
various routines to log and control the output. The idea is that decisions about where to log should ...
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_create(section, location, name, description, n_keywords, n_subsections, repeats, citations, deprecation_notice)
creates a list of keywords
subroutine, public section_add_keyword(section, keyword)
adds a keyword to the given section
subroutine, public section_add_subsection(section, subsection)
adds a subsection to the given section
recursive subroutine, public section_release(section)
releases the given keyword list (see doc/ReferenceCounting.html)
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Includes all necessary routines, functions and parameters from libxc. Provides CP2K routines/function...
represent a section of the input file