30#ifdef HAVE_LIBXC_FUNCS
39#include "functionals_list.F90"
54 integer,
public,
parameter :: &
55 XC_OEP_X = 901, & !< Exact exchange
76 integer,
public,
parameter :: &
77 XC_FAMILY_KS_INVERSION = 1024, &
85 integer :: family = xc_family_unknown
89 integer :: spin_channels = 0
92 logical,
private :: from_libxc = .false.
94 type(xc_f03_func_t) :: conf
95 type(xc_f03_func_info_t),
private :: info
96 type(libvdwxc_t) :: libvdwxc
99 integer,
public,
parameter :: LIBXC_C_INDEX = 1000
105 type(xc_functional_t),
intent(inout) :: functl
106 type(namespace_t),
intent(in) :: namespace
107 integer,
intent(in) :: id
108 integer,
intent(in) :: ndim
109 real(real64),
intent(in) :: nel
110 integer,
intent(in) :: spin_channels
112 integer :: interact_1d
113 real(real64) :: alpha, parameters(2)
119 functl%spin_channels = spin_channels
121 if (functl%id == 0)
then
122 functl%family = xc_family_none
125 functl%family = xc_f03_family_from_id(functl%id)
128 if (functl%family == xc_family_unknown)
then
130 select case (functl%id)
132 functl%family = xc_family_oep
135 functl%family = xc_family_lda
138 functl%family = xc_family_ks_inversion
148 functl%family = xc_family_hyb_gga
160 if (functl%family == xc_family_oep)
then
161 functl%type = xc_exchange
162 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
164 else if (functl%family == xc_family_ks_inversion .or. functl%family ==
xc_family_rdmft)
then
165 functl%type = xc_exchange_correlation
166 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
169 call xc_f03_func_init(functl%conf, xc_lda_c_pw, spin_channels)
170 functl%info = xc_f03_func_get_info(functl%conf)
171 functl%type = xc_f03_func_info_get_kind(functl%info)
172 functl%flags = xc_f03_func_info_get_flags(functl%info)
177 functl%type = xc_correlation
178 functl%flags = xc_flags_have_exc + xc_flags_have_vxc + xc_flags_3d
181 functl%type = xc_correlation
182 functl%flags = xc_flags_have_exc + xc_flags_have_vxc + xc_flags_3d
185 functl%type = xc_exchange
186 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
189 functl%type = xc_correlation
190 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
192 else if (functl%family == xc_family_none)
then
194 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
198 functl%from_libxc = .
true.
201 select case (functl%id)
203 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_hse06, spin_channels)
206 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_pbeh, spin_channels)
209 call xc_f03_func_init(functl%conf, functl%id, spin_channels)
211 functl%info = xc_f03_func_get_info(functl%conf)
212 functl%type = xc_f03_func_info_get_kind(functl%info)
213 functl%flags = xc_f03_func_info_get_flags(functl%info)
216 if (
bitand(functl%flags, xc_flags_have_exc) == 0)
then
217 message(1) =
'Specified functional does not have total energy available.'
218 message(2) =
'Corresponding component of energy will just be left as zero.'
222 if (
bitand(functl%flags, xc_flags_have_vxc) == 0)
then
223 message(1) =
'Specified functional does not have XC potential available.'
224 message(2) =
'Cannot run calculations. Choose another XCFunctional.'
230 if (functl%family /= xc_family_none)
then
235 if (
bitand(functl%flags, xc_flags_hyb_camy) /= 0)
then
240 if (
bitand(functl%flags, xc_flags_vv10) /= 0)
then
246 select case (functl%id)
248 case (xc_lda_c_xalpha)
260 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
263 case (xc_lda_x_1d_soft, xc_lda_c_1d_csc)
278 call parse_variable(namespace,
'Interaction1D', option__interaction1d__interaction_soft_coulomb, interact_1d)
292 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
308 assert(xc_f03_func_info_get_n_ext_params(functl%info) == 1)
310 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
311 write(
message(1),
'(a,i1)')
"Info: Setting the number of electrons for the functional for spin ", spin_channels
321 type(xc_functional_t),
intent(inout) :: functl
325 if (functl%family /= xc_family_none .and. functl%family /= xc_family_oep .and. &
326 functl%family /= xc_family_ks_inversion .and. functl%id /=
xc_lda_c_fbe &
328 call xc_f03_func_end(functl%conf)
342 type(xc_functional_t),
intent(in) :: functl
343 integer,
optional,
intent(in) :: iunit
344 type(namespace_t),
optional,
intent(in) :: namespace
346 character(len=1024) :: reference
347 character(len=120) :: family
348 integer :: ii, ind, istart, iend
352 if (functl%family == xc_family_oep)
then
355 select case (functl%id)
357 write(
message(1),
'(2x,a)')
'Exchange'
358 write(
message(2),
'(4x,a)')
'Exact exchange'
362 write(
message(1),
'(2x,a)')
'Exchange'
363 write(
message(2),
'(4x,a)')
'Slater exchange'
367 write(
message(1),
'(2x,a)')
'Exchange'
368 write(
message(2),
'(4x,a)')
'Force-based local exchange'
369 write(
message(3),
'(4x,a)')
'[1] Tancogne-Dejean et al., J. Chem. Phys. 160, 024103 (2024)'
373 write(
message(1),
'(2x,a)')
'Exchange'
374 write(
message(2),
'(4x,a)')
'Force-based local exchange - Sturm-Liouville'
378 write(
message(1),
'(2x,a)')
'Correlation'
379 write(
message(2),
'(4x,a)')
'Force-based local-density correlation - Sturm-Liouville'
387 select case (functl%id)
389 write(
message(1),
'(2x,a)')
'RDMFT'
390 write(
message(2),
'(4x,a)')
'Mueller functional'
394 else if (functl%family == xc_family_ks_inversion)
then
396 select case (functl%id)
398 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
399 write(
message(2),
'(4x,a)')
' KS Inversion'
407 write(
message(1),
'(2x,a)')
'Exchange'
408 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA)'
409 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
413 write(
message(1),
'(2x,a)')
'Exchange'
414 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel, gamma = 1.0 (MGGA)'
415 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
419 write(
message(1),
'(2x,a)')
'Exchange'
420 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA) with explicit inversion of x(y)'
421 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
422 write(
message(4),
'(4x,a)')
'[2] E. Proynov et al., Chemical Physics Letters 455, 103 (2008)'
426 write(
message(1),
'(2x,a)')
'Correlation'
427 write(
message(2),
'(4x,a)')
'Noncollinear Colle-Salvetti (MGGA)'
428 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
432 write(
message(1),
'(2x,a)')
'Correlation'
433 write(
message(2),
'(4x,a)')
'Force-based LDA correlation'
434 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, M. Penz, M. Ruggenthaler, A. Rubio, J. Phys. Chem. A 129, 3132 (2025)'
437 else if (functl%family /= xc_family_none)
then
438 select case (functl%type)
440 write(
message(1),
'(2x,a)')
'Exchange'
441 case (xc_correlation)
442 write(
message(1),
'(2x,a)')
'Correlation'
443 case (xc_exchange_correlation)
444 write(
message(1),
'(2x,a)')
'Exchange-correlation'
448 write(
message(1),
'(a,i6,a,i6)')
"Unknown functional type ", functl%type,
' for functional ', functl%id
452 select case (functl%family)
454 write(family,
'(a)')
"LDA"
456 write(family,
'(a)')
"GGA"
457 case (xc_family_mgga)
458 write(family,
'(a)')
"MGGA"
461 case (xc_family_hyb_lda)
462 write(family,
'(a)')
"Hybrid LDA"
463 case (xc_family_hyb_gga)
464 write(family,
'(a)')
"Hybrid GGA"
465 case (xc_family_hyb_mgga)
466 write(family,
'(a)')
"Hybrid MGGA"
468 write(
message(2),
'(4x,4a)') trim(xc_f03_func_info_get_name(functl%info)),
' (', trim(family),
')'
472 do while(ii >= 0 .and. ii < 256)
475 write(reference,
'(a)') trim(xc_f03_func_reference_get_ref(xc_f03_func_info_get_references(functl%info, ii)))
477 if (len_trim(reference) == 0) cycle
480 write(
message(1),
'(4x,a,i1,2a)')
'[', ind,
'] ', trim(reference(istart:iend))
482 do while (iend < len_trim(reference))
484 iend = min(istart + len(
message(1))-10, len_trim(reference))
485 write(
message(1),
'(7x,a)') trim(reference(istart:iend))
497 integer,
intent(in) :: dim
498 integer,
intent(in) :: pseudo_x_functional, pseudo_c_functional
505 default = pseudo_x_functional
511 default = xc_lda_x_2d
513 default = xc_lda_x_1d_soft
520 default = default + libxc_c_index*pseudo_c_functional
524 default = default + libxc_c_index * xc_lda_c_pz_mod
526 default = default + libxc_c_index * xc_lda_c_2d_amgb
528 default = default + libxc_c_index * xc_lda_c_1d_csc
539 type(xc_functional_t),
intent(in) :: functl
540 integer,
intent(in) :: ndim
541 type(namespace_t),
intent(in) :: namespace
548 ok =
bitand(functl%flags, xc_flags_1d) /= 0
549 if (ndim == 1 .and. (.not. ok))
then
550 message(1) =
'Cannot use the specified functionals in 1D.'
554 ok =
bitand(functl%flags, xc_flags_2d) /= 0
555 if (ndim == 2 .and. (.not. ok))
then
556 message(1) =
'Cannot use the specified functionals in 2D.'
560 ok =
bitand(functl%flags, xc_flags_3d) /= 0
561 if (ndim == 3 .and. (.not. ok))
then
562 message(1) =
'Cannot use the specified functionals in 3D.'
571 type(xc_functional_t),
intent(in) :: functl
572 type(namespace_t),
intent(in) :: namespace
574 integer :: n_ext_params, ip
575 character(len=128) :: ext_params_name
578 if (.not. functl%from_libxc)
return
583 n_ext_params = xc_f03_func_info_get_n_ext_params(functl%info)
584 do ip = 0, n_ext_params-1
585 ext_params_name = xc_f03_func_info_get_ext_params_name(functl%info, ip)
587 if (ext_params_name(1:1) ==
'_') cycle
588 if (trim(xc_f03_func_info_get_ext_params_description(functl%info, ip)) ==
'Number of electrons')
then
595 message(1) =
'The selected functional is currently not supported.'
602 logical pure function xc_functional_is_energy_functional(functl)
603 type(xc_functional_t),
intent(in) :: functl
605 xc_functional_is_energy_functional =
bitand(functl%flags, xc_flags_have_exc) /= 0
real(real64), parameter, public m_one
subroutine, public libvdwxc_end(this)
subroutine, public libvdwxc_init(libvdwxc, namespace, functional)
subroutine, public libvdwxc_write_info(this, iunit, namespace)
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_warning(no_lines, all_nodes, namespace)
subroutine, public messages_obsolete_variable(namespace, name, rep)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
logical function, public parse_is_defined(namespace, name)
integer, parameter, public pseudo_correlation_any
integer, parameter, public pseudo_exchange_any
integer, parameter, public xc_ks_inversion
inversion of Kohn-Sham potential
integer, parameter, public xc_vdw_c_vdwdf
vdw-df correlation from libvdwxc
integer, parameter, public xc_family_rdmft
subroutine, public xc_functional_write_info(functl, iunit, namespace)
Write functional information.
integer function, public xc_get_default_functional(dim, pseudo_x_functional, pseudo_c_functional)
Returns the default functional given the one parsed from the pseudopotentials and the space dimension...
integer, parameter, public xc_mgga_c_nc_cs
Noncollinear version of the Colle-Salvetti correlation functional.
integer, parameter, public xc_hyb_gga_xc_mvorb_pbeh
Density-based mixing parameter of PBE0.
integer, parameter, public xc_mgga_x_nc_br
Noncollinear version of the Becke-Roussel functional.
integer, parameter, public xc_vdw_c_vdwdfcx
vdw-df-cx correlation from libvdwxc
subroutine, public xc_functional_init(functl, namespace, id, ndim, nel, spin_channels)
integer, parameter, public xc_lda_c_fbe
LDA correlation based ib the force-balance equation.
integer, parameter, public xc_family_nc_mgga
integer, parameter, public xc_vdw_c_vdwdf2
vdw-df2 correlation from libvdwxc
subroutine xc_check_dimension(functl, ndim, namespace)
Check that the selected functional is compatible with the space dimension.
integer, parameter, public xc_family_libvdwxc
integer, parameter, public xc_hyb_gga_xc_mvorb_hse06
Density-based mixing parameter of HSE06.
subroutine, public xc_functional_end(functl)
integer, parameter, public xc_lda_c_fbe_sl
LDA correlation based ib the force-balance equation - Sturm-Liouville version.
integer, parameter, public xc_rdmft_xc_m
RDMFT Mueller functional.
integer, parameter, public xc_mgga_x_nc_br_1
Noncollinear version of the Becke-Roussel functional, gamma=1.
logical function, public xc_functional_is_not_size_consistent(functl, namespace)
Does the functional depend on the number of electrons or not.
integer, parameter, public xc_mgga_x_nc_br_explicit
Noncollinear version of the Becke-Roussel functional.
integer, parameter, public xc_family_nc_lda
integer, parameter, public xc_oep_x_fbe_sl
Exchange approximation based on the force balance equation - Sturn-Liouville version.
integer, parameter, public xc_oep_x_fbe
Exchange approximation based on the force balance equation.
logical pure function, public xc_functional_is_energy_functional(functl)
integer, parameter, public xc_oep_x_slater
Slater approximation to the exact exchange.