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_ks_inversion
145 functl%family = xc_family_hyb_gga
157 if (functl%family == xc_family_oep)
then
158 functl%type = xc_exchange
159 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
161 else if (functl%family == xc_family_ks_inversion .or. functl%family ==
xc_family_rdmft)
then
162 functl%type = xc_exchange_correlation
163 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
166 call xc_f03_func_init(functl%conf, xc_lda_c_pw, spin_channels)
167 functl%info = xc_f03_func_get_info(functl%conf)
168 functl%type = xc_f03_func_info_get_kind(functl%info)
169 functl%flags = xc_f03_func_info_get_flags(functl%info)
174 functl%family = xc_family_lda
175 functl%type = xc_correlation
176 functl%flags = xc_flags_have_exc + xc_flags_have_vxc + xc_flags_3d
179 functl%type = xc_exchange
180 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
183 functl%type = xc_correlation
184 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
186 else if (functl%family == xc_family_none)
then
188 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
192 functl%from_libxc = .
true.
195 select case (functl%id)
197 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_hse06, spin_channels)
200 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_pbeh, spin_channels)
203 call xc_f03_func_init(functl%conf, functl%id, spin_channels)
205 functl%info = xc_f03_func_get_info(functl%conf)
206 functl%type = xc_f03_func_info_get_kind(functl%info)
207 functl%flags = xc_f03_func_info_get_flags(functl%info)
210 if (
bitand(functl%flags, xc_flags_have_exc) == 0)
then
211 message(1) =
'Specified functional does not have total energy available.'
212 message(2) =
'Corresponding component of energy will just be left as zero.'
216 if (
bitand(functl%flags, xc_flags_have_vxc) == 0)
then
217 message(1) =
'Specified functional does not have XC potential available.'
218 message(2) =
'Cannot run calculations. Choose another XCFunctional.'
224 if (functl%family /= xc_family_none)
then
229 if (
bitand(functl%flags, xc_flags_hyb_camy) /= 0)
then
234 if (
bitand(functl%flags, xc_flags_vv10) /= 0)
then
240 select case (functl%id)
242 case (xc_lda_c_xalpha)
254 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
257 case (xc_lda_x_1d_soft, xc_lda_c_1d_csc)
272 call parse_variable(namespace,
'Interaction1D', option__interaction1d__interaction_soft_coulomb, interact_1d)
286 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
302 assert(xc_f03_func_info_get_n_ext_params(functl%info) == 1)
304 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
305 write(
message(1),
'(a,i1)')
"Info: Setting the number of electrons for the functional for spin ", spin_channels
315 type(xc_functional_t),
intent(inout) :: functl
319 if (functl%family /= xc_family_none .and. functl%family /= xc_family_oep .and. &
320 functl%family /= xc_family_ks_inversion .and. functl%id /=
xc_lda_c_fbe &
322 call xc_f03_func_end(functl%conf)
336 type(xc_functional_t),
intent(in) :: functl
337 integer,
optional,
intent(in) :: iunit
338 type(namespace_t),
optional,
intent(in) :: namespace
340 character(len=1024) :: reference
341 character(len=120) :: family
342 integer :: ii, ind, istart, iend
346 if (functl%family == xc_family_oep)
then
349 select case (functl%id)
351 write(
message(1),
'(2x,a)')
'Exchange'
352 write(
message(2),
'(4x,a)')
'Exact exchange'
356 write(
message(1),
'(2x,a)')
'Exchange'
357 write(
message(2),
'(4x,a)')
'Slater exchange'
361 write(
message(1),
'(2x,a)')
'Exchange'
362 write(
message(2),
'(4x,a)')
'Force-based local exchange'
363 write(
message(3),
'(4x,a)')
'[1] Tancogne-Dejean et al., J. Chem. Phys. 160, 024103 (2024)'
367 write(
message(1),
'(2x,a)')
'Exchange'
368 write(
message(2),
'(4x,a)')
'Force-based local exchange - Sturm-Liouville'
372 write(
message(1),
'(2x,a)')
'Correlation'
373 write(
message(2),
'(4x,a)')
'Force-based local-density correlation - Sturm-Liouville'
381 select case (functl%id)
383 write(
message(1),
'(2x,a)')
'RDMFT'
384 write(
message(2),
'(4x,a)')
'Mueller functional'
388 else if (functl%family == xc_family_ks_inversion)
then
390 select case (functl%id)
392 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
393 write(
message(2),
'(4x,a)')
' KS Inversion'
401 write(
message(1),
'(2x,a)')
'Exchange'
402 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA)'
403 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
407 write(
message(1),
'(2x,a)')
'Exchange'
408 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel, gamma = 1.0 (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 (MGGA) with explicit inversion of x(y)'
415 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
416 write(
message(4),
'(4x,a)')
'[2] E. Proynov et al., Chemical Physics Letters 455, 103 (2008)'
420 write(
message(1),
'(2x,a)')
'Correlation'
421 write(
message(2),
'(4x,a)')
'Noncollinear Colle-Salvetti (MGGA)'
422 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
426 write(
message(1),
'(2x,a)')
'Correlation'
427 write(
message(2),
'(4x,a)')
'Force-based LDA correlation'
428 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, M. Penz, M. Ruggenthaler, A. Rubio, J. Phys. Chem. A 129, 3132 (2025)'
431 else if (functl%family /= xc_family_none)
then
432 select case (functl%type)
434 write(
message(1),
'(2x,a)')
'Exchange'
435 case (xc_correlation)
436 write(
message(1),
'(2x,a)')
'Correlation'
437 case (xc_exchange_correlation)
438 write(
message(1),
'(2x,a)')
'Exchange-correlation'
442 write(
message(1),
'(a,i6,a,i6)')
"Unknown functional type ", functl%type,
' for functional ', functl%id
446 select case (functl%family)
448 write(family,
'(a)')
"LDA"
450 write(family,
'(a)')
"GGA"
451 case (xc_family_mgga)
452 write(family,
'(a)')
"MGGA"
455 case (xc_family_hyb_lda)
456 write(family,
'(a)')
"Hybrid LDA"
457 case (xc_family_hyb_gga)
458 write(family,
'(a)')
"Hybrid GGA"
459 case (xc_family_hyb_mgga)
460 write(family,
'(a)')
"Hybrid MGGA"
462 write(
message(2),
'(4x,4a)') trim(xc_f03_func_info_get_name(functl%info)),
' (', trim(family),
')'
469 write(reference,
'(a)') trim(xc_f03_func_reference_get_ref(xc_f03_func_info_get_references(functl%info, ii)))
471 if (len_trim(reference) == 0) cycle
474 write(
message(1),
'(4x,a,i1,2a)')
'[', ind,
'] ', trim(reference(istart:iend))
476 do while (iend < len_trim(reference))
478 iend = min(istart + len(
message(1))-10, len_trim(reference))
479 write(
message(1),
'(7x,a)') trim(reference(istart:iend))
491 integer,
intent(in) :: dim
492 integer,
intent(in) :: pseudo_x_functional, pseudo_c_functional
499 default = pseudo_x_functional
505 default = xc_lda_x_2d
507 default = xc_lda_x_1d_soft
514 default = default + libxc_c_index*pseudo_c_functional
518 default = default + libxc_c_index * xc_lda_c_pz_mod
520 default = default + libxc_c_index * xc_lda_c_2d_amgb
522 default = default + libxc_c_index * xc_lda_c_1d_csc
533 type(xc_functional_t),
intent(in) :: functl
534 integer,
intent(in) :: ndim
535 type(namespace_t),
intent(in) :: namespace
542 ok =
bitand(functl%flags, xc_flags_1d) /= 0
543 if (ndim == 1 .and. (.not. ok))
then
544 message(1) =
'Cannot use the specified functionals in 1D.'
548 ok =
bitand(functl%flags, xc_flags_2d) /= 0
549 if (ndim == 2 .and. (.not. ok))
then
550 message(1) =
'Cannot use the specified functionals in 2D.'
554 ok =
bitand(functl%flags, xc_flags_3d) /= 0
555 if (ndim == 3 .and. (.not. ok))
then
556 message(1) =
'Cannot use the specified functionals in 3D.'
565 type(xc_functional_t),
intent(in) :: functl
566 type(namespace_t),
intent(in) :: namespace
568 integer :: n_ext_params, ip
569 character(len=128) :: ext_params_name
572 if (.not. functl%from_libxc)
return
577 n_ext_params = xc_f03_func_info_get_n_ext_params(functl%info)
578 do ip = 0, n_ext_params-1
579 ext_params_name = xc_f03_func_info_get_ext_params_name(functl%info, ip)
581 if (ext_params_name(1:1) ==
'_') cycle
582 if (trim(xc_f03_func_info_get_ext_params_description(functl%info, ip)) ==
'Number of electrons')
then
589 message(1) =
'The selected functional is currently not supported.'
596 logical pure function xc_functional_is_energy_functional(functl)
597 type(xc_functional_t),
intent(in) :: functl
599 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.