30#ifdef HAVE_LIBXC_FUNCS
39#include "functionals_list.F90"
54 integer,
public,
parameter :: &
55 XC_OEP_X = 901, & !< Exact exchange
77 integer,
public,
parameter :: &
78 XC_FAMILY_KS_INVERSION = 1024, &
86 integer :: family = xc_family_unknown
90 integer :: spin_channels = 0
93 logical,
private :: from_libxc = .false.
95 type(xc_f03_func_t) :: conf
96 type(xc_f03_func_info_t),
private :: info
97 type(libvdwxc_t) :: libvdwxc
100 integer,
public,
parameter :: LIBXC_C_INDEX = 1000
106 type(xc_functional_t),
intent(inout) :: functl
107 type(namespace_t),
intent(in) :: namespace
108 integer,
intent(in) :: id
109 integer,
intent(in) :: ndim
110 real(real64),
intent(in) :: nel
111 integer,
intent(in) :: spin_channels
113 integer :: interact_1d
114 real(real64) :: alpha, parameters(2)
120 functl%spin_channels = spin_channels
122 if (functl%id == 0)
then
123 functl%family = xc_family_none
126 functl%family = xc_f03_family_from_id(functl%id)
129 if (functl%family == xc_family_unknown)
then
131 select case (functl%id)
133 functl%family = xc_family_oep
136 functl%family = xc_family_ks_inversion
140 functl%family = xc_family_lda
150 functl%family = xc_family_hyb_gga
162 if (functl%family == xc_family_oep)
then
163 functl%type = xc_exchange
164 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
166 else if (functl%family == xc_family_ks_inversion .or. functl%family ==
xc_family_rdmft)
then
167 functl%type = xc_exchange_correlation
168 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
171 call xc_f03_func_init(functl%conf, xc_lda_c_pw, spin_channels)
172 functl%info = xc_f03_func_get_info(functl%conf)
173 functl%type = xc_f03_func_info_get_kind(functl%info)
174 functl%flags = xc_f03_func_info_get_flags(functl%info)
179 functl%type = xc_exchange_correlation
180 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
183 functl%family = xc_family_lda
184 functl%type = xc_correlation
185 functl%flags = xc_flags_have_exc + xc_flags_have_vxc + xc_flags_3d
188 functl%type = xc_exchange
189 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
192 functl%type = xc_correlation
193 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
195 else if (functl%family == xc_family_none)
then
197 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
201 functl%from_libxc = .
true.
204 select case (functl%id)
206 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_hse06, spin_channels)
209 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_pbeh, spin_channels)
212 call xc_f03_func_init(functl%conf, functl%id, spin_channels)
214 functl%info = xc_f03_func_get_info(functl%conf)
215 functl%type = xc_f03_func_info_get_kind(functl%info)
216 functl%flags = xc_f03_func_info_get_flags(functl%info)
219 if (
bitand(functl%flags, xc_flags_have_exc) == 0)
then
220 message(1) =
'Specified functional does not have total energy available.'
221 message(2) =
'Corresponding component of energy will just be left as zero.'
225 if (
bitand(functl%flags, xc_flags_have_vxc) == 0)
then
226 message(1) =
'Specified functional does not have XC potential available.'
227 message(2) =
'Cannot run calculations. Choose another XCFunctional.'
233 if (functl%family /= xc_family_none)
then
238 if (
bitand(functl%flags, xc_flags_hyb_camy) /= 0)
then
244 select case (functl%id)
246 case (xc_lda_c_xalpha)
258 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
261 case (xc_lda_x_1d_soft, xc_lda_c_1d_csc)
276 call parse_variable(namespace,
'Interaction1D', option__interaction1d__interaction_soft_coulomb, interact_1d)
290 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
306 assert(xc_f03_func_info_get_n_ext_params(functl%info) == 1)
308 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
309 write(
message(1),
'(a,i1)')
"Info: Setting the number of electrons for the functional for spin ", spin_channels
319 type(xc_functional_t),
intent(inout) :: functl
323 if (functl%family /= xc_family_none .and. functl%family /= xc_family_oep .and. &
324 functl%family /= xc_family_ks_inversion .and. functl%id /=
xc_half_hartree &
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=120) :: family
350 if (functl%family == xc_family_oep)
then
353 select case (functl%id)
355 write(
message(1),
'(2x,a)')
'Exchange'
356 write(
message(2),
'(4x,a)')
'Exact exchange'
360 write(
message(1),
'(2x,a)')
'Exchange'
361 write(
message(2),
'(4x,a)')
'Slater exchange'
365 write(
message(1),
'(2x,a)')
'Exchange'
366 write(
message(2),
'(4x,a)')
'Force-based local exchange'
367 write(
message(3),
'(4x,a)')
'[1] Tancogne-Dejean et al., J. Chem. Phys. 160, 024103 (2024)'
371 write(
message(1),
'(2x,a)')
'Exchange'
372 write(
message(2),
'(4x,a)')
'Force-based local exchange - Sturm-Liouville'
376 write(
message(1),
'(2x,a)')
'Correlation'
377 write(
message(2),
'(4x,a)')
'Force-based local-density correlation - Sturm-Liouville'
384 else if (functl%family == xc_family_ks_inversion)
then
386 select case (functl%id)
388 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
389 write(
message(2),
'(4x,a)')
' KS Inversion'
397 write(
message(1),
'(2x,a)')
'Exchange'
398 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA)'
399 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
403 write(
message(1),
'(2x,a)')
'Exchange'
404 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel, gamma = 1.0 (MGGA)'
405 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
409 write(
message(1),
'(2x,a)')
'Exchange'
410 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA) with explicit inversion of x(y)'
411 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
412 write(
message(4),
'(4x,a)')
'[2] E. Proynov et al., Chemical Physics Letters 455, 103 (2008)'
416 write(
message(1),
'(2x,a)')
'Correlation'
417 write(
message(2),
'(4x,a)')
'Noncollinear Colle-Salvetti (MGGA)'
418 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
423 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
424 write(
message(2),
'(4x,a)')
'Half-Hartree two-electron exchange'
428 write(
message(1),
'(2x,a)')
'Correlation'
429 write(
message(2),
'(4x,a)')
'Force-based LDA correlation'
430 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, M. Penz, M. Ruggenthaler, A. Rubio, J. Phys. Chem. A 129, 3132 (2025)'
433 else if (functl%family /= xc_family_none)
then
434 select case (functl%type)
436 write(
message(1),
'(2x,a)')
'Exchange'
437 case (xc_correlation)
438 write(
message(1),
'(2x,a)')
'Correlation'
439 case (xc_exchange_correlation)
440 write(
message(1),
'(2x,a)')
'Exchange-correlation'
444 write(
message(1),
'(a,i6,a,i6)')
"Unknown functional type ", functl%type,
' for functional ', functl%id
448 select case (functl%family)
450 write(family,
'(a)')
"LDA"
452 write(family,
'(a)')
"GGA"
453 case (xc_family_mgga)
454 write(family,
'(a)')
"MGGA"
457 case (xc_family_hyb_lda)
458 write(family,
'(a)')
"Hybrid LDA"
459 case (xc_family_hyb_gga)
460 write(family,
'(a)')
"Hybrid GGA"
461 case (xc_family_hyb_mgga)
462 write(family,
'(a)')
"Hybrid MGGA"
464 write(
message(2),
'(4x,4a)') trim(xc_f03_func_info_get_name(functl%info)),
' (', trim(family),
')'
469 write(
message(1),
'(4x,a,i1,2a)')
'[', ii + 1,
'] ', &
470 trim(xc_f03_func_reference_get_ref(xc_f03_func_info_get_references(functl%info, ii)))
481 integer,
intent(in) :: dim
482 integer,
intent(in) :: pseudo_x_functional, pseudo_c_functional
489 default = pseudo_x_functional
495 default = xc_lda_x_2d
497 default = xc_lda_x_1d_soft
504 default = default + libxc_c_index*pseudo_c_functional
508 default = default + libxc_c_index * xc_lda_c_pz_mod
510 default = default + libxc_c_index * xc_lda_c_2d_amgb
512 default = default + libxc_c_index * xc_lda_c_1d_csc
523 type(xc_functional_t),
intent(in) :: functl
524 integer,
intent(in) :: ndim
525 type(namespace_t),
intent(in) :: namespace
532 ok =
bitand(functl%flags, xc_flags_1d) /= 0
533 if (ndim == 1 .and. (.not. ok))
then
534 message(1) =
'Cannot use the specified functionals in 1D.'
538 ok =
bitand(functl%flags, xc_flags_2d) /= 0
539 if (ndim == 2 .and. (.not. ok))
then
540 message(1) =
'Cannot use the specified functionals in 2D.'
544 ok =
bitand(functl%flags, xc_flags_3d) /= 0
545 if (ndim == 3 .and. (.not. ok))
then
546 message(1) =
'Cannot use the specified functionals in 3D.'
555 type(xc_functional_t),
intent(in) :: functl
556 type(namespace_t),
intent(in) :: namespace
558 integer :: n_ext_params, ip
559 character(len=128) :: ext_params_name
562 if (.not. functl%from_libxc)
return
567 n_ext_params = xc_f03_func_info_get_n_ext_params(functl%info)
568 do ip = 0, n_ext_params-1
569 ext_params_name = xc_f03_func_info_get_ext_params_name(functl%info, ip)
571 if (ext_params_name(1:1) ==
'_') cycle
572 if (trim(xc_f03_func_info_get_ext_params_description(functl%info, ip)) ==
'Number of electrons')
then
579 message(1) =
'The selected functional is currently not supported.'
586 logical pure function xc_functional_is_energy_functional(functl)
587 type(xc_functional_t),
intent(in) :: functl
589 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_experimental(name, namespace)
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_half_hartree
half-Hartree exchange for two electrons (supports complex scaling)
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.