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
243 select case (functl%id)
245 case (xc_lda_c_xalpha)
257 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
260 case (xc_lda_x_1d_soft, xc_lda_c_1d_csc)
275 call parse_variable(namespace,
'Interaction1D', option__interaction1d__interaction_soft_coulomb, interact_1d)
289 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
305 assert(xc_f03_func_info_get_n_ext_params(functl%info) == 1)
307 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
308 write(
message(1),
'(a,i1)')
"Info: Setting the number of electrons for the functional for spin ", spin_channels
318 type(xc_functional_t),
intent(inout) :: functl
322 if (functl%family /= xc_family_none .and. functl%family /= xc_family_oep .and. &
323 functl%family /= xc_family_ks_inversion .and. functl%id /=
xc_half_hartree &
326 call xc_f03_func_end(functl%conf)
340 type(xc_functional_t),
intent(in) :: functl
341 integer,
optional,
intent(in) :: iunit
342 type(namespace_t),
optional,
intent(in) :: namespace
344 character(len=120) :: family
349 if (functl%family == xc_family_oep)
then
352 select case (functl%id)
354 write(
message(1),
'(2x,a)')
'Exchange'
355 write(
message(2),
'(4x,a)')
'Exact exchange'
359 write(
message(1),
'(2x,a)')
'Exchange'
360 write(
message(2),
'(4x,a)')
'Slater exchange'
364 write(
message(1),
'(2x,a)')
'Exchange'
365 write(
message(2),
'(4x,a)')
'Force-based local exchange'
366 write(
message(3),
'(4x,a)')
'[1] Tancogne-Dejean et al., J. Chem. Phys. 160, 024103 (2024)'
370 write(
message(1),
'(2x,a)')
'Exchange'
371 write(
message(2),
'(4x,a)')
'Force-based local exchange - Sturm-Liouville'
375 write(
message(1),
'(2x,a)')
'Correlation'
376 write(
message(2),
'(4x,a)')
'Force-based local-density correlation - Sturm-Liouville'
383 else if (functl%family == xc_family_ks_inversion)
then
385 select case (functl%id)
387 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
388 write(
message(2),
'(4x,a)')
' KS Inversion'
396 write(
message(1),
'(2x,a)')
'Exchange'
397 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA)'
398 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
402 write(
message(1),
'(2x,a)')
'Exchange'
403 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel, gamma = 1.0 (MGGA)'
404 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
408 write(
message(1),
'(2x,a)')
'Exchange'
409 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA) with explicit inversion of x(y)'
410 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
411 write(
message(4),
'(4x,a)')
'[2] E. Proynov et al., Chemical Physics Letters 455, 103 (2008)'
415 write(
message(1),
'(2x,a)')
'Correlation'
416 write(
message(2),
'(4x,a)')
'Noncollinear Colle-Salvetti (MGGA)'
417 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-Correlation:'
423 write(
message(2),
'(4x,a)')
'Half-Hartree two-electron exchange'
427 write(
message(1),
'(2x,a)')
'Correlation'
428 write(
message(2),
'(4x,a)')
'Force-based LDA correlation'
429 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, M. Penz, M. Ruggenthaler, A. Rubio, J. Phys. Chem. A 129, 3132 (2025)'
432 else if (functl%family /= xc_family_none)
then
433 select case (functl%type)
435 write(
message(1),
'(2x,a)')
'Exchange'
436 case (xc_correlation)
437 write(
message(1),
'(2x,a)')
'Correlation'
438 case (xc_exchange_correlation)
439 write(
message(1),
'(2x,a)')
'Exchange-correlation'
443 write(
message(1),
'(a,i6,a,i6)')
"Unknown functional type ", functl%type,
' for functional ', functl%id
447 select case (functl%family)
449 write(family,
'(a)')
"LDA"
451 write(family,
'(a)')
"GGA"
452 case (xc_family_mgga)
453 write(family,
'(a)')
"MGGA"
456 case (xc_family_hyb_lda)
457 write(family,
'(a)')
"Hybrid LDA"
458 case (xc_family_hyb_gga)
459 write(family,
'(a)')
"Hybrid GGA"
460 case (xc_family_hyb_mgga)
461 write(family,
'(a)')
"Hybrid MGGA"
463 write(
message(2),
'(4x,4a)') trim(xc_f03_func_info_get_name(functl%info)),
' (', trim(family),
')'
468 write(
message(1),
'(4x,a,i1,2a)')
'[', ii + 1,
'] ', &
469 trim(xc_f03_func_reference_get_ref(xc_f03_func_info_get_references(functl%info, ii)))
480 integer,
intent(in) :: dim
481 integer,
intent(in) :: pseudo_x_functional, pseudo_c_functional
488 default = pseudo_x_functional
494 default = xc_lda_x_2d
496 default = xc_lda_x_1d_soft
503 default = default + libxc_c_index*pseudo_c_functional
507 default = default + libxc_c_index * xc_lda_c_pz_mod
509 default = default + libxc_c_index * xc_lda_c_2d_amgb
511 default = default + libxc_c_index * xc_lda_c_1d_csc
522 type(xc_functional_t),
intent(in) :: functl
523 integer,
intent(in) :: ndim
524 type(namespace_t),
intent(in) :: namespace
531 ok =
bitand(functl%flags, xc_flags_1d) /= 0
532 if (ndim == 1 .and. (.not. ok))
then
533 message(1) =
'Cannot use the specified functionals in 1D.'
537 ok =
bitand(functl%flags, xc_flags_2d) /= 0
538 if (ndim == 2 .and. (.not. ok))
then
539 message(1) =
'Cannot use the specified functionals in 2D.'
543 ok =
bitand(functl%flags, xc_flags_3d) /= 0
544 if (ndim == 3 .and. (.not. ok))
then
545 message(1) =
'Cannot use the specified functionals in 3D.'
554 type(xc_functional_t),
intent(in) :: functl
555 type(namespace_t),
intent(in) :: namespace
557 integer :: n_ext_params, ip
558 character(len=128) :: ext_params_name
561 if (.not. functl%from_libxc)
return
566 n_ext_params = xc_f03_func_info_get_n_ext_params(functl%info)
567 do ip = 0, n_ext_params-1
568 ext_params_name = xc_f03_func_info_get_ext_params_name(functl%info, ip)
570 if (ext_params_name(1:1) ==
'_') cycle
571 if (trim(xc_f03_func_info_get_ext_params_description(functl%info, ip)) ==
'Number of electrons')
then
578 message(1) =
'The selected functional is currently not supported.'
585 logical pure function xc_functional_is_energy_functional(functl)
586 type(xc_functional_t),
intent(in) :: functl
588 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.