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_ks_inversion
144 functl%family = xc_family_hyb_gga
156 if (functl%family == xc_family_oep)
then
157 functl%type = xc_exchange
158 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
160 else if (functl%family == xc_family_ks_inversion .or. functl%family ==
xc_family_rdmft)
then
161 functl%type = xc_exchange_correlation
162 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
165 call xc_f03_func_init(functl%conf, xc_lda_c_pw, spin_channels)
166 functl%info = xc_f03_func_get_info(functl%conf)
167 functl%type = xc_f03_func_info_get_kind(functl%info)
168 functl%flags = xc_f03_func_info_get_flags(functl%info)
173 functl%family = xc_family_lda
174 functl%type = xc_correlation
175 functl%flags = xc_flags_have_exc + xc_flags_have_vxc + xc_flags_3d
178 functl%type = xc_exchange
179 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
182 functl%type = xc_correlation
183 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
185 else if (functl%family == xc_family_none)
then
187 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
191 functl%from_libxc = .
true.
194 select case (functl%id)
196 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_hse06, spin_channels)
199 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_pbeh, spin_channels)
202 call xc_f03_func_init(functl%conf, functl%id, spin_channels)
204 functl%info = xc_f03_func_get_info(functl%conf)
205 functl%type = xc_f03_func_info_get_kind(functl%info)
206 functl%flags = xc_f03_func_info_get_flags(functl%info)
209 if (
bitand(functl%flags, xc_flags_have_exc) == 0)
then
210 message(1) =
'Specified functional does not have total energy available.'
211 message(2) =
'Corresponding component of energy will just be left as zero.'
215 if (
bitand(functl%flags, xc_flags_have_vxc) == 0)
then
216 message(1) =
'Specified functional does not have XC potential available.'
217 message(2) =
'Cannot run calculations. Choose another XCFunctional.'
223 if (functl%family /= xc_family_none)
then
228 if (
bitand(functl%flags, xc_flags_hyb_camy) /= 0)
then
233 if (
bitand(functl%flags, xc_flags_vv10) /= 0)
then
239 select case (functl%id)
241 case (xc_lda_c_xalpha)
253 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
256 case (xc_lda_x_1d_soft, xc_lda_c_1d_csc)
271 call parse_variable(namespace,
'Interaction1D', option__interaction1d__interaction_soft_coulomb, interact_1d)
285 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
301 assert(xc_f03_func_info_get_n_ext_params(functl%info) == 1)
303 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
304 write(
message(1),
'(a,i1)')
"Info: Setting the number of electrons for the functional for spin ", spin_channels
314 type(xc_functional_t),
intent(inout) :: functl
318 if (functl%family /= xc_family_none .and. functl%family /= xc_family_oep .and. &
319 functl%family /= xc_family_ks_inversion .and. functl%id /=
xc_lda_c_fbe &
321 call xc_f03_func_end(functl%conf)
335 type(xc_functional_t),
intent(in) :: functl
336 integer,
optional,
intent(in) :: iunit
337 type(namespace_t),
optional,
intent(in) :: namespace
339 character(len=1024) :: reference
340 character(len=120) :: family
341 integer :: ii, ind, istart, iend
345 if (functl%family == xc_family_oep)
then
348 select case (functl%id)
350 write(
message(1),
'(2x,a)')
'Exchange'
351 write(
message(2),
'(4x,a)')
'Exact exchange'
355 write(
message(1),
'(2x,a)')
'Exchange'
356 write(
message(2),
'(4x,a)')
'Slater exchange'
360 write(
message(1),
'(2x,a)')
'Exchange'
361 write(
message(2),
'(4x,a)')
'Force-based local exchange'
362 write(
message(3),
'(4x,a)')
'[1] Tancogne-Dejean et al., J. Chem. Phys. 160, 024103 (2024)'
366 write(
message(1),
'(2x,a)')
'Exchange'
367 write(
message(2),
'(4x,a)')
'Force-based local exchange - Sturm-Liouville'
371 write(
message(1),
'(2x,a)')
'Correlation'
372 write(
message(2),
'(4x,a)')
'Force-based local-density correlation - Sturm-Liouville'
380 select case (functl%id)
382 write(
message(1),
'(2x,a)')
'RDMFT'
383 write(
message(2),
'(4x,a)')
'Mueller functional'
387 else if (functl%family == xc_family_ks_inversion)
then
389 select case (functl%id)
391 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
392 write(
message(2),
'(4x,a)')
' KS Inversion'
400 write(
message(1),
'(2x,a)')
'Exchange'
401 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA)'
402 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
406 write(
message(1),
'(2x,a)')
'Exchange'
407 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel, gamma = 1.0 (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 (MGGA) with explicit inversion of x(y)'
414 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
415 write(
message(4),
'(4x,a)')
'[2] E. Proynov et al., Chemical Physics Letters 455, 103 (2008)'
419 write(
message(1),
'(2x,a)')
'Correlation'
420 write(
message(2),
'(4x,a)')
'Noncollinear Colle-Salvetti (MGGA)'
421 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
425 write(
message(1),
'(2x,a)')
'Correlation'
426 write(
message(2),
'(4x,a)')
'Force-based LDA correlation'
427 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, M. Penz, M. Ruggenthaler, A. Rubio, J. Phys. Chem. A 129, 3132 (2025)'
430 else if (functl%family /= xc_family_none)
then
431 select case (functl%type)
433 write(
message(1),
'(2x,a)')
'Exchange'
434 case (xc_correlation)
435 write(
message(1),
'(2x,a)')
'Correlation'
436 case (xc_exchange_correlation)
437 write(
message(1),
'(2x,a)')
'Exchange-correlation'
441 write(
message(1),
'(a,i6,a,i6)')
"Unknown functional type ", functl%type,
' for functional ', functl%id
445 select case (functl%family)
447 write(family,
'(a)')
"LDA"
449 write(family,
'(a)')
"GGA"
450 case (xc_family_mgga)
451 write(family,
'(a)')
"MGGA"
454 case (xc_family_hyb_lda)
455 write(family,
'(a)')
"Hybrid LDA"
456 case (xc_family_hyb_gga)
457 write(family,
'(a)')
"Hybrid GGA"
458 case (xc_family_hyb_mgga)
459 write(family,
'(a)')
"Hybrid MGGA"
461 write(
message(2),
'(4x,4a)') trim(xc_f03_func_info_get_name(functl%info)),
' (', trim(family),
')'
468 write(reference,
'(a)') trim(xc_f03_func_reference_get_ref(xc_f03_func_info_get_references(functl%info, ii)))
470 if (len_trim(reference) == 0) cycle
473 write(
message(1),
'(4x,a,i1,2a)')
'[', ind,
'] ', trim(reference(istart:iend))
475 do while (iend < len_trim(reference))
477 iend = min(istart + len(
message(1))-10, len_trim(reference))
478 write(
message(1),
'(7x,a)') trim(reference(istart:iend))
490 integer,
intent(in) :: dim
491 integer,
intent(in) :: pseudo_x_functional, pseudo_c_functional
498 default = pseudo_x_functional
504 default = xc_lda_x_2d
506 default = xc_lda_x_1d_soft
513 default = default + libxc_c_index*pseudo_c_functional
517 default = default + libxc_c_index * xc_lda_c_pz_mod
519 default = default + libxc_c_index * xc_lda_c_2d_amgb
521 default = default + libxc_c_index * xc_lda_c_1d_csc
532 type(xc_functional_t),
intent(in) :: functl
533 integer,
intent(in) :: ndim
534 type(namespace_t),
intent(in) :: namespace
541 ok =
bitand(functl%flags, xc_flags_1d) /= 0
542 if (ndim == 1 .and. (.not. ok))
then
543 message(1) =
'Cannot use the specified functionals in 1D.'
547 ok =
bitand(functl%flags, xc_flags_2d) /= 0
548 if (ndim == 2 .and. (.not. ok))
then
549 message(1) =
'Cannot use the specified functionals in 2D.'
553 ok =
bitand(functl%flags, xc_flags_3d) /= 0
554 if (ndim == 3 .and. (.not. ok))
then
555 message(1) =
'Cannot use the specified functionals in 3D.'
564 type(xc_functional_t),
intent(in) :: functl
565 type(namespace_t),
intent(in) :: namespace
567 integer :: n_ext_params, ip
568 character(len=128) :: ext_params_name
571 if (.not. functl%from_libxc)
return
576 n_ext_params = xc_f03_func_info_get_n_ext_params(functl%info)
577 do ip = 0, n_ext_params-1
578 ext_params_name = xc_f03_func_info_get_ext_params_name(functl%info, ip)
580 if (ext_params_name(1:1) ==
'_') cycle
581 if (trim(xc_f03_func_info_get_ext_params_description(functl%info, ip)) ==
'Number of electrons')
then
588 message(1) =
'The selected functional is currently not supported.'
595 logical pure function xc_functional_is_energy_functional(functl)
596 type(xc_functional_t),
intent(in) :: functl
598 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.