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
243 if (
bitand(functl%flags, xc_flags_vv10) /= 0)
then
249 select case (functl%id)
251 case (xc_lda_c_xalpha)
263 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
266 case (xc_lda_x_1d_soft, xc_lda_c_1d_csc)
281 call parse_variable(namespace,
'Interaction1D', option__interaction1d__interaction_soft_coulomb, interact_1d)
295 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
311 assert(xc_f03_func_info_get_n_ext_params(functl%info) == 1)
313 call xc_f03_func_set_ext_params(functl%conf,
parameters(1))
314 write(
message(1),
'(a,i1)')
"Info: Setting the number of electrons for the functional for spin ", spin_channels
324 type(xc_functional_t),
intent(inout) :: functl
328 if (functl%family /= xc_family_none .and. functl%family /= xc_family_oep .and. &
329 functl%family /= xc_family_ks_inversion .and. functl%id /=
xc_half_hartree &
332 call xc_f03_func_end(functl%conf)
346 type(xc_functional_t),
intent(in) :: functl
347 integer,
optional,
intent(in) :: iunit
348 type(namespace_t),
optional,
intent(in) :: namespace
350 character(len=1024) :: reference
351 character(len=120) :: family
352 integer :: ii, ind, istart, iend
356 if (functl%family == xc_family_oep)
then
359 select case (functl%id)
361 write(
message(1),
'(2x,a)')
'Exchange'
362 write(
message(2),
'(4x,a)')
'Exact exchange'
366 write(
message(1),
'(2x,a)')
'Exchange'
367 write(
message(2),
'(4x,a)')
'Slater exchange'
371 write(
message(1),
'(2x,a)')
'Exchange'
372 write(
message(2),
'(4x,a)')
'Force-based local exchange'
373 write(
message(3),
'(4x,a)')
'[1] Tancogne-Dejean et al., J. Chem. Phys. 160, 024103 (2024)'
377 write(
message(1),
'(2x,a)')
'Exchange'
378 write(
message(2),
'(4x,a)')
'Force-based local exchange - Sturm-Liouville'
382 write(
message(1),
'(2x,a)')
'Correlation'
383 write(
message(2),
'(4x,a)')
'Force-based local-density correlation - Sturm-Liouville'
391 select case (functl%id)
393 write(
message(1),
'(2x,a)')
'RDMFT'
394 write(
message(2),
'(4x,a)')
'Mueller functional'
398 else if (functl%family == xc_family_ks_inversion)
then
400 select case (functl%id)
402 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
403 write(
message(2),
'(4x,a)')
' KS Inversion'
411 write(
message(1),
'(2x,a)')
'Exchange'
412 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA)'
413 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
417 write(
message(1),
'(2x,a)')
'Exchange'
418 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel, gamma = 1.0 (MGGA)'
419 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'
424 write(
message(2),
'(4x,a)')
'Noncollinear Becke-Roussel (MGGA) with explicit inversion of x(y)'
425 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
426 write(
message(4),
'(4x,a)')
'[2] E. Proynov et al., Chemical Physics Letters 455, 103 (2008)'
430 write(
message(1),
'(2x,a)')
'Correlation'
431 write(
message(2),
'(4x,a)')
'Noncollinear Colle-Salvetti (MGGA)'
432 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, A. Rubio, and C. A. Ullrich, Phys. Rev. B 107, 165111 (2023)'
437 write(
message(1),
'(2x,a)')
'Exchange-Correlation:'
438 write(
message(2),
'(4x,a)')
'Half-Hartree two-electron exchange'
442 write(
message(1),
'(2x,a)')
'Correlation'
443 write(
message(2),
'(4x,a)')
'Force-based LDA correlation'
444 write(
message(3),
'(4x,a)')
'[1] N. Tancogne-Dejean, M. Penz, M. Ruggenthaler, A. Rubio, J. Phys. Chem. A 129, 3132 (2025)'
447 else if (functl%family /= xc_family_none)
then
448 select case (functl%type)
450 write(
message(1),
'(2x,a)')
'Exchange'
451 case (xc_correlation)
452 write(
message(1),
'(2x,a)')
'Correlation'
453 case (xc_exchange_correlation)
454 write(
message(1),
'(2x,a)')
'Exchange-correlation'
458 write(
message(1),
'(a,i6,a,i6)')
"Unknown functional type ", functl%type,
' for functional ', functl%id
462 select case (functl%family)
464 write(family,
'(a)')
"LDA"
466 write(family,
'(a)')
"GGA"
467 case (xc_family_mgga)
468 write(family,
'(a)')
"MGGA"
471 case (xc_family_hyb_lda)
472 write(family,
'(a)')
"Hybrid LDA"
473 case (xc_family_hyb_gga)
474 write(family,
'(a)')
"Hybrid GGA"
475 case (xc_family_hyb_mgga)
476 write(family,
'(a)')
"Hybrid MGGA"
478 write(
message(2),
'(4x,4a)') trim(xc_f03_func_info_get_name(functl%info)),
' (', trim(family),
')'
485 write(reference,
'(a)') trim(xc_f03_func_reference_get_ref(xc_f03_func_info_get_references(functl%info, ii)))
487 if (len_trim(reference) == 0) cycle
490 write(
message(1),
'(4x,a,i1,2a)')
'[', ind,
'] ', trim(reference(istart:iend))
492 do while (iend < len_trim(reference))
494 iend = min(istart + len(
message(1))-10, len_trim(reference))
495 write(
message(1),
'(7x,a)') trim(reference(istart:iend))
507 integer,
intent(in) :: dim
508 integer,
intent(in) :: pseudo_x_functional, pseudo_c_functional
515 default = pseudo_x_functional
521 default = xc_lda_x_2d
523 default = xc_lda_x_1d_soft
530 default = default + libxc_c_index*pseudo_c_functional
534 default = default + libxc_c_index * xc_lda_c_pz_mod
536 default = default + libxc_c_index * xc_lda_c_2d_amgb
538 default = default + libxc_c_index * xc_lda_c_1d_csc
549 type(xc_functional_t),
intent(in) :: functl
550 integer,
intent(in) :: ndim
551 type(namespace_t),
intent(in) :: namespace
558 ok =
bitand(functl%flags, xc_flags_1d) /= 0
559 if (ndim == 1 .and. (.not. ok))
then
560 message(1) =
'Cannot use the specified functionals in 1D.'
564 ok =
bitand(functl%flags, xc_flags_2d) /= 0
565 if (ndim == 2 .and. (.not. ok))
then
566 message(1) =
'Cannot use the specified functionals in 2D.'
570 ok =
bitand(functl%flags, xc_flags_3d) /= 0
571 if (ndim == 3 .and. (.not. ok))
then
572 message(1) =
'Cannot use the specified functionals in 3D.'
581 type(xc_functional_t),
intent(in) :: functl
582 type(namespace_t),
intent(in) :: namespace
584 integer :: n_ext_params, ip
585 character(len=128) :: ext_params_name
588 if (.not. functl%from_libxc)
return
593 n_ext_params = xc_f03_func_info_get_n_ext_params(functl%info)
594 do ip = 0, n_ext_params-1
595 ext_params_name = xc_f03_func_info_get_ext_params_name(functl%info, ip)
597 if (ext_params_name(1:1) ==
'_') cycle
598 if (trim(xc_f03_func_info_get_ext_params_description(functl%info, ip)) ==
'Number of electrons')
then
605 message(1) =
'The selected functional is currently not supported.'
612 logical pure function xc_functional_is_energy_functional(functl)
613 type(xc_functional_t),
intent(in) :: functl
615 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.