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
139 functl%family = xc_family_lda
149 functl%family = xc_family_hyb_gga
161 if (functl%family == xc_family_oep)
then
162 functl%type = xc_exchange
163 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
165 else if (functl%family == xc_family_ks_inversion .or. functl%family ==
xc_family_rdmft)
then
166 functl%type = xc_exchange_correlation
167 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
170 call xc_f03_func_init(functl%conf, xc_lda_c_pw, spin_channels)
171 functl%info = xc_f03_func_get_info(functl%conf)
172 functl%type = xc_f03_func_info_get_kind(functl%info)
173 functl%flags = xc_f03_func_info_get_flags(functl%info)
178 functl%type = xc_exchange_correlation
179 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
182 functl%family = xc_family_lda
183 functl%type = xc_correlation
184 functl%flags = xc_flags_have_exc + xc_flags_have_vxc + xc_flags_3d
187 functl%type = xc_exchange
188 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
191 functl%type = xc_correlation
192 functl%flags = xc_flags_have_vxc + xc_flags_have_exc + xc_flags_3d
194 else if (functl%family == xc_family_none)
then
196 functl%flags = xc_flags_1d + xc_flags_2d + xc_flags_3d
200 functl%from_libxc = .
true.
203 select case (functl%id)
205 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_hse06, spin_channels)
208 call xc_f03_func_init(functl%conf, xc_hyb_gga_xc_pbeh, spin_channels)
211 call xc_f03_func_init(functl%conf, functl%id, spin_channels)
213 functl%info = xc_f03_func_get_info(functl%conf)
214 functl%type = xc_f03_func_info_get_kind(functl%info)
215 functl%flags = xc_f03_func_info_get_flags(functl%info)
218 if (
bitand(functl%flags, xc_flags_have_exc) == 0)
then
219 message(1) =
'Specified functional does not have total energy available.'
220 message(2) =
'Corresponding component of energy will just be left as zero.'
224 if (
bitand(functl%flags, xc_flags_have_vxc) == 0)
then
225 message(1) =
'Specified functional does not have XC potential available.'
226 message(2) =
'Cannot run calculations. Choose another XCFunctional.'
232 if (functl%family /= xc_family_none)
then
237 if (
bitand(functl%flags, xc_flags_hyb_camy) /= 0)
then
242 if (
bitand(functl%flags, xc_flags_vv10) /= 0)
then
248 select case (functl%id)
250 case (xc_lda_c_xalpha)
262 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
265 case (xc_lda_x_1d_soft, xc_lda_c_1d_csc)
280 call parse_variable(namespace,
'Interaction1D', option__interaction1d__interaction_soft_coulomb, interact_1d)
294 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
310 assert(xc_f03_func_info_get_n_ext_params(functl%info) == 1)
312 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
313 write(
message(1),
'(a,i1)')
"Info: Setting the number of electrons for the functional for spin ", spin_channels
323 type(xc_functional_t),
intent(inout) :: functl
327 if (functl%family /= xc_family_none .and. functl%family /= xc_family_oep .and. &
328 functl%family /= xc_family_ks_inversion .and. functl%id /=
xc_half_hartree &
331 call xc_f03_func_end(functl%conf)
345 type(xc_functional_t),
intent(in) :: functl
346 integer,
optional,
intent(in) :: iunit
347 type(namespace_t),
optional,
intent(in) :: namespace
349 character(len=1024) :: reference
350 character(len=120) :: family
351 integer :: ii, ind, istart, iend
355 if (functl%family == xc_family_oep)
then
358 select case (functl%id)
360 write(
message(1),
'(2x,a)')
'Exchange'
361 write(
message(2),
'(4x,a)')
'Exact exchange'
365 write(
message(1),
'(2x,a)')
'Exchange'
366 write(
message(2),
'(4x,a)')
'Slater exchange'
370 write(
message(1),
'(2x,a)')
'Exchange'
371 write(
message(2),
'(4x,a)')
'Force-based local exchange'
372 write(
message(3),
'(4x,a)')
'[1] Tancogne-Dejean et al., J. Chem. Phys. 160, 024103 (2024)'
376 write(
message(1),
'(2x,a)')
'Exchange'
377 write(
message(2),
'(4x,a)')
'Force-based local exchange - Sturm-Liouville'
381 write(
message(1),
'(2x,a)')
'Correlation'
382 write(
message(2),
'(4x,a)')
'Force-based local-density correlation - Sturm-Liouville'
390 select case (functl%id)
392 write(
message(1),
'(2x,a)')
'RDMFT'
393 write(
message(2),
'(4x,a)')
'Mueller functional'
397 else if (functl%family == xc_family_ks_inversion)
then
399 select case (functl%id)
401 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
402 write(
message(2),
'(4x,a)')
' KS Inversion'
410 write(
message(1),
'(2x,a)')
'Exchange'
411 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA)'
412 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
416 write(
message(1),
'(2x,a)')
'Exchange'
417 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel, gamma = 1.0 (MGGA)'
418 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
422 write(
message(1),
'(2x,a)')
'Exchange'
423 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA) with explicit inversion of x(y)'
424 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
425 write(
message(4),
'(4x,a)')
'[2] E. Proynov et al., Chemical Physics Letters 455, 103 (2008)'
429 write(
message(1),
'(2x,a)')
'Correlation'
430 write(
message(2),
'(4x,a)')
'Noncollinear Colle-Salvetti (MGGA)'
431 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
436 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
437 write(
message(2),
'(4x,a)')
'Half-Hartree two-electron exchange'
441 write(
message(1),
'(2x,a)')
'Correlation'
442 write(
message(2),
'(4x,a)')
'Force-based LDA correlation'
443 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, M. Penz, M. Ruggenthaler, A. Rubio, J. Phys. Chem. A 129, 3132 (2025)'
446 else if (functl%family /= xc_family_none)
then
447 select case (functl%type)
449 write(
message(1),
'(2x,a)')
'Exchange'
450 case (xc_correlation)
451 write(
message(1),
'(2x,a)')
'Correlation'
452 case (xc_exchange_correlation)
453 write(
message(1),
'(2x,a)')
'Exchange-correlation'
457 write(
message(1),
'(a,i6,a,i6)')
"Unknown functional type ", functl%type,
' for functional ', functl%id
461 select case (functl%family)
463 write(family,
'(a)')
"LDA"
465 write(family,
'(a)')
"GGA"
466 case (xc_family_mgga)
467 write(family,
'(a)')
"MGGA"
470 case (xc_family_hyb_lda)
471 write(family,
'(a)')
"Hybrid LDA"
472 case (xc_family_hyb_gga)
473 write(family,
'(a)')
"Hybrid GGA"
474 case (xc_family_hyb_mgga)
475 write(family,
'(a)')
"Hybrid MGGA"
477 write(
message(2),
'(4x,4a)') trim(xc_f03_func_info_get_name(functl%info)),
' (', trim(family),
')'
484 write(reference,
'(a)') trim(xc_f03_func_reference_get_ref(xc_f03_func_info_get_references(functl%info, ii)))
486 if (len_trim(reference) == 0) cycle
489 write(
message(1),
'(4x,a,i1,2a)')
'[', ind,
'] ', trim(reference(istart:iend))
491 do while (iend < len_trim(reference))
493 iend = min(istart + len(
message(1))-10, len_trim(reference))
494 write(
message(1),
'(7x,a)') trim(reference(istart:iend))
506 integer,
intent(in) :: dim
507 integer,
intent(in) :: pseudo_x_functional, pseudo_c_functional
514 default = pseudo_x_functional
520 default = xc_lda_x_2d
522 default = xc_lda_x_1d_soft
529 default = default + libxc_c_index*pseudo_c_functional
533 default = default + libxc_c_index * xc_lda_c_pz_mod
535 default = default + libxc_c_index * xc_lda_c_2d_amgb
537 default = default + libxc_c_index * xc_lda_c_1d_csc
548 type(xc_functional_t),
intent(in) :: functl
549 integer,
intent(in) :: ndim
550 type(namespace_t),
intent(in) :: namespace
557 ok =
bitand(functl%flags, xc_flags_1d) /= 0
558 if (ndim == 1 .and. (.not. ok))
then
559 message(1) =
'Cannot use the specified functionals in 1D.'
563 ok =
bitand(functl%flags, xc_flags_2d) /= 0
564 if (ndim == 2 .and. (.not. ok))
then
565 message(1) =
'Cannot use the specified functionals in 2D.'
569 ok =
bitand(functl%flags, xc_flags_3d) /= 0
570 if (ndim == 3 .and. (.not. ok))
then
571 message(1) =
'Cannot use the specified functionals in 3D.'
580 type(xc_functional_t),
intent(in) :: functl
581 type(namespace_t),
intent(in) :: namespace
583 integer :: n_ext_params, ip
584 character(len=128) :: ext_params_name
587 if (.not. functl%from_libxc)
return
592 n_ext_params = xc_f03_func_info_get_n_ext_params(functl%info)
593 do ip = 0, n_ext_params-1
594 ext_params_name = xc_f03_func_info_get_ext_params_name(functl%info, ip)
596 if (ext_params_name(1:1) ==
'_') cycle
597 if (trim(xc_f03_func_info_get_ext_params_description(functl%info, ip)) ==
'Number of electrons')
then
604 message(1) =
'The selected functional is currently not supported.'
611 logical pure function xc_functional_is_energy_functional(functl)
612 type(xc_functional_t),
intent(in) :: functl
614 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 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.