30#ifdef HAVE_LIBXC_FUNCS
39#include "functionals_list.F90"
54 integer,
public,
parameter :: &
55 XC_OEP_X = 901, & !< Exact exchange
75 integer,
public,
parameter :: &
76 XC_FAMILY_KS_INVERSION = 1024, &
84 integer :: family = xc_family_unknown
88 integer :: spin_channels = 0
91 logical,
private :: from_libxc = .false.
93 type(xc_f03_func_t) :: conf
94 type(xc_f03_func_info_t),
private :: info
95 type(libvdwxc_t) :: libvdwxc
98 integer,
public,
parameter :: LIBXC_C_INDEX = 1000
104 type(xc_functional_t),
intent(inout) :: functl
105 type(namespace_t),
intent(in) :: namespace
106 integer,
intent(in) :: id
107 integer,
intent(in) :: ndim
108 real(real64),
intent(in) :: nel
109 integer,
intent(in) :: spin_channels
111 integer :: interact_1d
112 real(real64) :: alpha, parameters(2)
118 functl%spin_channels = spin_channels
120 if (functl%id == 0)
then
121 functl%family = xc_family_none
124 functl%family = xc_f03_family_from_id(functl%id)
127 if (functl%family == xc_family_unknown)
then
129 select case (functl%id)
131 functl%family = xc_family_oep
134 functl%family = xc_family_lda
137 functl%family = xc_family_ks_inversion
147 functl%family = xc_family_hyb_gga
159 if (functl%family == xc_family_oep)
then
160 functl%type = xc_exchange
161 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
163 else if (functl%family == xc_family_ks_inversion .or. functl%family ==
xc_family_rdmft)
then
164 functl%type = xc_exchange_correlation
165 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
168 call xc_f03_func_init(functl%conf, xc_lda_c_pw, spin_channels)
169 functl%info = xc_f03_func_get_info(functl%conf)
170 functl%type = xc_f03_func_info_get_kind(functl%info)
171 functl%flags = xc_f03_func_info_get_flags(functl%info)
176 functl%type = xc_correlation
177 functl%flags = xc_flags_have_exc + xc_flags_have_vxc + xc_flags_3d
180 functl%type = xc_correlation
181 functl%flags = xc_flags_have_exc + xc_flags_have_vxc + xc_flags_3d
184 functl%type = xc_exchange
185 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
188 functl%type = xc_correlation
189 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
191 else if (functl%family == xc_family_none)
then
193 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
197 functl%from_libxc = .
true.
200 select case (functl%id)
202 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_hse06, spin_channels)
205 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_pbeh, spin_channels)
208 call xc_f03_func_init(functl%conf, functl%id, spin_channels)
210 functl%info = xc_f03_func_get_info(functl%conf)
211 functl%type = xc_f03_func_info_get_kind(functl%info)
212 functl%flags = xc_f03_func_info_get_flags(functl%info)
215 if (
bitand(functl%flags, xc_flags_have_exc) == 0)
then
216 message(1) =
'Specified functional does not have total energy available.'
217 message(2) =
'Corresponding component of energy will just be left as zero.'
221 if (
bitand(functl%flags, xc_flags_have_vxc) == 0)
then
222 message(1) =
'Specified functional does not have XC potential available.'
223 message(2) =
'Cannot run calculations. Choose another XCFunctional.'
229 if (functl%family /= xc_family_none)
then
234 if (
bitand(functl%flags, xc_flags_hyb_camy) /= 0)
then
239 if (
bitand(functl%flags, xc_flags_vv10) /= 0)
then
245 select case (functl%id)
247 case (xc_lda_c_xalpha)
259 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
262 case (xc_lda_x_1d_soft, xc_lda_c_1d_csc)
277 call parse_variable(namespace,
'Interaction1D', option__interaction1d__interaction_soft_coulomb, interact_1d)
291 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
307 assert(xc_f03_func_info_get_n_ext_params(functl%info) == 1)
309 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
310 write(
message(1),
'(a,i1)')
"Info: Setting the number of electrons for the functional for spin ", spin_channels
320 type(xc_functional_t),
intent(inout) :: functl
324 if (functl%family /= xc_family_none .and. functl%family /= xc_family_oep .and. &
325 functl%family /= xc_family_ks_inversion .and. functl%id /=
xc_lda_c_fbe &
327 call xc_f03_func_end(functl%conf)
341 type(xc_functional_t),
intent(in) :: functl
342 integer,
optional,
intent(in) :: iunit
343 type(namespace_t),
optional,
intent(in) :: namespace
345 character(len=1024) :: reference
346 character(len=120) :: family
347 integer :: ii, ind, istart, iend
351 if (functl%family == xc_family_oep)
then
354 select case (functl%id)
356 write(
message(1),
'(2x,a)')
'Exchange'
357 write(
message(2),
'(4x,a)')
'Exact exchange'
361 write(
message(1),
'(2x,a)')
'Exchange'
362 write(
message(2),
'(4x,a)')
'Slater exchange'
366 write(
message(1),
'(2x,a)')
'Exchange'
367 write(
message(2),
'(4x,a)')
'Force-based local exchange'
368 write(
message(3),
'(4x,a)')
'[1] Tancogne-Dejean et al., J. Chem. Phys. 160, 024103 (2024)'
372 write(
message(1),
'(2x,a)')
'Exchange'
373 write(
message(2),
'(4x,a)')
'Force-based local exchange - Sturm-Liouville'
377 write(
message(1),
'(2x,a)')
'Correlation'
378 write(
message(2),
'(4x,a)')
'Force-based local-density correlation - Sturm-Liouville'
386 select case (functl%id)
388 write(
message(1),
'(2x,a)')
'RDMFT'
389 write(
message(2),
'(4x,a)')
'Mueller functional'
393 else if (functl%family == xc_family_ks_inversion)
then
395 select case (functl%id)
397 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
398 write(
message(2),
'(4x,a)')
' KS Inversion'
406 write(
message(1),
'(2x,a)')
'Exchange'
407 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA)'
408 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
412 write(
message(1),
'(2x,a)')
'Exchange'
413 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel, gamma = 1.0 (MGGA)'
414 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
418 write(
message(1),
'(2x,a)')
'Exchange'
419 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA) with explicit inversion of x(y)'
420 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
421 write(
message(4),
'(4x,a)')
'[2] E. Proynov et al., Chemical Physics Letters 455, 103 (2008)'
425 write(
message(1),
'(2x,a)')
'Correlation'
426 write(
message(2),
'(4x,a)')
'Noncollinear Colle-Salvetti (MGGA)'
427 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
431 write(
message(1),
'(2x,a)')
'Correlation'
432 write(
message(2),
'(4x,a)')
'Force-based LDA correlation'
433 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, M. Penz, M. Ruggenthaler, A. Rubio, J. Phys. Chem. A 129, 3132 (2025)'
436 else if (functl%family /= xc_family_none)
then
437 select case (functl%type)
439 write(
message(1),
'(2x,a)')
'Exchange'
440 case (xc_correlation)
441 write(
message(1),
'(2x,a)')
'Correlation'
442 case (xc_exchange_correlation)
443 write(
message(1),
'(2x,a)')
'Exchange-correlation'
447 write(
message(1),
'(a,i6,a,i6)')
"Unknown functional type ", functl%type,
' for functional ', functl%id
451 select case (functl%family)
453 write(family,
'(a)')
"LDA"
455 write(family,
'(a)')
"GGA"
456 case (xc_family_mgga)
457 write(family,
'(a)')
"MGGA"
460 case (xc_family_hyb_lda)
461 write(family,
'(a)')
"Hybrid LDA"
462 case (xc_family_hyb_gga)
463 write(family,
'(a)')
"Hybrid GGA"
464 case (xc_family_hyb_mgga)
465 write(family,
'(a)')
"Hybrid MGGA"
467 write(
message(2),
'(4x,4a)') trim(xc_f03_func_info_get_name(functl%info)),
' (', trim(family),
')'
471 do while(ii >= 0 .and. ii < 256)
474 write(reference,
'(a)') trim(xc_f03_func_reference_get_ref(xc_f03_func_info_get_references(functl%info, ii)))
476 if (len_trim(reference) == 0) cycle
479 write(
message(1),
'(4x,a,i1,2a)')
'[', ind,
'] ', trim(reference(istart:iend))
481 do while (iend < len_trim(reference))
483 iend = min(istart + len(
message(1))-10, len_trim(reference))
484 write(
message(1),
'(7x,a)') trim(reference(istart:iend))
496 integer,
intent(in) :: dim
497 integer,
intent(in) :: pseudo_x_functional, pseudo_c_functional
504 default = pseudo_x_functional
510 default = xc_lda_x_2d
512 default = xc_lda_x_1d_soft
519 default = default + libxc_c_index*pseudo_c_functional
523 default = default + libxc_c_index * xc_lda_c_pz_mod
525 default = default + libxc_c_index * xc_lda_c_2d_amgb
527 default = default + libxc_c_index * xc_lda_c_1d_csc
538 type(xc_functional_t),
intent(in) :: functl
539 integer,
intent(in) :: ndim
540 type(namespace_t),
intent(in) :: namespace
547 ok =
bitand(functl%flags, xc_flags_1d) /= 0
548 if (ndim == 1 .and. (.not. ok))
then
549 message(1) =
'Cannot use the specified functionals in 1D.'
553 ok =
bitand(functl%flags, xc_flags_2d) /= 0
554 if (ndim == 2 .and. (.not. ok))
then
555 message(1) =
'Cannot use the specified functionals in 2D.'
559 ok =
bitand(functl%flags, xc_flags_3d) /= 0
560 if (ndim == 3 .and. (.not. ok))
then
561 message(1) =
'Cannot use the specified functionals in 3D.'
570 type(xc_functional_t),
intent(in) :: functl
571 type(namespace_t),
intent(in) :: namespace
573 integer :: n_ext_params, ip
574 character(len=128) :: ext_params_name
577 if (.not. functl%from_libxc)
return
582 n_ext_params = xc_f03_func_info_get_n_ext_params(functl%info)
583 do ip = 0, n_ext_params-1
584 ext_params_name = xc_f03_func_info_get_ext_params_name(functl%info, ip)
586 if (ext_params_name(1:1) ==
'_') cycle
587 if (trim(xc_f03_func_info_get_ext_params_description(functl%info, ip)) ==
'Number of electrons')
then
594 message(1) =
'The selected functional is currently not supported.'
601 logical pure function xc_functional_is_energy_functional(functl)
602 type(xc_functional_t),
intent(in) :: functl
604 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 functionalwith an explicit inversion of x(y),...
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.