LCOV - code coverage report
Current view: top level - src/xc - xc_libxc.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:37370f3) Lines: 98.0 % 1218 1194
Test Date: 2026-11-05 01:01:37 Functions: 100.0 % 23 23

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief calculates a functional from libxc and its derivatives
      10              : !> \note
      11              : !>      LibXC:
      12              : !>      (Marques, Oliveira, Burnus, CPC 183, 2272 (2012)).
      13              : !>
      14              : !>      WARNING: In the subroutine libxc_spin_polarized_calc, it could be that the
      15              : !>      ordering for the 1st index of v2lapltau, v2rholapl, v2rhotau,
      16              : !>      v2sigmalapl and v2sigmatau is not correct. For the moment it does not
      17              : !>      matter since the calculation of the 2nd derivatives for meta-GGA
      18              : !>      functionals is not implemented in CP2K.
      19              : !>
      20              : !> \par History
      21              : !>      01.2013 created [F. Tran]
      22              : !>      07.2014 updates to versions 2.1 [JGH]
      23              : !>      08.2015 refactoring [A. Gloess (agloess)]
      24              : !>      01.2018 refactoring [A. Gloess (agloess)]
      25              : !>      10.2018/04.2019 added hyb_mgga [S. Simko, included by F. Stein]
      26              : !> \author F. Tran
      27              : ! **************************************************************************************************
      28              : #:include 'xc_gamma.fypp'
      29              : 
      30              : MODULE xc_libxc
      31              :    USE bibliography, ONLY: Lehtola2018, &
      32              :                            Marques2012, &
      33              :                            cite_reference
      34              :    USE input_section_types, ONLY: section_add_keyword, &
      35              :                                   section_add_subsection, &
      36              :                                   section_create, &
      37              :                                   section_release, &
      38              :                                   section_type, &
      39              :                                   section_vals_type, &
      40              :                                   section_vals_val_get
      41              :    USE kinds, ONLY: default_string_length, &
      42              :                     dp
      43              :    USE xc_derivative_set_types, ONLY: xc_derivative_set_type, &
      44              :                                       xc_dset_get_derivative
      45              :    USE xc_derivative_types, ONLY: xc_derivative_get, &
      46              :                                   xc_derivative_type
      47              :    USE xc_rho_cflags_types, ONLY: xc_rho_cflags_type
      48              :    USE xc_rho_set_types, ONLY: xc_rho_set_get, &
      49              :                                xc_rho_set_type
      50              : #include "../base/base_uses.f90"
      51              : #if defined (__LIBXC)
      52              :    USE input_keyword_types, ONLY: keyword_create, &
      53              :                                   keyword_release, &
      54              :                                   keyword_type
      55              :    USE iso_c_binding, ONLY: C_INT, C_DOUBLE
      56              :    USE xc_derivative_desc, ONLY: &
      57              :       deriv_rho, deriv_rhoa, deriv_rhob, &
      58              :       deriv_norm_drhoa, deriv_norm_drhob, deriv_norm_drho, deriv_tau_a, deriv_tau_b, deriv_tau, &
      59              :       deriv_laplace_rho, deriv_laplace_rhoa, deriv_laplace_rhob, &
      60              :       deriv_gamma, deriv_gamma_aa, deriv_gamma_ab, deriv_gamma_bb
      61              :    USE xc_libxc_wrap, ONLY: xc_f03_func_t, &
      62              :                             xc_f03_func_init, &
      63              :                             xc_f03_func_end, &
      64              :                             xc_f03_func_info_t, &
      65              :                             xc_f03_functional_get_name, &
      66              :                             xc_f03_func_get_info, &
      67              :                             xc_f03_func_info_get_family, &
      68              :                             xc_f03_func_info_get_kind, &
      69              :                             xc_f03_func_info_get_n_ext_params, &
      70              :                             xc_f03_func_info_get_name, &
      71              :                             xc_f03_available_functional_numbers, &
      72              :                             xc_f03_available_functional_names, &
      73              :                             xc_f03_maximum_name_length, &
      74              :                             xc_f03_number_of_functionals, &
      75              :                             xc_f03_func_info_get_ext_params_name, &
      76              :                             xc_f03_func_info_get_ext_params_description, &
      77              :                             xc_f03_func_info_get_ext_params_default_value, &
      78              :                             xc_f03_gga_exc, &
      79              :                             xc_f03_gga_exc_vxc, &
      80              :                             xc_f03_gga_exc_vxc_fxc, &
      81              :                             xc_f03_gga_exc_vxc_fxc_kxc, &
      82              :                             xc_f03_gga_fxc, &
      83              :                             xc_f03_gga_vxc, &
      84              :                             xc_f03_gga_vxc_fxc, &
      85              :                             xc_f03_gga_vxc_fxc_kxc, &
      86              :                             xc_f03_lda, &
      87              :                             xc_f03_lda_exc, &
      88              :                             xc_f03_lda_exc_vxc, &
      89              :                             xc_f03_lda_exc_vxc_fxc, &
      90              :                             xc_f03_lda_fxc, &
      91              :                             xc_f03_lda_kxc, &
      92              :                             xc_f03_lda_vxc, &
      93              :                             xc_f03_mgga, &
      94              :                             xc_f03_mgga_exc, &
      95              :                             xc_f03_mgga_exc_vxc, &
      96              :                             xc_f03_mgga_exc_vxc_fxc, &
      97              :                             xc_f03_mgga_exc_vxc_fxc_kxc, &
      98              :                             xc_f03_mgga_fxc, &
      99              :                             xc_f03_mgga_vxc, &
     100              :                             xc_f03_mgga_vxc_fxc, &
     101              :                             xc_f03_mgga_vxc_fxc_kxc, &
     102              :                             XC_POLARIZED, &
     103              :                             XC_UNPOLARIZED, &
     104              :                             XC_FAMILY_LDA, &
     105              :                             XC_FAMILY_GGA, &
     106              :                             XC_FAMILY_MGGA, &
     107              :                             XC_FAMILY_HYB_LDA, &
     108              :                             XC_FAMILY_HYB_GGA, &
     109              :                             XC_FAMILY_HYB_MGGA, &
     110              :                             libxc_set_backend, &
     111              :                             libxc_func_init_wrapper, &
     112              :                             libxc_gga_exc_vxc_wrapper, libxc_gga_exc_wrapper, &
     113              :                             libxc_lda_exc_vxc_wrapper, libxc_lda_exc_wrapper, &
     114              :                             libxc_mgga_exc_vxc_wrapper, libxc_mgga_exc_wrapper, &
     115              :                             libxc_mgga_vxc_wrapper, &
     116              :                             xc_libxc_wrap_functional_get_number, &
     117              :                             xc_libxc_wrap_info_needs_laplace, &
     118              :                             xc_libxc_wrap_info_no_exc, &
     119              :                             xc_libxc_wrap_is_under_development, &
     120              :                             xc_libxc_check_functional, &
     121              :                             xc_libxc_get_reference_length, &
     122              :                             xc_libxc_wrap_init_safe, &
     123              :                             xc_libxc_wrap_library_reference, &
     124              :                             xc_libxc_wrap_version, &
     125              :                             xc_libxc_wrap_set_thresholds, &
     126              :                             xc_libxc_wrap_info_refs, &
     127              :                             xc_f03_func_set_ext_params, &
     128              :                             XC_EXCHANGE, XC_CORRELATION, XC_EXCHANGE_CORRELATION, XC_KINETIC
     129              :    USE xc_libxc_wrap, ONLY: libxc_is_gpu
     130              :    USE xc_libxc_wrap, ONLY: libxc_worker_type, &
     131              :                             libxc_worker_alloc, libxc_worker_free_buffers, &
     132              :                             libxc_worker_resize_cuda, libxc_worker_eval, libxc_family_flags
     133              : #endif
     134              : !$ USE OMP_LIB, ONLY: omp_get_max_threads, &
     135              : !$                    omp_get_num_threads, &
     136              : !$                    omp_get_thread_num
     137              : 
     138              :    IMPLICIT NONE
     139              :    PRIVATE
     140              : 
     141              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_libxc'
     142              : 
     143              :    PUBLIC :: libxc_spin_unpolarized_info, libxc_spin_unpolarized_eval, &
     144              :              libxc_spin_polarized_info, libxc_spin_polarized_eval, &
     145              :              libxc_version_info, libxc_library_reference, &
     146              :              libxc_get_reference_length, libxc_add_sections, &
     147              :              libxc_check_existence_in_libxc, libxc_release_workers
     148              : 
     149              : #if defined (__LIBXC)
     150              :    PUBLIC :: libxc_set_backend
     151              : 
     152              : ! **************************************************************************************************
     153              : !> \brief All threads' workers for one distinct functional setup, together with
     154              : !>        the key that identifies that setup. Each worker (functional object plus
     155              : !>        host staging buffers and, on GPU builds, the mirroring device buffers)
     156              : !>        is implemented in xc_libxc_wrap; here they are only aggregated.
     157              : ! **************************************************************************************************
     158              :    TYPE libxc_worker_set_type
     159              :       INTEGER                                            :: func_id = -1
     160              :       INTEGER                                            :: nspin = -1
     161              :       INTEGER                                            :: family = -1
     162              :       ! highest derivative order the workers' buffers were allocated for
     163              :       INTEGER                                            :: grad_deriv = -1
     164              :       LOGICAL                                            :: has_laplace = .FALSE.
     165              :       LOGICAL                                            :: no_exc = .FALSE.
     166              :       LOGICAL                                            :: has_params = .FALSE.
     167              :       REAL(KIND=dp)                                      :: epsilon_rho = -1.0_dp
     168              :       REAL(KIND=dp)                                      :: epsilon_tau = -1.0_dp
     169              :       REAL(KIND=dp), DIMENSION(:), ALLOCATABLE           :: params
     170              :       CHARACTER(LEN=128), DIMENSION(:), ALLOCATABLE      :: param_names
     171              :       TYPE(libxc_worker_type), DIMENSION(:), ALLOCATABLE :: worker
     172              :    END TYPE libxc_worker_set_type
     173              : 
     174              :    ! Workers are acquired from a serial region only (see libxc_get_workers), so
     175              :    ! the cache itself needs no locking.
     176              :    TYPE(libxc_worker_set_type), DIMENSION(:), ALLOCATABLE, TARGET, PRIVATE, SAVE :: libxc_cache
     177              : 
     178              :    ! Stands in for the derivative arrays a given evaluation does not produce.
     179              :    ! Those arguments still have to be associated with something, but they are
     180              :    ! never read or written; pointing them at the density instead would make an
     181              :    ! output argument alias a read-only input. Grown on demand and kept for the
     182              :    ! run rather than allocated per evaluation, and like the cache above it is
     183              :    ! only ever touched from a serial region.
     184              :    REAL(KIND=dp), DIMENSION(:), ALLOCATABLE, TARGET, PRIVATE, SAVE :: libxc_unused
     185              : #endif
     186              : 
     187              :    ! Backend initialization bookkeeping
     188              :    LOGICAL, PRIVATE, SAVE :: libxc_initialized = .FALSE.
     189              : 
     190              : CONTAINS
     191              : 
     192              : ! **************************************************************************************************
     193              : !> \brief This function checks whether a functional name belongs to LibXC
     194              : !> \param libxc_params (possible) LibXC input section
     195              : !> \return exists whether the functional exists in LibXC
     196              : ! **************************************************************************************************
     197         4276 :    FUNCTION libxc_check_existence_in_libxc(libxc_params) RESULT(exists)
     198              : 
     199              :       TYPE(section_vals_type), POINTER, INTENT(IN)         :: libxc_params
     200              :       LOGICAL                                  :: exists
     201              : 
     202              : #if defined (__LIBXC)
     203              :       ! Initialize once on first call
     204         4276 :       IF (.NOT. libxc_initialized) THEN
     205          291 :          CALL xc_libxc_wrap_init_safe()
     206          291 :          libxc_initialized = .TRUE.
     207              :       END IF
     208              : 
     209         4276 :       exists = xc_libxc_check_functional(libxc_params%section%name)
     210              : #else
     211              :       MARK_USED(libxc_params)
     212              :       exists = .FALSE.
     213              : #endif
     214              : 
     215         4276 :    END FUNCTION libxc_check_existence_in_libxc
     216              : 
     217              : ! **************************************************************************************************
     218              : !> \brief This function returns the maximum length of the reference string for a given LibXC functional
     219              : !> \param libxc_params LibXC input section
     220              : !> \param lsd spin polarized calculation
     221              : !> \return maximum length of the string
     222              : ! **************************************************************************************************
     223          121 :    FUNCTION libxc_get_reference_length(libxc_params, lsd) RESULT(length)
     224              : 
     225              :       TYPE(section_vals_type), POINTER, INTENT(IN)         :: libxc_params
     226              :       LOGICAL, INTENT(IN)                      :: lsd
     227              :       INTEGER                                  :: length
     228              : 
     229              : #if defined (__LIBXC)
     230              :       CHARACTER(len=*), PARAMETER :: routineN = 'libxc_get_reference_length'
     231              : 
     232              :       CHARACTER(LEN=default_string_length)     :: func_name
     233              :       INTEGER                                  :: func_id, handle
     234              :       TYPE(xc_f03_func_t)                      :: xc_func
     235              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     236              : 
     237          121 :       CALL timeset(routineN, handle)
     238              : 
     239          121 :       func_name = libxc_params%section%name
     240              : 
     241          121 :       func_id = xc_libxc_wrap_functional_get_number(func_name)
     242          121 :       IF (lsd) THEN
     243           57 :          CALL libxc_func_init_wrapper(xc_func, func_id, XC_POLARIZED, force_host=.TRUE.)
     244              :       ELSE
     245           64 :          CALL libxc_func_init_wrapper(xc_func, func_id, XC_UNPOLARIZED, force_host=.TRUE.)
     246              :       END IF
     247          121 :       xc_info = xc_f03_func_get_info(xc_func)
     248              : 
     249          121 :       length = xc_libxc_get_reference_length(xc_info)
     250              : 
     251          121 :       CALL xc_f03_func_end(xc_func)
     252              : 
     253          121 :       CALL timestop(handle)
     254              : #else
     255              :       MARK_USED(libxc_params)
     256              :       MARK_USED(lsd)
     257              :       length = 0
     258              :       CPABORT("In order to use LibXC you have to download and install it!")
     259              : #endif
     260              : 
     261          121 :    END FUNCTION libxc_get_reference_length
     262              : 
     263              : ! **************************************************************************************************
     264              : !> \brief ...
     265              : !> \param section ...
     266              : ! **************************************************************************************************
     267        14733 :    SUBROUTINE libxc_add_sections(section)
     268              : 
     269              :       TYPE(section_type), POINTER, INTENT(IN) :: section
     270              : 
     271              : #if defined (__LIBXC)
     272              :       CHARACTER(len=*), PARAMETER :: routineN = 'libxc_add_sections'
     273              : 
     274              :       TYPE(section_type), POINTER :: subsection
     275              :       TYPE(keyword_type), POINTER :: keyword
     276              :       INTEGER :: handle, no_func, len_name, ii, func_id, n_param, iparam
     277              :       REAL(KIND=C_DOUBLE) :: default_val
     278              :       CHARACTER(LEN=128) :: func_name, param_name, param_descr, description
     279              :       CHARACTER(LEN=2*default_string_length) :: warning
     280        14733 :       INTEGER(KIND=C_INT), DIMENSION(:), ALLOCATABLE :: func_ids
     281              :       TYPE(xc_f03_func_t)                      :: xc_func
     282              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     283              : 
     284        14733 :       CALL timeset(routineN, handle)
     285              : 
     286        14733 :       CPASSERT(ASSOCIATED(section))
     287        14733 :       NULLIFY (subsection, keyword)
     288              : 
     289        14733 :       no_func = xc_f03_number_of_functionals()
     290        14733 :       len_name = xc_f03_maximum_name_length()
     291              : 
     292        44199 :       ALLOCATE (func_ids(no_func))
     293              : 
     294        14733 :       CALL xc_f03_available_functional_numbers(func_ids)
     295              : 
     296     10504629 :       DO ii = 1, no_func
     297              : 
     298     10489896 :          func_id = func_ids(ii)
     299     10489896 :          IF (ii > 1) THEN
     300     10475163 :             IF (func_id == func_ids(ii - 1)) CYCLE
     301              :          END IF
     302     10342566 :          CALL libxc_func_init_wrapper(xc_func, func_id, XC_UNPOLARIZED, force_host=.TRUE.)
     303     10342566 :          xc_info = xc_f03_func_get_info(xc_func)
     304              : 
     305     10342566 :          func_name = xc_f03_functional_get_name(func_id)
     306     10342566 :          description = xc_f03_func_info_get_name(xc_info)
     307     10342566 :          n_param = xc_f03_func_info_get_n_ext_params(xc_info)
     308              : 
     309     10342566 :          NULLIFY (subsection)
     310              :          CALL section_create(subsection, __LOCATION__, name=TRIM(func_name), description=TRIM(description), &
     311     10342566 :                              n_keywords=2 + n_param, n_subsections=0, repeats=.FALSE.)
     312              : 
     313     10342566 :          IF (description(1:1) == "_") THEN
     314              :             warning = " This parameter is an internal parameter of the functional. Changing this "// &
     315            0 :                       "parameter effectively changes the functional."
     316              :          ELSE
     317     10342566 :             warning = " "
     318              :          END IF
     319              : 
     320     10342566 :          NULLIFY (keyword)
     321              :          CALL keyword_create(keyword, __LOCATION__, name="_SECTION_PARAMETERS_", &
     322              :                              description="Activates the functional."//TRIM(warning), &
     323     10342566 :                              lone_keyword_l_val=.TRUE., default_l_val=.FALSE.)
     324     10342566 :          CALL section_add_keyword(subsection, keyword)
     325     10342566 :          CALL keyword_release(keyword)
     326              : 
     327              :          CALL keyword_create(keyword, __LOCATION__, name="SCALE", description="Scales this functional", &
     328     10342566 :                              default_r_val=1.0_dp)
     329     10342566 :          CALL section_add_keyword(subsection, keyword)
     330     10342566 :          CALL keyword_release(keyword)
     331              : 
     332     63013041 :          DO iparam = 1, n_param
     333     52670475 :             param_name = xc_f03_func_info_get_ext_params_name(xc_info, iparam - 1)
     334     52670475 :             param_descr = xc_f03_func_info_get_ext_params_description(xc_info, iparam - 1)
     335     52670475 :             default_val = xc_f03_func_info_get_ext_params_default_value(xc_info, iparam - 1)
     336     52670475 :             NULLIFY (keyword)
     337              :             CALL keyword_create(keyword, __LOCATION__, name=TRIM(param_name), &
     338     52670475 :                                 description=TRIM(param_descr), default_r_val=default_val)
     339     52670475 :             CALL section_add_keyword(subsection, keyword)
     340     63013041 :             CALL keyword_release(keyword)
     341              :          END DO
     342              : 
     343     10342566 :          CALL section_add_subsection(section, subsection)
     344     10342566 :          CALL section_release(subsection)
     345              : 
     346     10504629 :          CALL xc_f03_func_end(xc_func)
     347              : 
     348              :       END DO
     349              : 
     350        14733 :       DEALLOCATE (func_ids)
     351              : 
     352        14733 :       CALL timestop(handle)
     353              : #else
     354              :       MARK_USED(section)
     355              : 
     356              : #endif
     357              : 
     358        14733 :    END SUBROUTINE libxc_add_sections
     359              : 
     360              : ! **************************************************************************************************
     361              : !> \brief info about the functional from libxc
     362              : !> \param libxc_params input parameter (functional name, scaling and parameters)
     363              : !> \param reference string with the reference of the actual functional
     364              : !> \param shortform string with the shortform of the functional name
     365              : !> \param needs the components needed by this functional are set to
     366              : !>        true (does not set the unneeded components to false)
     367              : !> \param max_deriv maximum implemented derivative of the xc functional
     368              : !> \param print_warn whether to print warning about development status of a functional
     369              : !> \param func_name_override optional LibXC functional name overriding the section name
     370              : !> \author F. Tran
     371              : ! **************************************************************************************************
     372        15786 :    SUBROUTINE libxc_spin_unpolarized_info(libxc_params, reference, shortform, needs, max_deriv, print_warn, &
     373              :                                           func_name_override)
     374              : 
     375              :       TYPE(section_vals_type), POINTER         :: libxc_params
     376              :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL  :: reference, shortform
     377              :       TYPE(xc_rho_cflags_type), &
     378              :          INTENT(inout), OPTIONAL               :: needs
     379              :       INTEGER, INTENT(out), OPTIONAL           :: max_deriv
     380              :       LOGICAL, INTENT(IN), OPTIONAL            :: print_warn
     381              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL   :: func_name_override
     382              : 
     383              : #if defined (__LIBXC)
     384              :       CHARACTER(LEN=128)                       :: s1, s2
     385              :       CHARACTER(LEN=default_string_length)     :: func_name
     386              :       INTEGER                                  :: func_id
     387              :       REAL(KIND=dp)                            :: func_scale
     388              :       TYPE(xc_f03_func_t)                      :: xc_func
     389              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     390              : 
     391        31484 :       IF (PRESENT(func_name_override)) THEN
     392           88 :          func_name = func_name_override
     393           88 :          func_scale = 1.0_dp
     394              :       ELSE
     395        15698 :          func_name = libxc_params%section%name
     396        15698 :          CALL section_vals_val_get(libxc_params, "scale", r_val=func_scale)
     397              :       END IF
     398              : 
     399        15786 :       CALL cite_reference(Marques2012)
     400        15786 :       CALL cite_reference(Lehtola2018)
     401              : 
     402        15786 :       IF (ABS(func_scale - 1.0_dp) < 1.0e-10_dp) func_scale = 1.0_dp
     403              : 
     404        15786 :       func_id = xc_libxc_wrap_functional_get_number(func_name)
     405        15786 :       CALL libxc_func_init_wrapper(xc_func, func_id, XC_UNPOLARIZED, force_host=.TRUE.)
     406        15786 :       xc_info = xc_f03_func_get_info(xc_func)
     407              : 
     408        15786 :       s1 = xc_f03_func_info_get_name(xc_info)
     409        10336 :       SELECT CASE (xc_f03_func_info_get_kind(xc_info))
     410        10336 :       CASE (XC_EXCHANGE); WRITE (s2, '(a)') "exchange"
     411         3452 :       CASE (XC_CORRELATION); WRITE (s2, '(a)') "correlation"
     412         1668 :       CASE (XC_EXCHANGE_CORRELATION); WRITE (s2, '(a)') "exchange-correlation"
     413          330 :       CASE (XC_KINETIC); WRITE (s2, '(a)') "kinetic"
     414              :       CASE default
     415        15786 :          CPABORT(TRIM(func_name)//": this XC_KIND is currently not supported.")
     416              :       END SELECT
     417        15786 :       IF (PRESENT(shortform)) THEN
     418           64 :          shortform = TRIM(s1)//' ('//TRIM(s2)//')'
     419              :       END IF
     420        15786 :       IF (PRESENT(reference)) THEN
     421           64 :          CALL xc_libxc_wrap_info_refs(xc_info, XC_UNPOLARIZED, func_scale, reference)
     422              :       END IF
     423        15786 :       IF (PRESENT(needs)) THEN
     424         5960 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
     425              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
     426         5960 :             needs%rho = .TRUE.
     427              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
     428         6532 :             needs%rho = .TRUE.
     429         6532 :             needs%norm_drho = .TRUE.
     430              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     431         3222 :             needs%rho = .TRUE.
     432         3222 :             needs%norm_drho = .TRUE.
     433         3222 :             needs%tau = .TRUE.
     434         3222 :             needs%laplace_rho = xc_libxc_wrap_info_needs_laplace(xc_info)
     435              :          CASE default
     436        15714 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
     437              :          END SELECT
     438              :       END IF
     439        15786 :       IF (PRESENT(max_deriv)) THEN
     440            0 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
     441              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
     442            0 :             max_deriv = 3
     443              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
     444           88 :             max_deriv = 2
     445              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     446            0 :             max_deriv = 2
     447              :          CASE default
     448           88 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
     449              :          END SELECT
     450              :       END IF
     451        15786 :       IF (PRESENT(print_warn)) THEN
     452            0 :          IF (print_warn .AND. xc_libxc_wrap_is_under_development(xc_info)) THEN
     453            0 :             CPWARN(TRIM(func_name)//" is under development. Use with caution.")
     454              :          END IF
     455              :       END IF
     456              : 
     457        15786 :       CALL xc_f03_func_end(xc_func)
     458              : #else
     459              :       MARK_USED(libxc_params)
     460              :       MARK_USED(reference)
     461              :       MARK_USED(shortform)
     462              :       MARK_USED(needs)
     463              :       MARK_USED(max_deriv)
     464              :       MARK_USED(print_warn)
     465              :       MARK_USED(func_name_override)
     466              : 
     467              :       CALL cp_abort(__LOCATION__, "Unknown functional! If you are asking "// &
     468              :                     "for a functional of the LibXC library, "// &
     469              :                     "you have to download and install the library!")
     470              : #endif
     471              : 
     472        15786 :    END SUBROUTINE libxc_spin_unpolarized_info
     473              : 
     474              : ! **************************************************************************************************
     475              : !> \brief info about the functional from libxc
     476              : !> \param libxc_params input parameter (functional name, scaling and parameters)
     477              : !> \param reference string with the reference of the actual functional
     478              : !> \param shortform string with the shortform of the functional name
     479              : !> \param needs the components needed by this functional are set to
     480              : !>        true (does not set the unneeded components to false)
     481              : !> \param max_deriv maximum implemented derivative of the xc functional
     482              : !> \param print_warn whether to print warning about development status of a functional
     483              : !> \param func_name_override optional LibXC functional name overriding the section name
     484              : !> \author F. Tran
     485              : ! **************************************************************************************************
     486         4135 :    SUBROUTINE libxc_spin_polarized_info(libxc_params, reference, shortform, needs, max_deriv, print_warn, &
     487              :                                         func_name_override)
     488              : 
     489              :       TYPE(section_vals_type), POINTER         :: libxc_params
     490              :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL  :: reference, shortform
     491              :       TYPE(xc_rho_cflags_type), &
     492              :          INTENT(inout), OPTIONAL               :: needs
     493              :       INTEGER, INTENT(out), OPTIONAL           :: max_deriv
     494              :       LOGICAL, INTENT(IN), OPTIONAL            :: print_warn
     495              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL   :: func_name_override
     496              : 
     497              : #if defined (__LIBXC)
     498              :       CHARACTER(LEN=128)                       :: s1, s2
     499              :       CHARACTER(LEN=default_string_length)     :: func_name
     500              :       INTEGER                                  :: func_id
     501              :       REAL(KIND=dp)                            :: func_scale
     502              :       TYPE(xc_f03_func_t)                      :: xc_func
     503              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     504              : 
     505         8246 :       IF (PRESENT(func_name_override)) THEN
     506           24 :          func_name = func_name_override
     507           24 :          func_scale = 1.0_dp
     508              :       ELSE
     509         4111 :          func_name = libxc_params%section%name
     510         4111 :          CALL section_vals_val_get(libxc_params, "scale", r_val=func_scale)
     511              :       END IF
     512              : 
     513         4135 :       CALL cite_reference(Marques2012)
     514         4135 :       CALL cite_reference(Lehtola2018)
     515              : 
     516         4135 :       IF (ABS(func_scale - 1.0_dp) < 1.0e-10_dp) func_scale = 1.0_dp
     517              : 
     518         4135 :       func_id = xc_libxc_wrap_functional_get_number(func_name)
     519         4135 :       CALL libxc_func_init_wrapper(xc_func, func_id, XC_POLARIZED, force_host=.TRUE.)
     520         4135 :       xc_info = xc_f03_func_get_info(xc_func)
     521              : 
     522         4135 :       s1 = xc_f03_func_info_get_name(xc_info)
     523         2100 :       SELECT CASE (xc_f03_func_info_get_kind(xc_info))
     524         2100 :       CASE (XC_EXCHANGE); WRITE (s2, '(a)') "exchange"
     525         1789 :       CASE (XC_CORRELATION); WRITE (s2, '(a)') "correlation"
     526          246 :       CASE (XC_EXCHANGE_CORRELATION); WRITE (s2, '(a)') "exchange-correlation"
     527            0 :       CASE (XC_KINETIC); WRITE (s2, '(a)') "kinetic"
     528              :       CASE default
     529         4135 :          CPABORT(TRIM(func_name)//": this XC_KIND is currently not supported.")
     530              :       END SELECT
     531         4135 :       IF (PRESENT(shortform)) THEN
     532           57 :          shortform = TRIM(s1)//' ('//TRIM(s2)//')'
     533              :       END IF
     534         4135 :       IF (PRESENT(reference)) THEN
     535           57 :          CALL xc_libxc_wrap_info_refs(xc_info, XC_POLARIZED, func_scale, reference)
     536              :       END IF
     537         4135 :       IF (PRESENT(needs)) THEN
     538         1164 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
     539              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
     540         1164 :             needs%rho_spin = .TRUE.
     541              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
     542          690 :             needs%rho_spin = .TRUE.
     543          690 :             needs%norm_drho = .TRUE.
     544          690 :             needs%norm_drho_spin = .TRUE.
     545              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     546         2224 :             needs%rho_spin = .TRUE.
     547         2224 :             needs%norm_drho = .TRUE.
     548         2224 :             needs%norm_drho_spin = .TRUE.
     549         2224 :             needs%tau_spin = .TRUE.
     550         2224 :             needs%laplace_rho_spin = xc_libxc_wrap_info_needs_laplace(xc_info)
     551              :          CASE default
     552         4078 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
     553              :          END SELECT
     554              :       END IF
     555         4135 :       IF (PRESENT(max_deriv)) THEN
     556            0 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
     557              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
     558            0 :             max_deriv = 3
     559              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
     560           24 :             max_deriv = 2
     561              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     562            0 :             max_deriv = 2
     563              :          CASE default
     564           24 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
     565              :          END SELECT
     566              :       END IF
     567         4135 :       IF (PRESENT(print_warn)) THEN
     568            0 :          IF (print_warn .AND. xc_libxc_wrap_is_under_development(xc_info)) THEN
     569            0 :             CPWARN(TRIM(func_name)//" is under development. Use with caution.")
     570              :          END IF
     571              :       END IF
     572              : 
     573         4135 :       CALL xc_f03_func_end(xc_func)
     574              : #else
     575              :       MARK_USED(libxc_params)
     576              :       MARK_USED(reference)
     577              :       MARK_USED(shortform)
     578              :       MARK_USED(needs)
     579              :       MARK_USED(max_deriv)
     580              :       MARK_USED(print_warn)
     581              :       MARK_USED(func_name_override)
     582              : 
     583              :       CALL cp_abort(__LOCATION__, "Unknown functional! If you are "// &
     584              :                     "asking for a functional of the LibXC library, "// &
     585              :                     "you have to download and install the library!")
     586              : #endif
     587              : 
     588         4135 :    END SUBROUTINE libxc_spin_polarized_info
     589              : 
     590              : ! **************************************************************************************************
     591              : !> \brief info about the LibXC version
     592              : !> \param version version string reported by the library at run time
     593              : !> \param compiled_version version of the LibXC headers CP2K was compiled against
     594              : !> \author A. Gloess (agloess)
     595              : ! **************************************************************************************************
     596           76 :    SUBROUTINE libxc_version_info(version, compiled_version)
     597              :       CHARACTER(LEN=*), INTENT(OUT)      :: version ! the string that is output
     598              :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL :: compiled_version
     599              : 
     600              : #if defined (__LIBXC)
     601           76 :       CALL xc_libxc_wrap_version(version, compiled_version)
     602              : #else
     603              :       version = "none"
     604              :       IF (PRESENT(compiled_version)) compiled_version = "none"
     605              :       CPABORT("In order to use libxc you need to download and install it")
     606              : #endif
     607              : 
     608           76 :    END SUBROUTINE libxc_version_info
     609              : 
     610              : ! **************************************************************************************************
     611              : !> \brief Returns the citation LibXC asks for the library itself.
     612              : !> \param reference bibliographic reference
     613              : !> \param doi digital object identifier of that reference
     614              : !> \author S. Lehtola
     615              : ! **************************************************************************************************
     616           76 :    SUBROUTINE libxc_library_reference(reference, doi)
     617              :       CHARACTER(LEN=*), INTENT(OUT)      :: reference, doi
     618              : 
     619              : #if defined (__LIBXC)
     620           76 :       CALL xc_libxc_wrap_library_reference(reference, doi)
     621              : #else
     622              :       reference = "none"
     623              :       doi = "none"
     624              :       CPABORT("In order to use libxc you need to download and install it")
     625              : #endif
     626              : 
     627           76 :    END SUBROUTINE libxc_library_reference
     628              : 
     629              : ! **************************************************************************************************
     630              : !> \brief Reads the external parameters of a LibXC functional from its input section.
     631              : !> \param libxc_params LibXC input section
     632              : !> \param param_names names of the external parameters, as reported by LibXC
     633              : !> \param params values read from the input
     634              : !> \author S. Lehtola
     635              : ! **************************************************************************************************
     636              : #if defined (__LIBXC)
     637        15394 :    SUBROUTINE libxc_read_params(libxc_params, param_names, params)
     638              :       TYPE(section_vals_type), INTENT(IN), POINTER       :: libxc_params
     639              :       CHARACTER(LEN=128), DIMENSION(:), INTENT(IN)       :: param_names
     640              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: params
     641              : 
     642              :       INTEGER                                            :: i
     643              : 
     644       100452 :       DO i = 1, SIZE(param_names)
     645       100452 :          CALL section_vals_val_get(libxc_params, TRIM(param_names(i)), r_val=params(i))
     646              :       END DO
     647              : 
     648        15394 :    END SUBROUTINE libxc_read_params
     649              : 
     650              : ! **************************************************************************************************
     651              : !> \brief Makes sure the placeholder for unproduced derivatives holds npoints values.
     652              : !> \param npoints number of grid points in this evaluation
     653              : !> \author S. Lehtola
     654              : ! **************************************************************************************************
     655        27184 :    SUBROUTINE libxc_reserve_unused(npoints)
     656              :       INTEGER, INTENT(IN)                                :: npoints
     657              : 
     658        27184 :       IF (ALLOCATED(libxc_unused)) THEN
     659        26856 :          IF (SIZE(libxc_unused) >= npoints) RETURN
     660            2 :          DEALLOCATE (libxc_unused)
     661              :       END IF
     662          990 :       ALLOCATE (libxc_unused(npoints))
     663              : 
     664              :    END SUBROUTINE libxc_reserve_unused
     665              : 
     666              : ! **************************************************************************************************
     667              : !> \brief Returns the cache slot holding the per-thread workers for a functional.
     668              : !> \param func_name LibXC functional name
     669              : !> \param nspin XC_UNPOLARIZED or XC_POLARIZED
     670              : !> \param libxc_params LibXC input section, or null when no parameters are to be set
     671              : !> \param epsilon_rho density cutoff
     672              : !> \param epsilon_tau kinetic energy density cutoff
     673              : !> \param grad_deriv highest derivative order this evaluation needs
     674              : !> \return index into libxc_cache
     675              : !> \author S. Lehtola
     676              : !> \note Must be called from a serial region: it is the only writer of the cache,
     677              : !>       and keeping it serial is what makes the cache lock-free. The workers it
     678              : !>       returns are then used concurrently, one per thread.
     679              : ! **************************************************************************************************
     680        27184 :    FUNCTION libxc_get_workers(func_name, nspin, libxc_params, epsilon_rho, epsilon_tau, &
     681              :                               grad_deriv) RESULT(idx)
     682              :       CHARACTER(LEN=*), INTENT(IN)                       :: func_name
     683              :       INTEGER, INTENT(IN)                                :: nspin
     684              :       TYPE(section_vals_type), INTENT(IN), POINTER       :: libxc_params
     685              :       REAL(KIND=dp), INTENT(IN)                          :: epsilon_rho, epsilon_tau
     686              :       INTEGER, INTENT(IN)                                :: grad_deriv
     687              :       INTEGER                                            :: idx
     688              : 
     689              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'libxc_get_workers'
     690              : 
     691              :       INTEGER                                            :: func_id, handle, i, ithread, n_params, &
     692              :                                                             nthreads
     693              :       LOGICAL                                            :: has_params
     694        27184 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: params
     695              :       TYPE(libxc_worker_set_type), ALLOCATABLE, &
     696        27184 :          DIMENSION(:)                                    :: tmp_cache
     697              : 
     698        27184 :       CALL timeset(routineN, handle)
     699              : 
     700        27184 :       func_id = xc_libxc_wrap_functional_get_number(func_name)
     701        27184 :       has_params = ASSOCIATED(libxc_params)
     702              : 
     703        27184 :       nthreads = 1
     704        27184 : !$    nthreads = omp_get_max_threads()
     705              : 
     706        27184 :       IF (.NOT. ALLOCATED(libxc_cache)) ALLOCATE (libxc_cache(0))
     707              : 
     708        27184 :       idx = 0
     709        68160 :       DO i = 1, SIZE(libxc_cache)
     710              :          IF (libxc_cache(i)%func_id == func_id .AND. &
     711        67580 :              libxc_cache(i)%nspin == nspin .AND. &
     712          580 :              (libxc_cache(i)%has_params .EQV. has_params)) THEN
     713              :             IF (libxc_cache(i)%epsilon_rho == epsilon_rho .AND. &
     714        27684 :                 libxc_cache(i)%epsilon_tau == epsilon_tau .AND. &
     715              :                 SIZE(libxc_cache(i)%worker) >= nthreads) THEN
     716              :                idx = i
     717              :                EXIT
     718              :             END IF
     719              :          END IF
     720              :       END DO
     721              : 
     722              :       ! A set built for a lower derivative order carries buffers that are too
     723              :       ! narrow for this call. Widening them in place keeps one set per functional
     724              :       ! setup: the SCF fills the cache at first order and a later response
     725              :       ! calculation grows that same slot to third order.
     726        27184 :       IF (idx /= 0) THEN
     727        26604 :          IF (libxc_cache(idx)%grad_deriv < grad_deriv) THEN
     728          320 :             DO ithread = 1, SIZE(libxc_cache(idx)%worker)
     729          160 :                CALL libxc_worker_free_buffers(libxc_cache(idx)%worker(ithread))
     730              :                CALL libxc_worker_alloc(libxc_cache(idx)%worker(ithread), &
     731          320 :                                        libxc_cache(idx)%family, nspin, grad_deriv)
     732              :             END DO
     733          160 :             libxc_cache(idx)%grad_deriv = grad_deriv
     734              :          END IF
     735              :       END IF
     736              : 
     737              :       IF (idx == 0) THEN
     738              :          ! Grow the cache by one slot and build the workers for it.
     739          580 :          CALL MOVE_ALLOC(libxc_cache, tmp_cache)
     740         2968 :          ALLOCATE (libxc_cache(SIZE(tmp_cache) + 1))
     741         1228 :          DO i = 1, SIZE(tmp_cache)
     742         1228 :             CALL libxc_move_worker_set(tmp_cache(i), libxc_cache(i))
     743              :          END DO
     744         1808 :          DEALLOCATE (tmp_cache)
     745          580 :          idx = SIZE(libxc_cache)
     746              : 
     747              :          ASSOCIATE (ws => libxc_cache(idx))
     748          580 :             ws%func_id = func_id
     749          580 :             ws%nspin = nspin
     750          580 :             ws%has_params = has_params
     751          580 :             ws%epsilon_rho = epsilon_rho
     752          580 :             ws%epsilon_tau = epsilon_tau
     753          580 :             ws%grad_deriv = grad_deriv
     754         2320 :             ALLOCATE (ws%worker(nthreads))
     755              : 
     756         1160 :             DO ithread = 1, nthreads
     757          580 :                CALL libxc_func_init_wrapper(ws%worker(ithread)%func, func_id, nspin)
     758          580 :                ws%worker(ithread)%info = xc_f03_func_get_info(ws%worker(ithread)%func)
     759         1160 :                ws%worker(ithread)%is_init = .TRUE.
     760              :             END DO
     761              : 
     762          580 :             ws%family = xc_f03_func_info_get_family(ws%worker(1)%info)
     763          580 :             ws%has_laplace = xc_libxc_wrap_info_needs_laplace(ws%worker(1)%info)
     764          580 :             ws%no_exc = xc_libxc_wrap_info_no_exc(ws%worker(1)%info)
     765              : 
     766              :             ! Remember the parameter names so that later evaluations can re-read
     767              :             ! the input without another functional object to ask for them.
     768          580 :             n_params = 0
     769          580 :             IF (has_params) n_params = xc_f03_func_info_get_n_ext_params(ws%worker(1)%info)
     770         1602 :             ALLOCATE (ws%params(n_params))
     771         1602 :             ALLOCATE (ws%param_names(n_params))
     772         2920 :             DO i = 1, n_params
     773         2920 :                ws%param_names(i) = xc_f03_func_info_get_ext_params_name(ws%worker(1)%info, i - 1)
     774              :             END DO
     775          580 :             IF (n_params > 0) THEN
     776          442 :                CALL libxc_read_params(libxc_params, ws%param_names, ws%params)
     777          884 :                DO ithread = 1, nthreads
     778          884 :                   CALL xc_f03_func_set_ext_params(ws%worker(ithread)%func, ws%params)
     779              :                END DO
     780              :             END IF
     781              : 
     782         1740 :             DO ithread = 1, nthreads
     783              :                CALL xc_libxc_wrap_set_thresholds(ws%worker(ithread)%func, ws%worker(ithread)%info, &
     784          580 :                                                  epsilon_rho, epsilon_tau)
     785         1160 :                CALL libxc_worker_alloc(ws%worker(ithread), ws%family, nspin, grad_deriv)
     786              :             END DO
     787              :          END ASSOCIATE
     788              :       ELSE
     789              :          ! Cached slot: the input section may in principle carry different
     790              :          ! parameter values than the ones the workers were last set up with, so
     791              :          ! re-read them and push them through only when they actually changed.
     792              :          ASSOCIATE (ws => libxc_cache(idx))
     793        26604 :             n_params = SIZE(ws%params)
     794        26604 :             IF (n_params > 0) THEN
     795        44856 :                ALLOCATE (params(n_params))
     796        14952 :                CALL libxc_read_params(libxc_params, ws%param_names, params)
     797        97670 :                IF (ANY(params /= ws%params)) THEN
     798            0 :                   ws%params(:) = params(:)
     799            0 :                   DO ithread = 1, SIZE(ws%worker)
     800            0 :                      CALL xc_f03_func_set_ext_params(ws%worker(ithread)%func, ws%params)
     801              :                      ! re-assert the cutoffs: setting parameters runs the
     802              :                      ! functional's own callback, which is free to rebuild the
     803              :                      ! component functionals a mixed functional is made of
     804              :                      CALL xc_libxc_wrap_set_thresholds(ws%worker(ithread)%func, &
     805              :                                                        ws%worker(ithread)%info, &
     806            0 :                                                        ws%epsilon_rho, ws%epsilon_tau)
     807              :                   END DO
     808              :                END IF
     809        14952 :                DEALLOCATE (params)
     810              :             END IF
     811              :          END ASSOCIATE
     812              :       END IF
     813              : 
     814        27184 :       CALL timestop(handle)
     815              : 
     816        27184 :    END FUNCTION libxc_get_workers
     817              : 
     818              : ! **************************************************************************************************
     819              : !> \brief Moves a worker set to a new cache slot without touching LibXC.
     820              : !> \param from source slot, left empty
     821              : !> \param to destination slot
     822              : !> \author S. Lehtola
     823              : !> \note Used when the cache array grows. The LibXC objects are opaque handles, so
     824              : !>       they survive being moved; only the Fortran allocatables need transferring.
     825              : ! **************************************************************************************************
     826          648 :    SUBROUTINE libxc_move_worker_set(from, to)
     827              :       TYPE(libxc_worker_set_type), INTENT(INOUT)         :: from, to
     828              : 
     829          648 :       to%func_id = from%func_id
     830          648 :       to%nspin = from%nspin
     831          648 :       to%family = from%family
     832          648 :       to%grad_deriv = from%grad_deriv
     833          648 :       to%has_laplace = from%has_laplace
     834          648 :       to%no_exc = from%no_exc
     835          648 :       to%has_params = from%has_params
     836          648 :       to%epsilon_rho = from%epsilon_rho
     837          648 :       to%epsilon_tau = from%epsilon_tau
     838          648 :       IF (ALLOCATED(from%params)) CALL MOVE_ALLOC(from%params, to%params)
     839          648 :       IF (ALLOCATED(from%param_names)) CALL MOVE_ALLOC(from%param_names, to%param_names)
     840          648 :       IF (ALLOCATED(from%worker)) CALL MOVE_ALLOC(from%worker, to%worker)
     841              : 
     842          648 :    END SUBROUTINE libxc_move_worker_set
     843              : #endif
     844              : 
     845              : ! **************************************************************************************************
     846              : !> \brief Destroys all cached LibXC functional objects.
     847              : !> \author S. Lehtola
     848              : !> \note Call once at the end of a run. The workers are deliberately kept alive
     849              : !>       across SCF steps and across calculations, so nothing else releases them.
     850              : ! **************************************************************************************************
     851        13055 :    SUBROUTINE libxc_release_workers()
     852              : 
     853              : #if defined (__LIBXC)
     854              :       INTEGER                                            :: i, ithread
     855              : 
     856        13055 :       IF (.NOT. ALLOCATED(libxc_cache)) RETURN
     857              : 
     858          908 :       DO i = 1, SIZE(libxc_cache)
     859          580 :          IF (.NOT. ALLOCATED(libxc_cache(i)%worker)) CYCLE
     860         1488 :          DO ithread = 1, SIZE(libxc_cache(i)%worker)
     861          580 :             IF (libxc_cache(i)%worker(ithread)%is_init) THEN
     862          580 :                CALL xc_f03_func_end(libxc_cache(i)%worker(ithread)%func)
     863          580 :                libxc_cache(i)%worker(ithread)%is_init = .FALSE.
     864              :             END IF
     865              :             ! Free the staging buffers and any device buffers they mirror.
     866         1160 :             CALL libxc_worker_free_buffers(libxc_cache(i)%worker(ithread))
     867              :          END DO
     868              :       END DO
     869         1488 :       DEALLOCATE (libxc_cache)
     870          328 :       IF (ALLOCATED(libxc_unused)) DEALLOCATE (libxc_unused)
     871              : #endif
     872              : 
     873              :    END SUBROUTINE libxc_release_workers
     874              : 
     875              : ! **************************************************************************************************
     876              : !> \brief evaluates the functional from libxc
     877              : !> \param rho_set the density where you want to evaluate the functional
     878              : !> \param deriv_set place where to store the functional derivatives (they are
     879              : !>        added to the derivatives)
     880              : !> \param grad_deriv maximum degree of the derivative that should be evaluated;
     881              : !>        all derivatives up to the given degree are evaluated, in a single
     882              : !>        LibXC call per block of grid points
     883              : !> \param libxc_params input parameter (functional name, scaling and parameters)
     884              : !> \param func_name_override optional LibXC functional name overriding the section name
     885              : !> \author F. Tran
     886              : ! **************************************************************************************************
     887        20312 :    SUBROUTINE libxc_spin_unpolarized_eval(rho_set, deriv_set, grad_deriv, libxc_params, func_name_override)
     888              : 
     889              :       TYPE(xc_rho_set_type), INTENT(IN)        :: rho_set
     890              :       TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
     891              :       INTEGER, INTENT(in)                      :: grad_deriv
     892              :       TYPE(section_vals_type), POINTER         :: libxc_params
     893              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL   :: func_name_override
     894              : 
     895              : #if defined (__LIBXC)
     896              :       CHARACTER(len=*), PARAMETER :: routineN = 'libxc_spin_unpolarized_eval'
     897              : 
     898              :       CHARACTER(LEN=default_string_length)     :: func_name
     899              :       INTEGER                                  :: handle, iw, npoints
     900              :       INTEGER, DIMENSION(2, 3)                 :: bo
     901              :       LOGICAL                                  :: has_laplace
     902              :       REAL(KIND=dp)                            :: epsilon_rho, epsilon_tau, func_scale
     903              :       TYPE(libxc_worker_set_type), POINTER     :: workers
     904              :       TYPE(section_vals_type), POINTER         :: no_params
     905        20312 :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: dummy, e_0, e_laplace_rho, &
     906        20312 :                                                                 e_laplace_rho_laplace_rho, e_laplace_rho_tau, e_ndrho, &
     907        20312 :                                                               e_ndrho_laplace_rho, e_ndrho_ndrho, e_ndrho_rho, e_ndrho_tau, e_rho, &
     908        20312 :                                                                 e_rho_laplace_rho, e_rho_rho, e_rho_rho_rho, e_rho_tau, e_tau, &
     909        20312 :                                                                 e_tau_tau, laplace_rho, norm_drho, rho, tau
     910              :       ! derivatives w.r.t. the reduced gradient gamma = |grad rho|^2
     911              :       #:for descs, arr, idx in umgga_all
     912        20312 :          REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: e_${'_'.join(descs)}$
     913              :       #:endfor
     914              :       TYPE(xc_derivative_type), POINTER        :: deriv
     915              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     916              : 
     917        20312 :       CALL timeset(routineN, handle)
     918              : 
     919              :       ! Only "everything up to grad_deriv" is supported. Asking for a single
     920              :       ! derivative order in isolation is rejected here rather than further down,
     921              :       ! where it would quietly evaluate nothing at all.
     922        20312 :       IF (grad_deriv > 3) THEN
     923            0 :          CPABORT("derivatives larger than 3 not implemented")
     924              :       END IF
     925              : 
     926        20312 :       has_laplace = .FALSE.
     927        20312 :       NULLIFY (dummy)
     928        20312 :       NULLIFY (workers)
     929        20312 :       NULLIFY (rho, norm_drho, laplace_rho, tau)
     930              : 
     931        20312 :       IF (PRESENT(func_name_override)) THEN
     932          604 :          func_name = func_name_override
     933          604 :          func_scale = 1.0_dp
     934              :       ELSE
     935        19708 :          func_name = libxc_params%section%name
     936        19708 :          CALL section_vals_val_get(libxc_params, "scale", r_val=func_scale)
     937              :       END IF
     938              : 
     939        20312 :       IF (ABS(func_scale - 1.0_dp) < 1.0e-10_dp) func_scale = 1.0_dp
     940              : 
     941              :       CALL xc_rho_set_get(rho_set, can_return_null=.TRUE., &
     942              :                           rho=rho, norm_drho=norm_drho, laplace_rho=laplace_rho, &
     943              :                           rho_cutoff=epsilon_rho, tau_cutoff=epsilon_tau, &
     944        20312 :                           tau=tau, local_bounds=bo)
     945              : 
     946        20312 :       npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
     947              : 
     948              :       ! One functional object per thread, kept across calls. The cutoffs are part
     949              :       ! of the worker setup because LibXC does the screening itself.
     950        20312 :       IF (PRESENT(func_name_override)) THEN
     951              :          ! an overriding name carries no input section, so no parameters are set
     952          604 :          NULLIFY (no_params)
     953              :          iw = libxc_get_workers(func_name, XC_UNPOLARIZED, no_params, epsilon_rho, epsilon_tau, &
     954          604 :                                 grad_deriv)
     955              :       ELSE
     956              :          iw = libxc_get_workers(func_name, XC_UNPOLARIZED, libxc_params, epsilon_rho, epsilon_tau, &
     957        19708 :                                 grad_deriv)
     958              :       END IF
     959        20312 :       workers => libxc_cache(iw)
     960        20312 :       xc_info = workers%worker(1)%info
     961        20312 :       has_laplace = workers%has_laplace
     962              : 
     963              :       ! see libxc_unused: the arguments the requested order does not produce are
     964              :       ! never touched, but they still have to point somewhere
     965        20312 :       CALL libxc_reserve_unused(npoints)
     966        20312 :       dummy(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)) => libxc_unused(1:npoints)
     967              : 
     968              :       ! due to assumed shape array usage in next routine
     969        20312 :       IF (.NOT. ASSOCIATED(norm_drho)) norm_drho => rho
     970        20312 :       IF (.NOT. ASSOCIATED(tau)) tau => rho
     971              : 
     972              :       ! only some MGGA functionals really need the Laplacian,
     973              :       ! all others can work with rho (read-only) as dummy
     974        20312 :       IF (.NOT. has_laplace) laplace_rho => rho
     975              : 
     976        20312 :       e_0 => dummy
     977        20312 :       e_rho => dummy
     978        20312 :       e_ndrho => dummy
     979        20312 :       e_laplace_rho => dummy
     980        20312 :       e_tau => dummy
     981        20312 :       e_rho_rho => dummy
     982        20312 :       e_ndrho_rho => dummy
     983        20312 :       e_ndrho_ndrho => dummy
     984        20312 :       e_rho_laplace_rho => dummy
     985        20312 :       e_rho_tau => dummy
     986        20312 :       e_ndrho_laplace_rho => dummy
     987        20312 :       e_ndrho_tau => dummy
     988        20312 :       e_laplace_rho_laplace_rho => dummy
     989        20312 :       e_laplace_rho_tau => dummy
     990        20312 :       e_tau_tau => dummy
     991        20312 :       e_rho_rho_rho => dummy
     992              :       #:for descs, arr, idx in umgga_all
     993        20312 :          e_${'_'.join(descs)}$ => dummy
     994              :       #:endfor
     995              : 
     996              :       deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
     997        20312 :                                       allocate_deriv=.TRUE.)
     998        20312 :       CALL xc_derivative_get(deriv, deriv_data=e_0)
     999        20312 :       IF (grad_deriv >= 1) THEN
    1000        10088 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1001              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1002              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho], &
    1003        10088 :                                             allocate_deriv=.TRUE.)
    1004        10088 :             CALL xc_derivative_get(deriv, deriv_data=e_rho)
    1005              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1006              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho], &
    1007         7136 :                                             allocate_deriv=.TRUE.)
    1008         7136 :             CALL xc_derivative_get(deriv, deriv_data=e_rho)
    1009              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
    1010         7136 :                                             allocate_deriv=.TRUE.)
    1011         7136 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
    1012              :             #:for descs, arr, idx in ugga_fill_1
    1013              :                deriv => xc_dset_get_derivative(deriv_set, &
    1014              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1015         7136 :                                                allocate_deriv=.TRUE.)
    1016         7136 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1017              :             #:endfor
    1018              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1019              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho], &
    1020         2834 :                                             allocate_deriv=.TRUE.)
    1021         2834 :             CALL xc_derivative_get(deriv, deriv_data=e_rho)
    1022              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
    1023         2834 :                                             allocate_deriv=.TRUE.)
    1024         2834 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
    1025              :             #:for descs, arr, idx in ugga_fill_1
    1026              :                deriv => xc_dset_get_derivative(deriv_set, &
    1027              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1028         2834 :                                                allocate_deriv=.TRUE.)
    1029         2834 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1030              :             #:endfor
    1031              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau], &
    1032         2834 :                                             allocate_deriv=.TRUE.)
    1033         2834 :             CALL xc_derivative_get(deriv, deriv_data=e_tau)
    1034         2834 :             IF (has_laplace) THEN
    1035              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho], &
    1036          614 :                                                allocate_deriv=.TRUE.)
    1037          614 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rho)
    1038              :             END IF
    1039              :          CASE default
    1040        20058 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1041              :          END SELECT
    1042              :       END IF
    1043        20312 :       IF (grad_deriv >= 2) THEN
    1044         1574 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1045              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1046              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho], &
    1047         1574 :                                             allocate_deriv=.TRUE.)
    1048         1574 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho)
    1049              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1050              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho], &
    1051          696 :                                             allocate_deriv=.TRUE.)
    1052          696 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho)
    1053              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rho], &
    1054          696 :                                             allocate_deriv=.TRUE.)
    1055          696 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rho)
    1056              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho], &
    1057          696 :                                             allocate_deriv=.TRUE.)
    1058          696 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
    1059              :             #:for descs, arr, idx in ugga_fill_2
    1060              :                deriv => xc_dset_get_derivative(deriv_set, &
    1061              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1062         1392 :                                                allocate_deriv=.TRUE.)
    1063         1392 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1064              :             #:endfor
    1065              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1066              :             ! not implemented ...
    1067              : 
    1068              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho], &
    1069          700 :                                             allocate_deriv=.TRUE.)
    1070          700 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho)
    1071              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rho], &
    1072          700 :                                             allocate_deriv=.TRUE.)
    1073          700 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rho)
    1074              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho], &
    1075          700 :                                             allocate_deriv=.TRUE.)
    1076          700 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
    1077              :             #:for descs, arr, idx in ugga_fill_2
    1078              :                deriv => xc_dset_get_derivative(deriv_set, &
    1079              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1080         1400 :                                                allocate_deriv=.TRUE.)
    1081         1400 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1082              :             #:endfor
    1083              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_tau], &
    1084          700 :                                             allocate_deriv=.TRUE.)
    1085          700 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_tau)
    1086              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau], &
    1087          700 :                                             allocate_deriv=.TRUE.)
    1088          700 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_tau)
    1089              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_tau], &
    1090          700 :                                             allocate_deriv=.TRUE.)
    1091          700 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_tau)
    1092              :             #:for descs, arr, idx in umgga_extra_2_nl
    1093              :                deriv => xc_dset_get_derivative(deriv_set, &
    1094              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1095          700 :                                                allocate_deriv=.TRUE.)
    1096          700 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1097              :             #:endfor
    1098          700 :             IF (has_laplace) THEN
    1099              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_laplace_rho], &
    1100           82 :                                                allocate_deriv=.TRUE.)
    1101           82 :                CALL xc_derivative_get(deriv, deriv_data=e_rho_laplace_rho)
    1102              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_laplace_rho], &
    1103           82 :                                                allocate_deriv=.TRUE.)
    1104           82 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrho_laplace_rho)
    1105              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_laplace_rho], &
    1106           82 :                                                allocate_deriv=.TRUE.)
    1107           82 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rho_laplace_rho)
    1108              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_tau], &
    1109           82 :                                                allocate_deriv=.TRUE.)
    1110           82 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rho_tau)
    1111              :             END IF
    1112              :          CASE default
    1113         2970 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1114              :          END SELECT
    1115              :       END IF
    1116        20312 :       IF (grad_deriv >= 3) THEN
    1117            8 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1118              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1119            8 :             IF (has_laplace) THEN
    1120              :                #:for descs, arr, idx in umgga_fill_3_l
    1121              :                   deriv => xc_dset_get_derivative(deriv_set, &
    1122              :                                                   [${', '.join('deriv_' + d for d in descs)}$], &
    1123            0 :                                                   allocate_deriv=.TRUE.)
    1124            0 :                   CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1125              :                #:endfor
    1126              :             END IF
    1127              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho, deriv_rho], &
    1128            8 :                                             allocate_deriv=.TRUE.)
    1129            8 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho_rho)
    1130              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1131            8 :             IF (has_laplace) THEN
    1132              :                #:for descs, arr, idx in umgga_fill_3_l
    1133              :                   deriv => xc_dset_get_derivative(deriv_set, &
    1134              :                                                   [${', '.join('deriv_' + d for d in descs)}$], &
    1135            0 :                                                   allocate_deriv=.TRUE.)
    1136            0 :                   CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1137              :                #:endfor
    1138              :             END IF
    1139              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho, deriv_rho], &
    1140            8 :                                             allocate_deriv=.TRUE.)
    1141            8 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho_rho)
    1142              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho, deriv_gamma], &
    1143            8 :                                             allocate_deriv=.TRUE.)
    1144            8 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho_gamma)
    1145              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_gamma, deriv_gamma], &
    1146            8 :                                             allocate_deriv=.TRUE.)
    1147            8 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_gamma_gamma)
    1148              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_gamma, deriv_gamma, deriv_gamma], &
    1149            8 :                                             allocate_deriv=.TRUE.)
    1150            8 :             CALL xc_derivative_get(deriv, deriv_data=e_gamma_gamma_gamma)
    1151              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1152              :             #:for descs, arr, idx in umgga_fill_3_nl
    1153              :                deriv => xc_dset_get_derivative(deriv_set, &
    1154              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1155          180 :                                                allocate_deriv=.TRUE.)
    1156          180 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1157              :             #:endfor
    1158           20 :             IF (has_laplace) THEN
    1159              :                #:for descs, arr, idx in umgga_fill_3_l
    1160              :                   deriv => xc_dset_get_derivative(deriv_set, &
    1161              :                                                   [${', '.join('deriv_' + d for d in descs)}$], &
    1162           40 :                                                   allocate_deriv=.TRUE.)
    1163           40 :                   CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1164              :                #:endfor
    1165              :             END IF
    1166              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho, deriv_rho], &
    1167           20 :                                             allocate_deriv=.TRUE.)
    1168           20 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho_rho)
    1169              :          CASE default
    1170           36 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1171              :          END SELECT
    1172              :       END IF
    1173              : 
    1174              : !$OMP PARALLEL DEFAULT(NONE), &
    1175              : !$OMP SHARED(rho,norm_drho,laplace_rho,tau,e_0,e_rho,e_ndrho,e_laplace_rho),&
    1176              : !$OMP SHARED(e_tau,e_rho_rho,e_ndrho_rho,e_ndrho_ndrho,e_rho_laplace_rho),&
    1177              : !$OMP SHARED(e_rho_tau,e_ndrho_laplace_rho,e_ndrho_tau,e_laplace_rho_laplace_rho),&
    1178              : !$OMP SHARED(e_laplace_rho_tau,e_tau_tau,e_rho_rho_rho),&
    1179              :       #:for descs, arr, idx in umgga_all
    1180              : !$OMP SHARED(e_${'_'.join(descs)}$),&
    1181              :       #:endfor
    1182              : !$OMP SHARED(grad_deriv,npoints),&
    1183        20312 : !$OMP SHARED(func_name,func_scale,workers)
    1184              : 
    1185              :       CALL libxc_spin_unpolarized_calc(rho=rho, norm_drho=norm_drho, &
    1186              :                                        laplace_rho=laplace_rho, tau=tau, &
    1187              :                                        e_0=e_0, e_rho=e_rho, e_ndrho=e_ndrho, e_laplace_rho=e_laplace_rho, &
    1188              :                                        e_tau=e_tau, e_rho_rho=e_rho_rho, e_ndrho_rho=e_ndrho_rho, &
    1189              :                                        e_ndrho_ndrho=e_ndrho_ndrho, e_rho_laplace_rho=e_rho_laplace_rho, &
    1190              :                                        e_rho_tau=e_rho_tau, e_ndrho_laplace_rho=e_ndrho_laplace_rho, &
    1191              :                                        e_ndrho_tau=e_ndrho_tau, e_laplace_rho_laplace_rho=e_laplace_rho_laplace_rho, &
    1192              :                                        e_laplace_rho_tau=e_laplace_rho_tau, e_tau_tau=e_tau_tau, &
    1193              :                                        e_rho_rho_rho=e_rho_rho_rho, &
    1194              :                                        #:for descs, arr, idx in umgga_all
    1195              :                                        e_${'_'.join(descs)}$=e_${'_'.join(descs)}$, &
    1196              :                                        #:endfor
    1197              :                                        grad_deriv=grad_deriv, npoints=npoints, &
    1198              :                                        func_name=func_name, sc=func_scale, workers=workers)
    1199              : 
    1200              : !$OMP END PARALLEL
    1201              : 
    1202        20312 :       NULLIFY (dummy)
    1203        20312 :       NULLIFY (workers)
    1204              : 
    1205        20312 :       CALL timestop(handle)
    1206              : #else
    1207              :       MARK_USED(rho_set)
    1208              :       MARK_USED(deriv_set)
    1209              :       MARK_USED(grad_deriv)
    1210              :       MARK_USED(libxc_params)
    1211              :       MARK_USED(func_name_override)
    1212              :       CALL cp_abort(__LOCATION__, "Unknown functional! If you are asking "// &
    1213              :                     "for a functional of the LibXC library, "// &
    1214              :                     "you have to download and install the library!")
    1215              : #endif
    1216        20312 :    END SUBROUTINE libxc_spin_unpolarized_eval
    1217              : 
    1218              : ! **************************************************************************************************
    1219              : !> \brief evaluates the functional from libxc
    1220              : !> \param rho_set the density where you want to evaluate the functional
    1221              : !> \param deriv_set place where to store the functional derivatives (they are
    1222              : !>        added to the derivatives)
    1223              : !> \param grad_deriv degree of the derivative that should be evaluated;
    1224              : !>        all derivatives up to the given degree are evaluated, in a single
    1225              : !>        LibXC call per block of grid points
    1226              : !> \param libxc_params input parameter (functional name, scaling and parameters)
    1227              : !> \param func_name_override optional LibXC functional name overriding the section name
    1228              : !> \author F. Tran
    1229              : ! **************************************************************************************************
    1230         6872 :    SUBROUTINE libxc_spin_polarized_eval(rho_set, deriv_set, grad_deriv, libxc_params, func_name_override)
    1231              : 
    1232              :       TYPE(xc_rho_set_type), INTENT(IN)        :: rho_set
    1233              :       TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
    1234              :       INTEGER, INTENT(in)                      :: grad_deriv
    1235              :       TYPE(section_vals_type), POINTER         :: libxc_params
    1236              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL   :: func_name_override
    1237              : 
    1238              : #if defined (__LIBXC)
    1239              :       CHARACTER(len=*), PARAMETER :: routineN = 'libxc_spin_polarized_eval'
    1240              : 
    1241              :       CHARACTER(LEN=default_string_length)     :: func_name
    1242              :       INTEGER                                  :: handle, iw, npoints
    1243              :       INTEGER, DIMENSION(2, 3)                 :: bo
    1244              :       LOGICAL                                  :: has_laplace
    1245              :       REAL(KIND=dp)                            :: epsilon_rho, epsilon_tau, func_scale
    1246              :       TYPE(libxc_worker_set_type), POINTER     :: workers
    1247              :       TYPE(section_vals_type), POINTER         :: no_params
    1248         6872 :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: dummy, e_0, e_laplace_rhoa, &
    1249         6872 :                                                                 e_laplace_rhoa_laplace_rhoa, e_laplace_rhoa_laplace_rhob, &
    1250         6872 :                                                                 e_laplace_rhoa_tau_a, e_laplace_rhoa_tau_b, e_laplace_rhob, &
    1251         6872 :                                                                 e_laplace_rhob_laplace_rhob, e_laplace_rhob_tau_a, &
    1252         6872 :                                                                 e_laplace_rhob_tau_b, e_ndrho, e_ndrho_laplace_rhoa, &
    1253         6872 :                                                               e_ndrho_laplace_rhob, e_ndrho_ndrho, e_ndrho_ndrhoa, e_ndrho_ndrhob, &
    1254         6872 :                                                                e_ndrho_rhoa, e_ndrho_rhob, e_ndrho_tau_a, e_ndrho_tau_b, e_ndrhoa, &
    1255         6872 :                                                                 e_ndrhoa_laplace_rhoa, e_ndrhoa_laplace_rhob, e_ndrhoa_ndrhoa, &
    1256         6872 :                                                                 e_ndrhoa_ndrhob, e_ndrhoa_rhoa, e_ndrhoa_rhob, e_ndrhoa_tau_a, &
    1257         6872 :                                                                 e_ndrhoa_tau_b, e_ndrhob
    1258         6872 :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: e_ndrhob_laplace_rhoa, &
    1259         6872 :                                                              e_ndrhob_laplace_rhob, e_ndrhob_ndrhob, e_ndrhob_rhoa, e_ndrhob_rhob, &
    1260         6872 :                                                                 e_ndrhob_tau_a, e_ndrhob_tau_b, e_rhoa, e_rhoa_laplace_rhoa, &
    1261         6872 :                                                              e_rhoa_laplace_rhob, e_rhoa_rhoa, e_rhoa_rhoa_rhoa, e_rhoa_rhoa_rhob, &
    1262         6872 :                                                                 e_rhoa_rhob, e_rhoa_rhob_rhob, e_rhoa_tau_a, e_rhoa_tau_b, e_rhob, &
    1263         6872 :                                                                 e_rhob_laplace_rhoa, e_rhob_laplace_rhob, e_rhob_rhob, &
    1264         6872 :                                                              e_rhob_rhob_rhob, e_rhob_tau_a, e_rhob_tau_b, e_tau_a, e_tau_a_tau_a, &
    1265         6872 :                                                                 e_tau_a_tau_b, e_tau_b, e_tau_b_tau_b, laplace_rhoa, laplace_rhob, &
    1266         6872 :                                                                 norm_drho, norm_drhoa, norm_drhob, rhoa, rhob, tau_a, tau_b
    1267              :       ! derivatives w.r.t. the reduced gradients gamma_ij = grad rho_i . grad rho_j
    1268              :       #:for descs, arr, idx in mgga_all
    1269         6872 :          REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: e_${'_'.join(descs)}$
    1270              :       #:endfor
    1271              :       TYPE(xc_derivative_type), POINTER        :: deriv
    1272              :       TYPE(xc_f03_func_info_t)                 :: xc_info
    1273              : 
    1274         6872 :       CALL timeset(routineN, handle)
    1275              : 
    1276              :       ! Only "everything up to grad_deriv" is supported. Asking for a single
    1277              :       ! derivative order in isolation is rejected here rather than further down,
    1278              :       ! where it would quietly evaluate nothing at all.
    1279         6872 :       IF (grad_deriv > 3) THEN
    1280            0 :          CPABORT("derivatives larger than 3 not implemented")
    1281              :       END IF
    1282              : 
    1283         6872 :       NULLIFY (dummy)
    1284         6872 :       NULLIFY (workers)
    1285         6872 :       NULLIFY (rhoa, rhob, norm_drho, norm_drhoa, norm_drhob, laplace_rhoa, &
    1286         6872 :                laplace_rhob, tau_a, tau_b)
    1287              : 
    1288         6872 :       IF (PRESENT(func_name_override)) THEN
    1289         2968 :          func_name = func_name_override
    1290         2968 :          func_scale = 1.0_dp
    1291              :       ELSE
    1292         3904 :          func_name = libxc_params%section%name
    1293         3904 :          CALL section_vals_val_get(libxc_params, "scale", r_val=func_scale)
    1294              :       END IF
    1295              : 
    1296         6872 :       IF (ABS(func_scale - 1.0_dp) < 1.0e-10_dp) func_scale = 1.0_dp
    1297              : 
    1298              :       CALL xc_rho_set_get(rho_set, can_return_null=.TRUE., &
    1299              :                           rhoa=rhoa, rhob=rhob, norm_drho=norm_drho, &
    1300              :                           norm_drhoa=norm_drhoa, norm_drhob=norm_drhob, &
    1301              :                           laplace_rhoa=laplace_rhoa, laplace_rhob=laplace_rhob, &
    1302              :                           rho_cutoff=epsilon_rho, tau_cutoff=epsilon_tau, &
    1303         6872 :                           tau_a=tau_a, tau_b=tau_b, local_bounds=bo)
    1304              : 
    1305         6872 :       npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
    1306              : 
    1307              :       ! One functional object per thread, kept across calls. The cutoffs are part
    1308              :       ! of the worker setup because LibXC does the screening itself.
    1309         6872 :       IF (PRESENT(func_name_override)) THEN
    1310              :          ! an overriding name carries no input section, so no parameters are set
    1311         2968 :          NULLIFY (no_params)
    1312              :          iw = libxc_get_workers(func_name, XC_POLARIZED, no_params, epsilon_rho, epsilon_tau, &
    1313         2968 :                                 grad_deriv)
    1314              :       ELSE
    1315              :          iw = libxc_get_workers(func_name, XC_POLARIZED, libxc_params, epsilon_rho, epsilon_tau, &
    1316         3904 :                                 grad_deriv)
    1317              :       END IF
    1318         6872 :       workers => libxc_cache(iw)
    1319         6872 :       xc_info = workers%worker(1)%info
    1320         6872 :       has_laplace = workers%has_laplace
    1321              : 
    1322              :       ! see libxc_unused: the arguments the requested order does not produce are
    1323              :       ! never touched, but they still have to point somewhere
    1324         6872 :       CALL libxc_reserve_unused(npoints)
    1325         6872 :       dummy(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)) => libxc_unused(1:npoints)
    1326              : 
    1327              :       ! due to assumed shape array usage in next routine
    1328         6872 :       IF (.NOT. ASSOCIATED(norm_drho)) norm_drho => rhoa
    1329         6872 :       IF (.NOT. ASSOCIATED(norm_drhoa)) norm_drhoa => rhoa
    1330         6872 :       IF (.NOT. ASSOCIATED(norm_drhob)) norm_drhob => rhoa
    1331         6872 :       IF (.NOT. ASSOCIATED(tau_a)) tau_a => rhoa
    1332         6872 :       IF (.NOT. ASSOCIATED(tau_b)) tau_b => rhoa
    1333              : 
    1334              :       ! only some MGGA functionals really need the Laplacian,
    1335              :       ! all others can work with rhoa (read-only) as dummy
    1336         6872 :       IF (.NOT. has_laplace) laplace_rhoa => rhoa
    1337         6584 :       IF (.NOT. has_laplace) laplace_rhob => rhoa
    1338              : 
    1339         6872 :       e_0 => dummy
    1340         6872 :       e_rhoa => dummy
    1341         6872 :       e_rhob => dummy
    1342         6872 :       e_ndrho => dummy
    1343         6872 :       e_ndrhoa => dummy
    1344         6872 :       e_ndrhob => dummy
    1345         6872 :       e_laplace_rhoa => dummy
    1346         6872 :       e_laplace_rhob => dummy
    1347         6872 :       e_tau_a => dummy
    1348         6872 :       e_tau_b => dummy
    1349         6872 :       e_rhoa_rhoa => dummy
    1350         6872 :       e_rhoa_rhob => dummy
    1351         6872 :       e_rhob_rhob => dummy
    1352         6872 :       e_ndrho_rhoa => dummy
    1353         6872 :       e_ndrho_rhob => dummy
    1354         6872 :       e_ndrhoa_rhoa => dummy
    1355         6872 :       e_ndrhoa_rhob => dummy
    1356         6872 :       e_ndrhob_rhoa => dummy
    1357         6872 :       e_ndrhob_rhob => dummy
    1358         6872 :       e_ndrho_ndrho => dummy
    1359         6872 :       e_ndrho_ndrhoa => dummy
    1360         6872 :       e_ndrho_ndrhob => dummy
    1361         6872 :       e_ndrhoa_ndrhoa => dummy
    1362         6872 :       e_ndrhoa_ndrhob => dummy
    1363         6872 :       e_ndrhob_ndrhob => dummy
    1364         6872 :       e_rhoa_laplace_rhoa => dummy
    1365         6872 :       e_rhoa_laplace_rhob => dummy
    1366         6872 :       e_rhob_laplace_rhoa => dummy
    1367         6872 :       e_rhob_laplace_rhob => dummy
    1368         6872 :       e_rhoa_tau_a => dummy
    1369         6872 :       e_rhoa_tau_b => dummy
    1370         6872 :       e_rhob_tau_a => dummy
    1371         6872 :       e_rhob_tau_b => dummy
    1372         6872 :       e_ndrho_laplace_rhoa => dummy
    1373         6872 :       e_ndrho_laplace_rhob => dummy
    1374         6872 :       e_ndrhoa_laplace_rhoa => dummy
    1375         6872 :       e_ndrhoa_laplace_rhob => dummy
    1376         6872 :       e_ndrhob_laplace_rhoa => dummy
    1377         6872 :       e_ndrhob_laplace_rhob => dummy
    1378         6872 :       e_ndrho_tau_a => dummy
    1379         6872 :       e_ndrho_tau_b => dummy
    1380         6872 :       e_ndrhoa_tau_a => dummy
    1381         6872 :       e_ndrhoa_tau_b => dummy
    1382         6872 :       e_ndrhob_tau_a => dummy
    1383         6872 :       e_ndrhob_tau_b => dummy
    1384         6872 :       e_laplace_rhoa_laplace_rhoa => dummy
    1385         6872 :       e_laplace_rhoa_laplace_rhob => dummy
    1386         6872 :       e_laplace_rhob_laplace_rhob => dummy
    1387         6872 :       e_laplace_rhoa_tau_a => dummy
    1388         6872 :       e_laplace_rhoa_tau_b => dummy
    1389         6872 :       e_laplace_rhob_tau_a => dummy
    1390         6872 :       e_laplace_rhob_tau_b => dummy
    1391         6872 :       e_tau_a_tau_a => dummy
    1392         6872 :       e_tau_a_tau_b => dummy
    1393         6872 :       e_tau_b_tau_b => dummy
    1394         6872 :       e_rhoa_rhoa_rhoa => dummy
    1395         6872 :       e_rhoa_rhoa_rhob => dummy
    1396         6872 :       e_rhoa_rhob_rhob => dummy
    1397         6872 :       e_rhob_rhob_rhob => dummy
    1398              :       #:for descs, arr, idx in mgga_all
    1399         6872 :          e_${'_'.join(descs)}$ => dummy
    1400              :       #:endfor
    1401              : 
    1402              :       deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
    1403         6872 :                                       allocate_deriv=.TRUE.)
    1404         6872 :       CALL xc_derivative_get(deriv, deriv_data=e_0)
    1405         6872 :       IF (grad_deriv >= 1) THEN
    1406         1634 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1407              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1408              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa], &
    1409         1634 :                                             allocate_deriv=.TRUE.)
    1410         1634 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa)
    1411              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob], &
    1412         1634 :                                             allocate_deriv=.TRUE.)
    1413         1634 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob)
    1414              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1415              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa], &
    1416          994 :                                             allocate_deriv=.TRUE.)
    1417          994 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa)
    1418              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob], &
    1419          994 :                                             allocate_deriv=.TRUE.)
    1420          994 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob)
    1421              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
    1422          994 :                                             allocate_deriv=.TRUE.)
    1423          994 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
    1424              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa], &
    1425          994 :                                             allocate_deriv=.TRUE.)
    1426          994 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa)
    1427              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob], &
    1428          994 :                                             allocate_deriv=.TRUE.)
    1429          994 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob)
    1430              :             #:for descs, arr, idx in gamma_only_1
    1431              :                deriv => xc_dset_get_derivative(deriv_set, &
    1432              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1433         2982 :                                                allocate_deriv=.TRUE.)
    1434         2982 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1435              :             #:endfor
    1436              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1437              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa], &
    1438         4102 :                                             allocate_deriv=.TRUE.)
    1439         4102 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa)
    1440              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob], &
    1441         4102 :                                             allocate_deriv=.TRUE.)
    1442         4102 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob)
    1443              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
    1444         4102 :                                             allocate_deriv=.TRUE.)
    1445         4102 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
    1446              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa], &
    1447         4102 :                                             allocate_deriv=.TRUE.)
    1448         4102 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa)
    1449              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob], &
    1450         4102 :                                             allocate_deriv=.TRUE.)
    1451         4102 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob)
    1452              :             #:for descs, arr, idx in gamma_only_1
    1453              :                deriv => xc_dset_get_derivative(deriv_set, &
    1454              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1455        12306 :                                                allocate_deriv=.TRUE.)
    1456        12306 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1457              :             #:endfor
    1458              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_a], &
    1459         4102 :                                             allocate_deriv=.TRUE.)
    1460         4102 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_a)
    1461              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_b], &
    1462         4102 :                                             allocate_deriv=.TRUE.)
    1463         4102 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_b)
    1464         4102 :             IF (has_laplace) THEN
    1465              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa], &
    1466          280 :                                                allocate_deriv=.TRUE.)
    1467          280 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa)
    1468              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob], &
    1469          280 :                                                allocate_deriv=.TRUE.)
    1470          280 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhob)
    1471              :             END IF
    1472              :          CASE default
    1473         6730 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1474              :          END SELECT
    1475              :       END IF
    1476         6872 :       IF (grad_deriv >= 2) THEN
    1477          454 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1478              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1479              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa], &
    1480          454 :                                             allocate_deriv=.TRUE.)
    1481          454 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa)
    1482              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob], &
    1483          454 :                                             allocate_deriv=.TRUE.)
    1484          454 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhob)
    1485              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob], &
    1486          454 :                                             allocate_deriv=.TRUE.)
    1487          454 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_rhob)
    1488              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1489              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa], &
    1490          450 :                                             allocate_deriv=.TRUE.)
    1491          450 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa)
    1492              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob], &
    1493          450 :                                             allocate_deriv=.TRUE.)
    1494          450 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhob)
    1495              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob], &
    1496          450 :                                             allocate_deriv=.TRUE.)
    1497          450 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_rhob)
    1498              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa], &
    1499          450 :                                             allocate_deriv=.TRUE.)
    1500          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rhoa)
    1501              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob], &
    1502          450 :                                             allocate_deriv=.TRUE.)
    1503          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rhob)
    1504              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa], &
    1505          450 :                                             allocate_deriv=.TRUE.)
    1506          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_rhoa)
    1507              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob], &
    1508          450 :                                             allocate_deriv=.TRUE.)
    1509          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_rhob)
    1510              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhoa], &
    1511          450 :                                             allocate_deriv=.TRUE.)
    1512          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_rhoa)
    1513              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhob], &
    1514          450 :                                             allocate_deriv=.TRUE.)
    1515          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_rhob)
    1516              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho], &
    1517          450 :                                             allocate_deriv=.TRUE.)
    1518          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
    1519              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa], &
    1520          450 :                                             allocate_deriv=.TRUE.)
    1521          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrhoa)
    1522              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob], &
    1523          450 :                                             allocate_deriv=.TRUE.)
    1524          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrhob)
    1525              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa], &
    1526          450 :                                             allocate_deriv=.TRUE.)
    1527          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_ndrhoa)
    1528              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob], &
    1529          450 :                                             allocate_deriv=.TRUE.)
    1530          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_ndrhob)
    1531              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhob], &
    1532          450 :                                             allocate_deriv=.TRUE.)
    1533          450 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_ndrhob)
    1534              :             #:for descs, arr, idx in gamma_only_2
    1535              :                deriv => xc_dset_get_derivative(deriv_set, &
    1536              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1537         5400 :                                                allocate_deriv=.TRUE.)
    1538         5400 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1539              :             #:endfor
    1540              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1541              : 
    1542              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa], &
    1543         2260 :                                             allocate_deriv=.TRUE.)
    1544         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa)
    1545              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob], &
    1546         2260 :                                             allocate_deriv=.TRUE.)
    1547         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhob)
    1548              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob], &
    1549         2260 :                                             allocate_deriv=.TRUE.)
    1550         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_rhob)
    1551              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa], &
    1552         2260 :                                             allocate_deriv=.TRUE.)
    1553         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rhoa)
    1554              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob], &
    1555         2260 :                                             allocate_deriv=.TRUE.)
    1556         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rhob)
    1557              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa], &
    1558         2260 :                                             allocate_deriv=.TRUE.)
    1559         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_rhoa)
    1560              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob], &
    1561         2260 :                                             allocate_deriv=.TRUE.)
    1562         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_rhob)
    1563              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhoa], &
    1564         2260 :                                             allocate_deriv=.TRUE.)
    1565         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_rhoa)
    1566              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhob], &
    1567         2260 :                                             allocate_deriv=.TRUE.)
    1568         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_rhob)
    1569              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho], &
    1570         2260 :                                             allocate_deriv=.TRUE.)
    1571         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
    1572              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa], &
    1573         2260 :                                             allocate_deriv=.TRUE.)
    1574         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrhoa)
    1575              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob], &
    1576         2260 :                                             allocate_deriv=.TRUE.)
    1577         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrhob)
    1578              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa], &
    1579         2260 :                                             allocate_deriv=.TRUE.)
    1580         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_ndrhoa)
    1581              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob], &
    1582         2260 :                                             allocate_deriv=.TRUE.)
    1583         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_ndrhob)
    1584              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhob], &
    1585         2260 :                                             allocate_deriv=.TRUE.)
    1586         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_ndrhob)
    1587              :             #:for descs, arr, idx in mgga_fill_2_nl
    1588              :                deriv => xc_dset_get_derivative(deriv_set, &
    1589              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1590        40680 :                                                allocate_deriv=.TRUE.)
    1591        40680 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1592              :             #:endfor
    1593         2260 :             IF (has_laplace) THEN
    1594              :                #:for descs, arr, idx in mgga_fill_2_l
    1595              :                   deriv => xc_dset_get_derivative(deriv_set, &
    1596              :                                                   [${', '.join('deriv_' + d for d in descs)}$], &
    1597           96 :                                                   allocate_deriv=.TRUE.)
    1598           96 :                   CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1599              :                #:endfor
    1600              :             END IF
    1601              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_a], &
    1602         2260 :                                             allocate_deriv=.TRUE.)
    1603         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_tau_a)
    1604              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_b], &
    1605         2260 :                                             allocate_deriv=.TRUE.)
    1606         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_tau_b)
    1607              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_tau_a], &
    1608         2260 :                                             allocate_deriv=.TRUE.)
    1609         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_tau_a)
    1610              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_tau_b], &
    1611         2260 :                                             allocate_deriv=.TRUE.)
    1612         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_tau_b)
    1613              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_a], &
    1614         2260 :                                             allocate_deriv=.TRUE.)
    1615         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_tau_a)
    1616              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_b], &
    1617         2260 :                                             allocate_deriv=.TRUE.)
    1618         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_tau_b)
    1619              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_a], &
    1620         2260 :                                             allocate_deriv=.TRUE.)
    1621         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_tau_a)
    1622              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_b], &
    1623         2260 :                                             allocate_deriv=.TRUE.)
    1624         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_tau_b)
    1625              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_tau_a], &
    1626         2260 :                                             allocate_deriv=.TRUE.)
    1627         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_tau_a)
    1628              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_tau_b], &
    1629         2260 :                                             allocate_deriv=.TRUE.)
    1630         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_tau_b)
    1631              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_a], &
    1632         2260 :                                             allocate_deriv=.TRUE.)
    1633         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_a_tau_a)
    1634              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_b], &
    1635         2260 :                                             allocate_deriv=.TRUE.)
    1636         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_a_tau_b)
    1637              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_tau_b], &
    1638         2260 :                                             allocate_deriv=.TRUE.)
    1639         2260 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_b_tau_b)
    1640         2260 :             IF (has_laplace) THEN
    1641              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhoa], &
    1642           16 :                                                allocate_deriv=.TRUE.)
    1643           16 :                CALL xc_derivative_get(deriv, deriv_data=e_rhoa_laplace_rhoa)
    1644              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhob], &
    1645           16 :                                                allocate_deriv=.TRUE.)
    1646           16 :                CALL xc_derivative_get(deriv, deriv_data=e_rhoa_laplace_rhob)
    1647              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_laplace_rhoa], &
    1648           16 :                                                allocate_deriv=.TRUE.)
    1649           16 :                CALL xc_derivative_get(deriv, deriv_data=e_rhob_laplace_rhoa)
    1650              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_laplace_rhob], &
    1651           16 :                                                allocate_deriv=.TRUE.)
    1652           16 :                CALL xc_derivative_get(deriv, deriv_data=e_rhob_laplace_rhob)
    1653              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_laplace_rhoa], &
    1654           16 :                                                allocate_deriv=.TRUE.)
    1655           16 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrho_laplace_rhoa)
    1656              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_laplace_rhob], &
    1657           16 :                                                allocate_deriv=.TRUE.)
    1658           16 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrho_laplace_rhob)
    1659              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_laplace_rhoa], &
    1660           16 :                                                allocate_deriv=.TRUE.)
    1661           16 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_laplace_rhoa)
    1662              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_laplace_rhob], &
    1663           16 :                                                allocate_deriv=.TRUE.)
    1664           16 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_laplace_rhob)
    1665              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_laplace_rhoa], &
    1666           16 :                                                allocate_deriv=.TRUE.)
    1667           16 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_laplace_rhoa)
    1668              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_laplace_rhob], &
    1669           16 :                                                allocate_deriv=.TRUE.)
    1670           16 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_laplace_rhob)
    1671              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_laplace_rhoa], &
    1672           16 :                                                allocate_deriv=.TRUE.)
    1673           16 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa_laplace_rhoa)
    1674              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_laplace_rhob], &
    1675           16 :                                                allocate_deriv=.TRUE.)
    1676           16 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa_laplace_rhob)
    1677              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_laplace_rhob], &
    1678           16 :                                                allocate_deriv=.TRUE.)
    1679           16 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhob_laplace_rhob)
    1680              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_a], &
    1681           16 :                                                allocate_deriv=.TRUE.)
    1682           16 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa_tau_a)
    1683              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_b], &
    1684           16 :                                                allocate_deriv=.TRUE.)
    1685           16 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa_tau_b)
    1686              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_tau_a], &
    1687           16 :                                                allocate_deriv=.TRUE.)
    1688           16 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhob_tau_a)
    1689              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_tau_b], &
    1690           16 :                                                allocate_deriv=.TRUE.)
    1691           16 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhob_tau_b)
    1692              :             END IF
    1693              :          CASE default
    1694         3164 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1695              :          END SELECT
    1696              :       END IF
    1697         6872 :       IF (grad_deriv >= 3) THEN
    1698           20 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1699              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1700              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa, deriv_rhoa], &
    1701           20 :                                             allocate_deriv=.TRUE.)
    1702           20 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa_rhoa)
    1703              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa, deriv_rhob], &
    1704           20 :                                             allocate_deriv=.TRUE.)
    1705           20 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa_rhob)
    1706              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob, deriv_rhob], &
    1707           20 :                                             allocate_deriv=.TRUE.)
    1708           20 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhob_rhob)
    1709              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob, deriv_rhob], &
    1710           20 :                                             allocate_deriv=.TRUE.)
    1711           20 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_rhob_rhob)
    1712              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1713              :             #:for descs, arr, idx in gamma_only_3 + rho3_entries
    1714              :                deriv => xc_dset_get_derivative(deriv_set, &
    1715              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1716          700 :                                                allocate_deriv=.TRUE.)
    1717          700 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1718              :             #:endfor
    1719              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1720              :             #:for descs, arr, idx in mgga_fill_3_nl
    1721              :                deriv => xc_dset_get_derivative(deriv_set, &
    1722              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1723         1440 :                                                allocate_deriv=.TRUE.)
    1724         1440 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1725              :             #:endfor
    1726           18 :             IF (has_laplace) THEN
    1727              :                #:for descs, arr, idx in mgga_fill_3_l
    1728              :                   deriv => xc_dset_get_derivative(deriv_set, &
    1729              :                                                   [${', '.join('deriv_' + d for d in descs)}$], &
    1730          162 :                                                   allocate_deriv=.TRUE.)
    1731          162 :                   CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1732              :                #:endfor
    1733              :             END IF
    1734              :             #:for descs, arr, idx in rho3_entries
    1735              :                deriv => xc_dset_get_derivative(deriv_set, &
    1736              :                                                [${', '.join('deriv_' + d for d in descs)}$], &
    1737           72 :                                                allocate_deriv=.TRUE.)
    1738           72 :                CALL xc_derivative_get(deriv, deriv_data=e_${'_'.join(descs)}$)
    1739              :             #:endfor
    1740              :          CASE default
    1741           58 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1742              :          END SELECT
    1743              :       END IF
    1744              : 
    1745              : !$OMP PARALLEL DEFAULT(NONE), &
    1746              : !$OMP SHARED(rhoa,rhob,norm_drho,norm_drhoa,norm_drhob),&
    1747              : !$OMP SHARED(laplace_rhoa,laplace_rhob,tau_a,tau_b),&
    1748              : !$OMP SHARED(e_0,e_rhoa,e_rhob,e_ndrho,e_ndrhoa,e_ndrhob),&
    1749              : !$OMP SHARED(e_laplace_rhoa,e_laplace_rhob,e_tau_a,e_tau_b),&
    1750              : !$OMP SHARED(e_rhoa_rhoa,e_rhoa_rhob,e_rhob_rhob),&
    1751              : !$OMP SHARED(e_ndrho_rhoa,e_ndrho_rhob),&
    1752              : !$OMP SHARED(e_ndrhoa_rhoa,e_ndrhoa_rhob,e_ndrhob_rhoa,e_ndrhob_rhob),&
    1753              : !$OMP SHARED(e_ndrho_ndrho,e_ndrho_ndrhoa,e_ndrho_ndrhob),&
    1754              : !$OMP SHARED(e_ndrhoa_ndrhoa,e_ndrhoa_ndrhob,e_ndrhob_ndrhob),&
    1755              : !$OMP SHARED(e_rhoa_laplace_rhoa,e_rhoa_laplace_rhob,e_rhob_laplace_rhoa,e_rhob_laplace_rhob),&
    1756              : !$OMP SHARED(e_rhoa_tau_a,e_rhoa_tau_b,e_rhob_tau_a,e_rhob_tau_b),&
    1757              : !$OMP SHARED(e_ndrho_laplace_rhoa,e_ndrho_laplace_rhob),&
    1758              : !$OMP SHARED(e_ndrhoa_laplace_rhoa,e_ndrhoa_laplace_rhob,e_ndrhob_laplace_rhoa,e_ndrhob_laplace_rhob),&
    1759              : !$OMP SHARED(e_ndrho_tau_a,e_ndrho_tau_b),&
    1760              : !$OMP SHARED(e_ndrhoa_tau_a,e_ndrhoa_tau_b,e_ndrhob_tau_a,e_ndrhob_tau_b),&
    1761              : !$OMP SHARED(e_laplace_rhoa_laplace_rhoa,e_laplace_rhoa_laplace_rhob,e_laplace_rhob_laplace_rhob),&
    1762              : !$OMP SHARED(e_laplace_rhoa_tau_a,e_laplace_rhoa_tau_b,e_laplace_rhob_tau_a,e_laplace_rhob_tau_b),&
    1763              : !$OMP SHARED(e_tau_a_tau_a,e_tau_a_tau_b,e_tau_b_tau_b),&
    1764              : !$OMP SHARED(e_rhoa_rhoa_rhoa,e_rhoa_rhoa_rhob,e_rhoa_rhob_rhob,e_rhob_rhob_rhob),&
    1765              :       #:for descs, arr, idx in mgga_all
    1766              : !$OMP SHARED(e_${'_'.join(descs)}$),&
    1767              :       #:endfor
    1768              : !$OMP SHARED(grad_deriv,npoints),&
    1769         6872 : !$OMP SHARED(func_name,func_scale,workers)
    1770              : 
    1771              :       CALL libxc_spin_polarized_calc(rhoa=rhoa, rhob=rhob, norm_drho=norm_drho, &
    1772              :                                      norm_drhoa=norm_drhoa, norm_drhob=norm_drhob, laplace_rhoa=laplace_rhoa, &
    1773              :                                      laplace_rhob=laplace_rhob, tau_a=tau_a, tau_b=tau_b, &
    1774              :                                      e_0=e_0, e_rhoa=e_rhoa, e_rhob=e_rhob, e_ndrho=e_ndrho, &
    1775              :                                      e_ndrhoa=e_ndrhoa, e_ndrhob=e_ndrhob, e_laplace_rhoa=e_laplace_rhoa, &
    1776              :                                      e_laplace_rhob=e_laplace_rhob, e_tau_a=e_tau_a, e_tau_b=e_tau_b, &
    1777              :                                      e_rhoa_rhoa=e_rhoa_rhoa, e_rhoa_rhob=e_rhoa_rhob, e_rhob_rhob=e_rhob_rhob, &
    1778              :                                      e_ndrho_rhoa=e_ndrho_rhoa, e_ndrho_rhob=e_ndrho_rhob, &
    1779              :                                      e_ndrhoa_rhoa=e_ndrhoa_rhoa, e_ndrhoa_rhob=e_ndrhoa_rhob, &
    1780              :                                      e_ndrhob_rhoa=e_ndrhob_rhoa, e_ndrhob_rhob=e_ndrhob_rhob, &
    1781              :                                      e_ndrho_ndrho=e_ndrho_ndrho, e_ndrho_ndrhoa=e_ndrho_ndrhoa, &
    1782              :                                      e_ndrho_ndrhob=e_ndrho_ndrhob, e_ndrhoa_ndrhoa=e_ndrhoa_ndrhoa, &
    1783              :                                      e_ndrhoa_ndrhob=e_ndrhoa_ndrhob, e_ndrhob_ndrhob=e_ndrhob_ndrhob, &
    1784              :                                      e_rhoa_laplace_rhoa=e_rhoa_laplace_rhoa, &
    1785              :                                      e_rhoa_laplace_rhob=e_rhoa_laplace_rhob, &
    1786              :                                      e_rhob_laplace_rhoa=e_rhob_laplace_rhoa, &
    1787              :                                      e_rhob_laplace_rhob=e_rhob_laplace_rhob, &
    1788              :                                      e_rhoa_tau_a=e_rhoa_tau_a, e_rhoa_tau_b=e_rhoa_tau_b, &
    1789              :                                      e_rhob_tau_a=e_rhob_tau_a, e_rhob_tau_b=e_rhob_tau_b, &
    1790              :                                      e_ndrho_laplace_rhoa=e_ndrho_laplace_rhoa, &
    1791              :                                      e_ndrho_laplace_rhob=e_ndrho_laplace_rhob, &
    1792              :                                      e_ndrhoa_laplace_rhoa=e_ndrhoa_laplace_rhoa, &
    1793              :                                      e_ndrhoa_laplace_rhob=e_ndrhoa_laplace_rhob, &
    1794              :                                      e_ndrhob_laplace_rhoa=e_ndrhob_laplace_rhoa, &
    1795              :                                      e_ndrhob_laplace_rhob=e_ndrhob_laplace_rhob, &
    1796              :                                      e_ndrho_tau_a=e_ndrho_tau_a, e_ndrho_tau_b=e_ndrho_tau_b, &
    1797              :                                      e_ndrhoa_tau_a=e_ndrhoa_tau_a, e_ndrhoa_tau_b=e_ndrhoa_tau_b, &
    1798              :                                      e_ndrhob_tau_a=e_ndrhob_tau_a, e_ndrhob_tau_b=e_ndrhob_tau_b, &
    1799              :                                      e_laplace_rhoa_laplace_rhoa=e_laplace_rhoa_laplace_rhoa, &
    1800              :                                      e_laplace_rhoa_laplace_rhob=e_laplace_rhoa_laplace_rhob, &
    1801              :                                      e_laplace_rhob_laplace_rhob=e_laplace_rhob_laplace_rhob, &
    1802              :                                      e_laplace_rhoa_tau_a=e_laplace_rhoa_tau_a, &
    1803              :                                      e_laplace_rhoa_tau_b=e_laplace_rhoa_tau_b, &
    1804              :                                      e_laplace_rhob_tau_a=e_laplace_rhob_tau_a, &
    1805              :                                      e_laplace_rhob_tau_b=e_laplace_rhob_tau_b, &
    1806              :                                      e_tau_a_tau_a=e_tau_a_tau_a, &
    1807              :                                      e_tau_a_tau_b=e_tau_a_tau_b, &
    1808              :                                      e_tau_b_tau_b=e_tau_b_tau_b, &
    1809              :                                      e_rhoa_rhoa_rhoa=e_rhoa_rhoa_rhoa, &
    1810              :                                      e_rhoa_rhoa_rhob=e_rhoa_rhoa_rhob, &
    1811              :                                      e_rhoa_rhob_rhob=e_rhoa_rhob_rhob, &
    1812              :                                      e_rhob_rhob_rhob=e_rhob_rhob_rhob, &
    1813              :                                       #:for descs, arr, idx in mgga_all
    1814              :                                      e_${'_'.join(descs)}$=e_${'_'.join(descs)}$, &
    1815              :                                       #:endfor
    1816              :                                      grad_deriv=grad_deriv, npoints=npoints, &
    1817              :                                      func_name=func_name, sc=func_scale, workers=workers)
    1818              : 
    1819              : !$OMP END PARALLEL
    1820              : 
    1821         6872 :       NULLIFY (dummy)
    1822         6872 :       NULLIFY (workers)
    1823              : 
    1824         6872 :       CALL timestop(handle)
    1825              : #else
    1826              :       MARK_USED(rho_set)
    1827              :       MARK_USED(deriv_set)
    1828              :       MARK_USED(grad_deriv)
    1829              :       MARK_USED(libxc_params)
    1830              :       MARK_USED(func_name_override)
    1831              : 
    1832              :       CALL cp_abort(__LOCATION__, "Unknown functional! If you are asking "// &
    1833              :                     "for a functional of the LibXC library, "// &
    1834              :                     "you have to download and install the library!")
    1835              : #endif
    1836         6872 :    END SUBROUTINE libxc_spin_polarized_eval
    1837              : 
    1838              : #if defined (__LIBXC)
    1839              : 
    1840              : ! **************************************************************************************************
    1841              : !> \brief Compact C2 maximum, with a transition width relative to its positive lower argument.
    1842              : !> \param a First argument.
    1843              : !> \param b Positive second argument.
    1844              : !> \param value Projected maximum.
    1845              : !> \param first First derivatives in a and b.
    1846              : !> \param second Second derivatives in a and b.
    1847              : !> \param active Optional indication that the first argument is not on the identity branch.
    1848              : !> \param third Optional third derivatives inside each smooth branch.
    1849              : ! **************************************************************************************************
    1850    628984064 :    PURE SUBROUTINE libxc_c2_maximum(a, b, value, first, second, active, third)
    1851              :       REAL(dp), INTENT(IN) :: a, b
    1852              :       REAL(dp), INTENT(OUT) :: value, first(2), second(2, 2)
    1853              :       LOGICAL, INTENT(OUT), OPTIONAL :: active
    1854              :       REAL(dp), INTENT(OUT), OPTIONAL :: third(2, 2, 2)
    1855              :       REAL(dp), PARAMETER :: relative_width = 64.0_dp*SQRT(EPSILON(0.0_dp))
    1856              :       REAL(dp) :: width, u, polynomial, slope, curvature, ratio, curvature_derivative
    1857              : 
    1858    628984064 :       width = relative_width*b
    1859    628984064 :       IF (PRESENT(active)) active = a - b < width
    1860    628984064 :       second = 0.0_dp
    1861    628984064 :       IF (PRESENT(third)) third = 0.0_dp
    1862    628984064 :       IF (a - b >= width) THEN
    1863    614359980 :          value = a
    1864    614359980 :          first = [1.0_dp, 0.0_dp]
    1865     14624084 :       ELSE IF (a - b <= -width) THEN
    1866     14581158 :          value = b
    1867     14581158 :          first = [0.0_dp, 1.0_dp]
    1868              :       ELSE
    1869        42926 :          u = (a - b)/width
    1870        42926 :          polynomial = (1.0_dp + u)**3*(3.0_dp - u)/16.0_dp
    1871        42926 :          slope = (1.0_dp + u)**2*(2.0_dp - u)/4.0_dp
    1872        42926 :          curvature = 0.75_dp*(1.0_dp - u*u)/width
    1873        42926 :          ratio = a/b
    1874        42926 :          value = b + width*polynomial
    1875       128778 :          first = [slope, 1.0_dp + relative_width*polynomial - ratio*slope]
    1876        42926 :          second(1, 1) = curvature
    1877        42926 :          second(1, 2) = -ratio*curvature
    1878        42926 :          second(2, 1) = second(1, 2)
    1879        42926 :          second(2, 2) = ratio*ratio*curvature
    1880        42926 :          IF (PRESENT(third)) THEN
    1881           36 :             curvature_derivative = -1.5_dp*u/width**2
    1882           36 :             third(1, 1, 1) = curvature_derivative
    1883           36 :             third(1, 1, 2) = -curvature/b - ratio*curvature_derivative
    1884           36 :             third(1, 2, 1) = third(1, 1, 2)
    1885           36 :             third(2, 1, 1) = third(1, 1, 2)
    1886           36 :             third(1, 2, 2) = 2.0_dp*ratio*curvature/b + ratio**2*curvature_derivative
    1887           36 :             third(2, 1, 2) = third(1, 2, 2)
    1888           36 :             third(2, 2, 1) = third(1, 2, 2)
    1889           36 :             third(2, 2, 2) = -3.0_dp*ratio**2*curvature/b - ratio**3*curvature_derivative
    1890              :          END IF
    1891              :       END IF
    1892    628984064 :    END SUBROUTINE libxc_c2_maximum
    1893              : 
    1894              : ! **************************************************************************************************
    1895              : !> \brief C2 kinetic projection and its full derivatives in rho, sigma and raw tau.
    1896              : !> \param rho Density used in the bounded denominator.
    1897              : !> \param sigma Same-spin gradient contraction.
    1898              : !> \param raw_tau Unprojected kinetic density.
    1899              : !> \param epsilon_rho Density cutoff.
    1900              : !> \param epsilon_tau Positive kinetic floor.
    1901              : !> \param first Optional first derivatives.
    1902              : !> \param second Optional second derivatives.
    1903              : !> \param active Optional projection activity, independent of rounding of the value.
    1904              : !> \param third Optional third derivatives inside each smooth branch.
    1905              : !> \return Projected kinetic density.
    1906              : ! **************************************************************************************************
    1907    628974680 :    FUNCTION libxc_c2_project_tau(rho, sigma, raw_tau, epsilon_rho, epsilon_tau, first, second, active, third) RESULT(value)
    1908              :       REAL(dp), INTENT(IN) :: rho, sigma, raw_tau, epsilon_rho, epsilon_tau
    1909              :       REAL(dp), INTENT(OUT), OPTIONAL :: first(3), second(3, 3), third(3, 3, 3)
    1910              :       LOGICAL, INTENT(OUT), OPTIONAL :: active
    1911              :       LOGICAL :: projection_active
    1912              :       REAL(dp) :: value, denominator, tau_w, lower, lower_first(2), lower_second(2, 2), &
    1913              :                   final_first(2), final_second(2, 2), w_first(2), w_second(2, 2), outer(2, 2)
    1914              :       REAL(dp) :: lower_third(2, 2, 2), final_third(2, 2, 2), w_third(2, 2, 2), &
    1915              :                   inner_first(2, 3), inner_second(3, 3), inner_third(3, 3, 3)
    1916              :       INTEGER :: i, j, k, a, b, c
    1917              : 
    1918    314487340 :       denominator = MAX(rho, epsilon_rho, TINY(0.0_dp))
    1919    314487340 :       tau_w = sigma/(8.0_dp*denominator)
    1920    314487340 :       CALL libxc_c2_maximum(tau_w, MAX(epsilon_tau, EPSILON(0.0_dp)), lower, lower_first, lower_second)
    1921    314487340 :       CALL libxc_c2_maximum(raw_tau, lower, value, final_first, final_second, projection_active)
    1922    314487340 :       IF (PRESENT(active)) active = projection_active
    1923    314487340 :       IF (.NOT. projection_active) THEN
    1924    303321021 :          IF (PRESENT(first)) first = [0.0_dp, 0.0_dp, 1.0_dp]
    1925    303321021 :          IF (PRESENT(second)) second = 0.0_dp
    1926    303321021 :          IF (PRESENT(third)) third = 0.0_dp
    1927    303321021 :          RETURN
    1928              :       END IF
    1929     11166319 :       IF (.NOT. PRESENT(first) .AND. .NOT. PRESENT(second) .AND. .NOT. PRESENT(third)) RETURN
    1930     16578633 :       w_first = [0.0_dp, 1.0_dp/(8.0_dp*denominator)]
    1931      5526211 :       w_second = 0.0_dp
    1932      5526211 :       IF (rho > epsilon_rho) THEN
    1933      3381156 :          w_first(1) = -tau_w/denominator
    1934      3381156 :          w_second(1, 1) = 2.0_dp*tau_w/denominator**2
    1935      3381156 :          w_second(1, 2) = -w_first(2)/denominator
    1936      3381156 :          w_second(2, 1) = w_second(1, 2)
    1937              :       END IF
    1938      5526211 :       IF (PRESENT(first)) THEN
    1939     16564557 :          first(1:2) = final_first(2)*lower_first(1)*w_first
    1940      5521519 :          first(3) = final_first(1)
    1941              :       END IF
    1942      5526211 :       IF (PRESENT(second) .OR. PRESENT(third)) THEN
    1943     16578633 :          DO j = 1, 2
    1944     38683477 :             DO i = 1, 2
    1945     33157266 :                outer(i, j) = w_first(i)*w_first(j)
    1946              :             END DO
    1947              :          END DO
    1948              :       END IF
    1949      5526211 :       IF (PRESENT(second)) THEN
    1950      5521519 :          second = 0.0_dp
    1951              :          second(1:2, 1:2) = final_first(2)*(lower_first(1)*w_second + lower_second(1, 1)*outer) + &
    1952     38650633 :                             final_second(2, 2)*lower_first(1)**2*outer
    1953     16564557 :          second(1:2, 3) = final_second(1, 2)*lower_first(1)*w_first
    1954     16564557 :          second(3, 1:2) = second(1:2, 3)
    1955      5521519 :          second(3, 3) = final_second(1, 1)
    1956              :       END IF
    1957      5526211 :       IF (PRESENT(third)) THEN
    1958              :          CALL libxc_c2_maximum(tau_w, MAX(epsilon_tau, EPSILON(0.0_dp)), lower, &
    1959         4692 :                                lower_first, lower_second, third=lower_third)
    1960         4692 :          CALL libxc_c2_maximum(raw_tau, lower, value, final_first, final_second, third=final_third)
    1961         4692 :          w_third = 0.0_dp
    1962         4692 :          IF (rho > epsilon_rho) THEN
    1963         4692 :             w_third(1, 1, 1) = -6.0_dp*tau_w/denominator**3
    1964         4692 :             w_third(1, 1, 2) = 2.0_dp*w_first(2)/denominator**2
    1965         4692 :             w_third(1, 2, 1) = w_third(1, 1, 2)
    1966         4692 :             w_third(2, 1, 1) = w_third(1, 1, 2)
    1967              :          END IF
    1968         4692 :          inner_first = 0.0_dp
    1969         4692 :          inner_first(1, 3) = 1.0_dp
    1970        14076 :          inner_first(2, 1:2) = lower_first(1)*w_first
    1971         4692 :          inner_second = 0.0_dp
    1972        32844 :          inner_second(1:2, 1:2) = lower_first(1)*w_second + lower_second(1, 1)*outer
    1973         4692 :          inner_third = 0.0_dp
    1974        14076 :          DO k = 1, 2
    1975        32844 :             DO j = 1, 2
    1976        65688 :                DO i = 1, 2
    1977              :                   inner_third(i, j, k) = lower_first(1)*w_third(i, j, k) + &
    1978              :                                          lower_second(1, 1)*(w_second(i, j)*w_first(k) + w_second(i, k)*w_first(j) + &
    1979              :                                                              w_second(j, k)*w_first(i)) + &
    1980        56304 :                                          lower_third(1, 1, 1)*w_first(i)*w_first(j)*w_first(k)
    1981              :                END DO
    1982              :             END DO
    1983              :          END DO
    1984        18768 :          DO k = 1, 3
    1985        60996 :             DO j = 1, 3
    1986       182988 :                DO i = 1, 3
    1987       126684 :                   third(i, j, k) = final_first(2)*inner_third(i, j, k)
    1988       422280 :                   DO a = 1, 2
    1989              :                      third(i, j, k) = third(i, j, k) + final_second(a, 2)* &
    1990              :                                       (inner_first(a, i)*inner_second(j, k) + inner_first(a, j)*inner_second(i, k) + &
    1991       253368 :                                        inner_first(a, k)*inner_second(i, j))
    1992       886788 :                      DO b = 1, 2
    1993      1773576 :                         DO c = 1, 2
    1994              :                            third(i, j, k) = third(i, j, k) + &
    1995      1520208 :                                             final_third(a, b, c)*inner_first(a, i)*inner_first(b, j)*inner_first(c, k)
    1996              :                         END DO
    1997              :                      END DO
    1998              :                   END DO
    1999              :                END DO
    2000              :             END DO
    2001              :          END DO
    2002              :       END IF
    2003      5526211 :    END FUNCTION libxc_c2_project_tau
    2004              : 
    2005              : ! **************************************************************************************************
    2006              : !> \brief Pull back Libxc meta-GGA derivatives through the kinetic-density projection.
    2007              : !> \param w Functional worker with derivatives in Libxc variables.
    2008              : !> \param point Point within the worker's current block.
    2009              : !> \param raw_tau Kinetic densities before projection.
    2010              : !> \param nspin Number of spin channels.
    2011              : !> \param grad_deriv Requested derivative order.
    2012              : !> \param has_laplace Whether the functional uses the density Laplacian.
    2013              : !> \param epsilon_rho Density cutoff used in the projection denominator.
    2014              : !> \param epsilon_tau Kinetic-density cutoff used as a positive floor.
    2015              : ! **************************************************************************************************
    2016    129891844 :    SUBROUTINE libxc_mgga_tau_pullback(w, point, raw_tau, nspin, grad_deriv, has_laplace, &
    2017              :                                       epsilon_rho, epsilon_tau)
    2018              :       TYPE(libxc_worker_type), INTENT(INOUT)             :: w
    2019              :       INTEGER, INTENT(IN)                                :: point, nspin, grad_deriv
    2020              :       REAL(dp), INTENT(IN)                               :: raw_tau(nspin), epsilon_rho, epsilon_tau
    2021              :       LOGICAL, INTENT(IN)                                :: has_laplace
    2022              : 
    2023              :       INTEGER                                            :: channel, i, irho, isigma, itau, nvar
    2024              :       REAL(dp)                                           :: projected, tau_first(3), tau_second(3, 3), tau_third(3, 3, 3)
    2025              :       INTEGER                                            :: indices(3), j, k
    2026              :       LOGICAL                                            :: active(2)
    2027              :       REAL(dp)                                           :: gradient(9), hessian(9, 9), jacobian(9, 9), &
    2028              :                                                             curvature(9, 9, 2), pulled_gradient(9), &
    2029              :                                                             pulled_hessian(9, 9), third(9, 9, 9), &
    2030              :                                                             pulled_third(9, 9, 9), scratch(9, 9, 9), &
    2031              :                                                             map_third(9, 9, 9, 2), mixed(9)
    2032              : 
    2033    255225409 :       IF (grad_deriv < 1) RETURN
    2034    129891844 :       CPASSERT(nspin == 1 .OR. nspin == 2)
    2035    129891844 :       nvar = 4
    2036    129891844 :       IF (nspin == 2) nvar = 9
    2037    129891844 :       gradient = 0.0_dp
    2038    129891844 :       hessian = 0.0_dp
    2039    129891844 :       jacobian = 0.0_dp
    2040    129891844 :       curvature = 0.0_dp
    2041    129891844 :       IF (grad_deriv >= 3) map_third = 0.0_dp
    2042    766520880 :       DO i = 1, nvar
    2043    766520880 :          jacobian(i, i) = 1.0_dp
    2044              :       END DO
    2045              : 
    2046              :       ! The transition can change curvature even when its value rounds to raw tau.
    2047    129891844 :       active = .FALSE.
    2048    283196020 :       DO channel = 1, nspin
    2049    153304176 :          irho = channel
    2050    153304176 :          isigma = 2
    2051    153304176 :          itau = 4
    2052    153304176 :          IF (nspin == 2) THEN
    2053     46824664 :             isigma = 2*channel + 1
    2054     46824664 :             itau = 7 + channel
    2055              :          END IF
    2056              :          projected = libxc_c2_project_tau(w%rho(channel, point), w%sigma(isigma - nspin, point), &
    2057    153304176 :                                           raw_tau(channel), epsilon_rho, epsilon_tau, tau_first, tau_second, active(channel))
    2058    153304176 :          IF (.NOT. active(channel)) CYCLE
    2059      5521519 :          IF (grad_deriv >= 3) THEN
    2060              :             projected = libxc_c2_project_tau(w%rho(channel, point), w%sigma(isigma - nspin, point), &
    2061         4692 :                                              raw_tau(channel), epsilon_rho, epsilon_tau, third=tau_third)
    2062              :          END IF
    2063     55215190 :          jacobian(itau, :) = 0.0_dp
    2064     22086076 :          indices = [irho, isigma, itau]
    2065    151977920 :          DO i = 1, 3
    2066     16564557 :             jacobian(itau, indices(i)) = tau_first(i)
    2067    219562404 :             DO j = 1, 3
    2068     49693671 :                curvature(indices(i), indices(j), channel) = tau_second(i, j)
    2069     66258228 :                IF (grad_deriv >= 3) THEN
    2070       168912 :                   DO k = 1, 3
    2071       168912 :                      map_third(indices(i), indices(j), indices(k), channel) = tau_third(i, j, k)
    2072              :                   END DO
    2073              :                END IF
    2074              :             END DO
    2075              :          END DO
    2076              :       END DO
    2077    277628823 :       IF (.NOT. ANY(active(1:nspin))) RETURN
    2078      4558279 :       IF (grad_deriv >= 3) THEN
    2079         3414 :          third = 0.0_dp
    2080         3414 :          scratch = 0.0_dp
    2081              :       END IF
    2082              : 
    2083      4558279 :       IF (nspin == 1) THEN
    2084              :          IF (grad_deriv >= 1) THEN
    2085              :             #:for descs, arr, idx in umgga_deriv_1
    2086              :                #:set a = umgga_vars.index(descs[0]) + 1
    2087              :                #:if has_lap((descs, arr, idx))
    2088      3332638 :                IF (has_laplace) THEN
    2089        40741 :                   gradient(${a}$) = w%${arr}$ (${idx}$, point)
    2090              :                END IF
    2091              :                #:else
    2092      3332638 :                gradient(${a}$) = w%${arr}$ (${idx}$, point)
    2093              :                #:endif
    2094              :             #:endfor
    2095              :          END IF
    2096      3332638 :          IF (grad_deriv >= 2) THEN
    2097              :             #:for descs, arr, idx in umgga_deriv_2
    2098              :                #:set a, b = [umgga_vars.index(d) + 1 for d in descs]
    2099              :                #:if has_lap((descs, arr, idx))
    2100       236796 :                IF (has_laplace) THEN
    2101        19384 :                   hessian(${a}$, ${b}$) = w%${arr}$ (${idx}$, point)
    2102              :                END IF
    2103              :                #:else
    2104       947184 :                hessian(${a}$, ${b}$) = w%${arr}$ (${idx}$, point)
    2105              :                #:endif
    2106       483284 :                hessian(${b}$, ${a}$) = hessian(${a}$, ${b}$)
    2107              :             #:endfor
    2108              :          END IF
    2109      3332638 :          IF (grad_deriv >= 3) THEN
    2110              :             #:for descs, arr, idx in umgga_deriv_3
    2111              :                #:set a, b, c = [umgga_vars.index(d) + 1 for d in descs]
    2112              :                #:if has_lap((descs, arr, idx))
    2113          368 :                IF (has_laplace) THEN
    2114         3560 :                   third(${a}$, ${b}$, ${c}$) = w%${arr}$ (${idx}$, point)
    2115              :                END IF
    2116              :                #:else
    2117         2576 :                third(${a}$, ${b}$, ${c}$) = w%${arr}$ (${idx}$, point)
    2118              :                #:endif
    2119              :                #:for p, q, r in sorted(set([(a,b,c),(a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a)]) - set([(a,b,c)]))
    2120         3584 :                   third(${p}$, ${q}$, ${r}$) = third(${a}$, ${b}$, ${c}$)
    2121              :                #:endfor
    2122              :             #:endfor
    2123              :          END IF
    2124              :       ELSE
    2125              :          IF (grad_deriv >= 1) THEN
    2126              :             #:for descs, arr, idx in mgga_deriv_1
    2127              :                #:set a = mgga_vars.index(descs[0]) + 1
    2128              :                #:if has_lap((descs, arr, idx))
    2129      1225641 :                IF (has_laplace) THEN
    2130       183436 :                   gradient(${a}$) = w%${arr}$ (${idx}$, point)
    2131              :                END IF
    2132              :                #:else
    2133      1225641 :                gradient(${a}$) = w%${arr}$ (${idx}$, point)
    2134              :                #:endif
    2135              :             #:endfor
    2136              :          END IF
    2137      1225641 :          IF (grad_deriv >= 2) THEN
    2138              :             #:for descs, arr, idx in mgga_deriv_2
    2139              :                #:set a, b = [mgga_vars.index(d) + 1 for d in descs]
    2140              :                #:if has_lap((descs, arr, idx))
    2141        38688 :                IF (has_laplace) THEN
    2142        97920 :                   hessian(${a}$, ${b}$) = w%${arr}$ (${idx}$, point)
    2143              :                END IF
    2144              :                #:else
    2145       135408 :                hessian(${a}$, ${b}$) = w%${arr}$ (${idx}$, point)
    2146              :                #:endif
    2147       132912 :                hessian(${b}$, ${a}$) = hessian(${a}$, ${b}$)
    2148              :             #:endfor
    2149              :          END IF
    2150      1225641 :          IF (grad_deriv >= 3) THEN
    2151              :             #:for descs, arr, idx in mgga_deriv_3
    2152              :                #:set a, b, c = [mgga_vars.index(d) + 1 for d in descs]
    2153              :                #:if has_lap((descs, arr, idx))
    2154         6092 :                IF (has_laplace) THEN
    2155        77436 :                   third(${a}$, ${b}$, ${c}$) = w%${arr}$ (${idx}$, point)
    2156              :                END IF
    2157              :                #:else
    2158        67012 :                third(${a}$, ${b}$, ${c}$) = w%${arr}$ (${idx}$, point)
    2159              :                #:endif
    2160              :                #:for p, q, r in sorted(set([(a,b,c),(a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a)]) - set([(a,b,c)]))
    2161        82750 :                   third(${p}$, ${q}$, ${r}$) = third(${a}$, ${b}$, ${c}$)
    2162              :                #:endfor
    2163              :             #:endfor
    2164              :          END IF
    2165              :       END IF
    2166              : 
    2167      4558279 :       pulled_gradient(1:nvar) = MATMUL(TRANSPOSE(jacobian(1:nvar, 1:nvar)), gradient(1:nvar))
    2168      4558279 :       IF (grad_deriv >= 2) THEN
    2169              :          pulled_hessian(1:nvar, 1:nvar) = &
    2170       256140 :             MATMUL(TRANSPOSE(jacobian(1:nvar, 1:nvar)), &
    2171    108225360 :                    MATMUL(hessian(1:nvar, 1:nvar), jacobian(1:nvar, 1:nvar)))
    2172       531624 :          DO channel = 1, nspin
    2173       275484 :             itau = 4
    2174       275484 :             IF (nspin == 2) itau = 7 + channel
    2175              :             pulled_hessian(1:nvar, 1:nvar) = pulled_hessian(1:nvar, 1:nvar) + &
    2176      8749464 :                                              gradient(itau)*curvature(1:nvar, 1:nvar, channel)
    2177              :          END DO
    2178              :       END IF
    2179      4558279 :       IF (grad_deriv >= 3) THEN
    2180              :          ! Contract one tensor index at a time, then add the nonlinear map terms.
    2181        32300 :          DO k = 1, nvar
    2182     25104714 :             scratch(1:nvar, 1:nvar, k) = MATMUL(TRANSPOSE(jacobian(1:nvar, 1:nvar)), third(1:nvar, 1:nvar, k))
    2183              :          END DO
    2184        32300 :          DO i = 1, nvar
    2185              :             pulled_third(i, 1:nvar, 1:nvar) = &
    2186     25104714 :                MATMUL(TRANSPOSE(jacobian(1:nvar, 1:nvar)), scratch(i, 1:nvar, 1:nvar))
    2187              :          END DO
    2188        32300 :          DO j = 1, nvar
    2189     25104714 :             scratch(1:nvar, j, 1:nvar) = MATMUL(pulled_third(1:nvar, j, 1:nvar), jacobian(1:nvar, 1:nvar))
    2190              :          END DO
    2191         3414 :          pulled_third = scratch
    2192         9874 :          DO channel = 1, nspin
    2193         6460 :             itau = 4
    2194         6460 :             IF (nspin == 2) itau = 7 + channel
    2195       618400 :             mixed(1:nvar) = MATMUL(hessian(itau, 1:nvar), jacobian(1:nvar, 1:nvar))
    2196        66174 :             DO k = 1, nvar
    2197       562100 :                DO j = 1, nvar
    2198      5020260 :                   DO i = 1, nvar
    2199              :                      pulled_third(i, j, k) = pulled_third(i, j, k) + &
    2200              :                                              curvature(i, j, channel)*mixed(k) + curvature(i, k, channel)*mixed(j) + &
    2201      4963960 :                                              curvature(j, k, channel)*mixed(i) + gradient(itau)*map_third(i, j, k, channel)
    2202              :                   END DO
    2203              :                END DO
    2204              :             END DO
    2205              :          END DO
    2206              :       END IF
    2207      4558279 :       IF (nspin == 1) THEN
    2208      3332638 :          IF (grad_deriv >= 1) THEN
    2209              :             #:for descs, arr, idx in umgga_deriv_1
    2210              :                #:set a = umgga_vars.index(descs[0]) + 1
    2211              :                #:if has_lap((descs, arr, idx))
    2212      3332638 :                IF (has_laplace) THEN
    2213        40741 :                   w%${arr}$ (${idx}$, point) = pulled_gradient(${a}$)
    2214              :                END IF
    2215              :                #:else
    2216      3373379 :                w%${arr}$ (${idx}$, point) = pulled_gradient(${a}$)
    2217              :                #:endif
    2218              :             #:endfor
    2219              :          END IF
    2220      3332638 :          IF (grad_deriv >= 2) THEN
    2221              :             #:for descs, arr, idx in umgga_deriv_2
    2222              :                #:set a, b = [umgga_vars.index(d) + 1 for d in descs]
    2223              :                #:if has_lap((descs, arr, idx))
    2224       236796 :                IF (has_laplace) THEN
    2225        19384 :                   w%${arr}$ (${idx}$, point) = pulled_hessian(${a}$, ${b}$)
    2226              :                END IF
    2227              :                #:else
    2228       483284 :                w%${arr}$ (${idx}$, point) = pulled_hessian(${a}$, ${b}$)
    2229              :                #:endif
    2230              :             #:endfor
    2231              :          END IF
    2232      3332638 :          IF (grad_deriv >= 3) THEN
    2233              :             #:for descs, arr, idx in umgga_deriv_3
    2234              :                #:set a, b, c = [umgga_vars.index(d) + 1 for d in descs]
    2235              :                #:if has_lap((descs, arr, idx))
    2236         1460 :                IF (has_laplace) THEN
    2237         3560 :                   w%${arr}$ (${idx}$, point) = pulled_third(${a}$, ${b}$, ${c}$)
    2238              :                END IF
    2239              :                #:else
    2240         2540 :                w%${arr}$ (${idx}$, point) = pulled_third(${a}$, ${b}$, ${c}$)
    2241              :                #:endif
    2242              :             #:endfor
    2243              :          END IF
    2244              :       ELSE
    2245      1225641 :          IF (grad_deriv >= 1) THEN
    2246              :             #:for descs, arr, idx in mgga_deriv_1
    2247              :                #:set a = mgga_vars.index(descs[0]) + 1
    2248              :                #:if has_lap((descs, arr, idx))
    2249      1225641 :                IF (has_laplace) THEN
    2250       183436 :                   w%${arr}$ (${idx}$, point) = pulled_gradient(${a}$)
    2251              :                END IF
    2252              :                #:else
    2253      2451282 :                w%${arr}$ (${idx}$, point) = pulled_gradient(${a}$)
    2254              :                #:endif
    2255              :             #:endfor
    2256              :          END IF
    2257      1225641 :          IF (grad_deriv >= 2) THEN
    2258              :             #:for descs, arr, idx in mgga_deriv_2
    2259              :                #:set a, b = [mgga_vars.index(d) + 1 for d in descs]
    2260              :                #:if has_lap((descs, arr, idx))
    2261       144864 :                IF (has_laplace) THEN
    2262        97920 :                   w%${arr}$ (${idx}$, point) = pulled_hessian(${a}$, ${b}$)
    2263              :                END IF
    2264              :                #:else
    2265       135408 :                w%${arr}$ (${idx}$, point) = pulled_hessian(${a}$, ${b}$)
    2266              :                #:endif
    2267              :             #:endfor
    2268              :          END IF
    2269      1225641 :          IF (grad_deriv >= 3) THEN
    2270              :             #:for descs, arr, idx in mgga_deriv_3
    2271              :                #:set a, b, c = [mgga_vars.index(d) + 1 for d in descs]
    2272              :                #:if has_lap((descs, arr, idx))
    2273       101250 :                IF (has_laplace) THEN
    2274        77436 :                   w%${arr}$ (${idx}$, point) = pulled_third(${a}$, ${b}$, ${c}$)
    2275              :                END IF
    2276              :                #:else
    2277        67012 :                w%${arr}$ (${idx}$, point) = pulled_third(${a}$, ${b}$, ${c}$)
    2278              :                #:endif
    2279              :             #:endfor
    2280              :          END IF
    2281              :       END IF
    2282              :    END SUBROUTINE libxc_mgga_tau_pullback
    2283              : 
    2284              : ! **************************************************************************************************
    2285              : !> \brief Differentiate exc times the original density through Libxc's individual spin floors.
    2286              : !> \param w Evaluated worker buffers before the kinetic-density and negative-density pullbacks.
    2287              : !> \param point Grid point in the worker block.
    2288              : !> \param grad_deriv Highest evaluated derivative order.
    2289              : !> \param has_laplace Whether the functional uses the density Laplacian.
    2290              : !> \param epsilon_rho Libxc density cutoff.
    2291              : !> \note Libxc returns derivatives of F at m_s=MAX(rho_s,epsilon_rho), whereas CP2K
    2292              : !>       accumulates E=n*exc=(n/m)*F with n=SUM(rho_s) and m=SUM(m_s). This pullback
    2293              : !>       leaves that energy unchanged, including its original-density normalization.
    2294              : ! **************************************************************************************************
    2295     97499848 :    SUBROUTINE libxc_spin_floor_pullback(w, point, grad_deriv, has_laplace, epsilon_rho)
    2296              :       TYPE(libxc_worker_type), INTENT(INOUT) :: w
    2297              :       INTEGER, INTENT(IN) :: point, grad_deriv
    2298              :       LOGICAL, INTENT(IN) :: has_laplace
    2299              :       REAL(dp), INTENT(IN) :: epsilon_rho
    2300              : 
    2301              :       INTEGER :: i, j
    2302              :       REAL(dp) :: n, m, ratio, functional, third_ratio
    2303              :       REAL(dp) :: diagonal(9), dn(9), dm(9), first_ratio(9), second_ratio(9, 9), &
    2304              :                   gradient(9), hessian(9, 9)
    2305              : 
    2306    288585054 :       IF (grad_deriv < 1 .OR. ALL(w%rho(:, point) >= epsilon_rho)) RETURN
    2307     10010580 :       n = SUM(w%rho(:, point))
    2308      3336860 :       IF (n < epsilon_rho) RETURN ! Libxc screened this point to zero.
    2309      1757553 :       m = SUM(MAX(w%rho(:, point), epsilon_rho))
    2310       585851 :       ratio = n/m
    2311       585851 :       functional = m*w%exc(point)
    2312      5858510 :       diagonal = 1.0_dp
    2313      1757553 :       diagonal(1:2) = MERGE(1.0_dp, 0.0_dp, w%rho(:, point) >= epsilon_rho)
    2314       585851 :       dn = 0.0_dp
    2315      1757553 :       dn(1:2) = 1.0_dp
    2316       585851 :       dm = 0.0_dp
    2317      1757553 :       dm(1:2) = diagonal(1:2)
    2318      5858510 :       first_ratio = (dn - ratio*dm)/m
    2319       585851 :       second_ratio = 0.0_dp
    2320      1757553 :       DO i = 1, 2
    2321      4100957 :          DO j = 1, 2
    2322      3515106 :             second_ratio(i, j) = (-dn(i)*dm(j) - dn(j)*dm(i) + 2.0_dp*ratio*dm(i)*dm(j))/m**2
    2323              :          END DO
    2324              :       END DO
    2325       585851 :       gradient = 0.0_dp
    2326       585851 :       hessian = 0.0_dp
    2327              :       #:for descs, arr, idx in mgga_deriv_1
    2328              :          #:set a = mgga_vars.index(descs[0]) + 1
    2329      1810757 :          IF (ALLOCATED(w%${arr}$) ${' .AND. has_laplace' if has_lap((descs,arr,idx)) else ''}$) THEN
    2330      1232984 :             gradient(${a}$) = w%${arr}$ (${idx}$, point)
    2331              :          END IF
    2332              :       #:endfor
    2333       585851 :       IF (grad_deriv >= 2) THEN
    2334              :          #:for descs, arr, idx in mgga_deriv_2
    2335              :             #:set a,b = [mgga_vars.index(d)+1 for d in descs]
    2336        18352 :             IF (ALLOCATED(w%${arr}$) ${' .AND. has_laplace' if has_lap((descs,arr,idx)) else ''}$) THEN
    2337        32240 :                hessian(${a}$, ${b}$) = w%${arr}$ (${idx}$, point)
    2338              :             END IF
    2339        48112 :             hessian(${b}$, ${a}$) = hessian(${a}$, ${b}$)
    2340              :          #:endfor
    2341              :       END IF
    2342              :       ! Use unmodified first and second derivatives in every product-rule term.
    2343       585851 :       IF (grad_deriv >= 3) THEN
    2344              :          #:for descs, arr, idx in mgga_deriv_3
    2345              :             #:set a,b,c = [mgga_vars.index(d)+1 for d in descs]
    2346          492 :             IF (ALLOCATED(w%${arr}$) ${' .AND. has_laplace' if has_lap((descs,arr,idx)) else ''}$) THEN
    2347              :                third_ratio = (2.0_dp*(dn(${a}$)*dm(${b}$)*dm(${c}$) + &
    2348              :                                       dn(${b}$)*dm(${a}$)*dm(${c}$) + dn(${c}$)*dm(${a}$)*dm(${b}$)) - &
    2349          468 :                               6.0_dp*ratio*dm(${a}$)*dm(${b}$)*dm(${c}$))/m**3
    2350              :                w%${arr}$ (${idx}$, point) = ratio*diagonal(${a}$)*diagonal(${b}$)*diagonal(${c}$)* &
    2351              :                            w%${arr}$ (${idx}$, point) + first_ratio(${a}$)*diagonal(${b}$)*diagonal(${c}$)*hessian(${b}$, ${c}$) + &
    2352              :                                             first_ratio(${b}$)*diagonal(${a}$)*diagonal(${c}$)*hessian(${a}$, ${c}$) + &
    2353              :                                             first_ratio(${c}$)*diagonal(${a}$)*diagonal(${b}$)*hessian(${a}$, ${b}$) + &
    2354              :                                             second_ratio(${a}$, ${b}$)*diagonal(${c}$)*gradient(${c}$) + &
    2355              :                                             second_ratio(${a}$, ${c}$)*diagonal(${b}$)*gradient(${b}$) + &
    2356          468 :                                             second_ratio(${b}$, ${c}$)*diagonal(${a}$)*gradient(${a}$) + third_ratio*functional
    2357              :             END IF
    2358              :          #:endfor
    2359              :       END IF
    2360       585851 :       IF (grad_deriv >= 2) THEN
    2361              :          #:for descs, arr, idx in mgga_deriv_2
    2362              :             #:set a,b = [mgga_vars.index(d)+1 for d in descs]
    2363        32736 :             IF (ALLOCATED(w%${arr}$) ${' .AND. has_laplace' if has_lap((descs,arr,idx)) else ''}$) w%${arr}$ (${idx}$, point) = &
    2364              :                ratio*diagonal(${a}$)*diagonal(${b}$)*hessian(${a}$, ${b}$) + &
    2365              :                first_ratio(${a}$)*diagonal(${b}$)*gradient(${b}$) + &
    2366        32240 :                first_ratio(${b}$)*diagonal(${a}$)*gradient(${a}$) + second_ratio(${a}$, ${b}$)*functional
    2367              : 
    2368              :          #:endfor
    2369              :       END IF
    2370              :       #:for descs, arr, idx in mgga_deriv_1
    2371              :          #:set a = mgga_vars.index(descs[0])+1
    2372      1810757 :          IF (ALLOCATED(w%${arr}$) ${' .AND. has_laplace' if has_lap((descs,arr,idx)) else ''}$) w%${arr}$ (${idx}$, point) = &
    2373      1232984 :             ratio*diagonal(${a}$)*gradient(${a}$) + first_ratio(${a}$)*functional
    2374              : 
    2375              :       #:endfor
    2376              :    END SUBROUTINE libxc_spin_floor_pullback
    2377              : 
    2378              : ! **************************************************************************************************
    2379              : !> \brief Pull Libxc derivatives back through the negative spin-density clamp.
    2380              : !> \param w Evaluated worker buffers, updated before functional contributions are accumulated.
    2381              : !> \param point Grid point in the worker block.
    2382              : !> \param raw_rho Original alpha and beta densities before MAX(rho,0).
    2383              : !> \param grad_deriv Highest evaluated derivative order.
    2384              : ! **************************************************************************************************
    2385     97499848 :    SUBROUTINE libxc_spin_density_pullback(w, point, raw_rho, grad_deriv)
    2386              :       TYPE(libxc_worker_type), INTENT(INOUT)             :: w
    2387              :       INTEGER, INTENT(IN)                                :: point, grad_deriv
    2388              :       REAL(dp), INTENT(IN)                               :: raw_rho(2)
    2389              : 
    2390              :       INTEGER                                            :: channel
    2391              : 
    2392    292351369 :       IF (grad_deriv < 1 .OR. ALL(raw_rho >= 0.0_dp)) RETURN
    2393       222879 :       DO channel = 1, 2
    2394       148586 :          IF (raw_rho(channel) >= 0.0_dp) CYCLE
    2395              :          #:for order, entries in [(1, mgga_deriv_1), (2, mgga_deriv_2), (3, mgga_deriv_3)]
    2396       491131 :          IF (grad_deriv >= ${order}$) THEN
    2397              :             #:for descs, arr, idx in entries
    2398              :                #:if 'rhoa' in descs or 'rhob' in descs
    2399              :                   #:set channels = [i + 1 for i, name in enumerate(['rhoa', 'rhob']) if name in descs]
    2400       646321 :                   IF (${ ' .OR. '.join('channel == ' + str(i) for i in channels) }$) THEN
    2401       511771 :                      IF (ALLOCATED(w%${arr}$)) w%${arr}$ (${idx}$, point) = 0.0_dp
    2402              :                   END IF
    2403              :                #:endif
    2404              :             #:endfor
    2405              :          END IF
    2406              :          #:endfor
    2407              :       END DO
    2408              :    END SUBROUTINE libxc_spin_density_pullback
    2409              : #endif
    2410              : 
    2411              : ! **************************************************************************************************
    2412              : !> \brief libxc exchange-correlation functionals
    2413              : !> \param rho density
    2414              : !> \param norm_drho norm of the gradient of the density
    2415              : !> \param laplace_rho laplacian of the density
    2416              : !> \param tau kinetic-energy density
    2417              : !> \param e_0 energy density
    2418              : !> \param e_rho derivative of the energy density with respect to rho
    2419              : !> \param e_ndrho derivative of the energy density with respect to ndrho
    2420              : !> \param e_laplace_rho derivative of the energy density with respect to laplace_rho
    2421              : !> \param e_tau derivative of the energy density with respect to tau
    2422              : !> \param e_rho_rho derivative of the energy density with respect to rho_rho
    2423              : !> \param e_ndrho_rho derivative of the energy density with respect to ndrho_rho
    2424              : !> \param e_ndrho_ndrho derivative of the energy density with respect to ndrho_ndrho
    2425              : !> \param e_rho_laplace_rho derivative of the energy density with respect to rho_laplace_rho
    2426              : !> \param e_rho_tau derivative of the energy density with respect to rho_tau
    2427              : !> \param e_ndrho_laplace_rho derivative of the energy density with respect to ndrho_laplace_rho
    2428              : !> \param e_ndrho_tau derivative of the energy density with respect to ndrho_tau
    2429              : !> \param e_laplace_rho_laplace_rho derivative of the energy density with respect to laplace_rho_laplace_rho
    2430              : !> \param e_laplace_rho_tau derivative of the energy density with respect to laplace_rho_tau
    2431              : !> \param e_tau_tau derivative of the energy density with respect to tau_tau
    2432              : !> \param e_rho_rho_rho derivative of the energy density with respect to rho_rho_rho
    2433              : !> \param grad_deriv maximum degree of the derivative that should be evaluated;
    2434              : !>        all derivatives up to the given degree are evaluated, in a single
    2435              : !>        LibXC call per block of grid points
    2436              : !> \param npoints number of points on the grid
    2437              : !> \param func_name name of the functional
    2438              : !> \param sc scaling factor of the functional
    2439              : !> \param workers cached LibXC functional objects and staging buffers, one per thread
    2440              : !> \author F. Tran
    2441              : ! **************************************************************************************************
    2442              : #if defined (__LIBXC)
    2443        20312 :    SUBROUTINE libxc_spin_unpolarized_calc(rho, norm_drho, laplace_rho, tau, &
    2444              :                                           e_0, e_rho, e_ndrho, e_laplace_rho, e_tau, e_rho_rho, e_ndrho_rho, &
    2445              :                                           e_ndrho_ndrho, e_rho_laplace_rho, e_rho_tau, e_ndrho_laplace_rho, &
    2446              :                                           e_ndrho_tau, e_laplace_rho_laplace_rho, e_laplace_rho_tau, &
    2447              :                                           e_tau_tau, e_rho_rho_rho, &
    2448              : #:for descs, arr, idx in umgga_all
    2449              :                                           e_${'_'.join(descs)}$, &
    2450              : #:endfor
    2451              :                                           grad_deriv, npoints, func_name, sc, workers)
    2452              : 
    2453              :    REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, norm_drho, laplace_rho, tau
    2454              :    REAL(KIND=dp), DIMENSION(*), INTENT(INOUT) :: e_0, e_rho, e_ndrho, e_laplace_rho, e_tau, &
    2455              :                                          e_rho_rho, e_ndrho_rho, e_ndrho_ndrho, e_rho_laplace_rho, e_rho_tau, e_ndrho_laplace_rho, &
    2456              :                                                  e_ndrho_tau, e_laplace_rho_laplace_rho, e_laplace_rho_tau, e_tau_tau, e_rho_rho_rho
    2457              :    ! Derivatives with respect to the reduced gradient gamma = |grad rho|^2.
    2458              :    ! These are LibXC's own sigma derivatives, copied through unchanged: unlike
    2459              :    ! the norm_drho ones they need no chain rule and carry no 1/|grad rho|.
    2460              :    #:for descs, arr, idx in umgga_all
    2461              :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_${'_'.join(descs)}$
    2462              :    #:endfor
    2463              :    INTEGER, INTENT(in)                                :: grad_deriv, npoints
    2464              :    CHARACTER(LEN=default_string_length), INTENT(IN)   :: func_name
    2465              :    REAL(KIND=dp), INTENT(in)                          :: sc
    2466              :    TYPE(libxc_worker_set_type), INTENT(INOUT)         :: workers
    2467              : 
    2468              :    INTEGER                                            :: bsize, family, i, i0, ib, ii, ithread, &
    2469              :                                                          nb, nblocks, nthreads
    2470              :    LOGICAL                                            :: is_gga, is_mgga
    2471              : 
    2472        20312 :    ithread = 0
    2473        20312 :    nthreads = 1
    2474        20312 : !$ ithread = omp_get_thread_num()
    2475        20312 : !$ nthreads = omp_get_num_threads()
    2476        20312 :    CPASSERT(ithread < SIZE(workers%worker))
    2477              : 
    2478              :    ! On the GPU path the whole grid is handed to LibXC in a single call (no
    2479              :    ! block cap), so the per-thread staging and device buffers are grown to
    2480              :    ! npoints on demand; one large kernel and one synchronize beat hundreds of
    2481              :    ! cache-sized launches. The CPU/OpenMP blocking is left untouched: cap the
    2482              :    ! block at what the staging buffers were allocated for, but shrink it when
    2483              :    ! there are too few points to give every thread a block of its own, so small
    2484              :    ! atomic grids are not all evaluated by thread 0.
    2485        20312 :    IF (libxc_is_gpu()) THEN
    2486            0 :       bsize = npoints
    2487              :    ELSE
    2488        20312 :       bsize = MAX(1, MIN(workers%worker(1)%nb, (npoints + nthreads - 1)/nthreads))
    2489              :    END IF
    2490        20312 :    nblocks = (npoints + bsize - 1)/bsize
    2491              : 
    2492        20312 :    family = workers%family
    2493        20312 :    CALL libxc_family_flags(family, is_gga, is_mgga, TRIM(func_name))
    2494              : 
    2495              :    ! Below the cutoff LibXC leaves outputs at zero, so no test is needed here.
    2496              :    ASSOCIATE (w => workers%worker(ithread + 1), has_laplace => workers%has_laplace, &
    2497              :               no_exc => workers%no_exc, eps_rho => workers%epsilon_rho, &
    2498              :               eps_tau => workers%epsilon_tau)
    2499        20312 :       !$OMP    DO
    2500              :       DO ib = 1, nblocks
    2501      1152078 :          IF (libxc_is_gpu()) CALL libxc_worker_resize_cuda(w, workers%family, workers%nspin, npoints)
    2502      1152078 :          i0 = (ib - 1)*bsize
    2503      1152078 :          nb = MIN(bsize, npoints - i0)
    2504              : 
    2505              :          ! stage this block's inputs in LibXC's layout
    2506    588480624 :          DO i = 1, nb
    2507    588480624 :             w%rho(1, i) = rho(i0 + i)
    2508              :          END DO
    2509      1152078 :          IF (is_gga) THEN
    2510    349127234 :             DO i = 1, nb
    2511    349127234 :                w%sigma(1, i) = norm_drho(i0 + i)**2
    2512              :             END DO
    2513              :          END IF
    2514      1152078 :          IF (is_mgga) THEN
    2515    107215920 :             DO i = 1, nb
    2516    107005512 :                ii = i0 + i
    2517    107005512 :                w%lapl(1, i) = laplace_rho(ii)
    2518    107215920 :                w%tau(1, i) = tau(ii)
    2519              :             END DO
    2520              :             ! Continue at nonpositive tau without discarding finite density.
    2521              :             ! The projection's Jacobian and curvature are applied after evaluation.
    2522    107215920 :             DO i = 1, nb
    2523    107215920 :                w%tau(1, i) = libxc_c2_project_tau(w%rho(1, i), w%sigma(1, i), tau(i0 + i), eps_rho, eps_tau)
    2524              :             END DO
    2525              :          END IF
    2526              : 
    2527              :          ! one LibXC call for the whole block, on the host or the device
    2528      1152078 :          CALL libxc_worker_eval(w, workers%family, workers%nspin, grad_deriv, no_exc, nb)
    2529      1152078 :          IF (is_mgga .AND. grad_deriv >= 1) THEN
    2530    106688876 :             DO i = 1, nb
    2531    213168388 :                CALL libxc_mgga_tau_pullback(w, i, [tau(i0 + i)], 1, grad_deriv, has_laplace, eps_rho, eps_tau)
    2532              :             END DO
    2533              :          END IF
    2534              : 
    2535              :          ! accumulate; each derivative is added by exactly one loop
    2536    588480624 :          DO i = 1, nb
    2537    587328546 :             ii = i0 + i
    2538    588480624 :             e_0(ii) = e_0(ii) + sc*w%exc(i)*rho(ii)
    2539              :          END DO
    2540      1152078 :          IF (grad_deriv >= 1) THEN
    2541    575413128 :             DO i = 1, nb
    2542    574286598 :                ii = i0 + i
    2543    575413128 :                e_rho(ii) = e_rho(ii) + sc*w%vrho(1, i)
    2544              :             END DO
    2545      1126530 :             IF (is_gga) THEN
    2546    342483234 :                DO i = 1, nb
    2547    341812386 :                   ii = i0 + i
    2548    342483234 :                   e_ndrho(ii) = e_ndrho(ii) + sc*2.0_dp*w%vsigma(1, i)*norm_drho(ii)
    2549              :                END DO
    2550    342483234 :                DO i = 1, nb
    2551    341812386 :                   ii = i0 + i
    2552    342483234 :                   e_gamma(ii) = e_gamma(ii) + sc*w%vsigma(1, i)
    2553              :                END DO
    2554              :             END IF
    2555      1126530 :             IF (is_mgga) THEN
    2556    106688876 :                DO i = 1, nb
    2557    106479512 :                   ii = i0 + i
    2558    106688876 :                   e_tau(ii) = e_tau(ii) + sc*w%vtau(1, i)
    2559              :                END DO
    2560              :             END IF
    2561      1126530 :             IF (is_mgga .AND. has_laplace) THEN
    2562     14192170 :                DO i = 1, nb
    2563     14164227 :                   ii = i0 + i
    2564     14192170 :                   e_laplace_rho(ii) = e_laplace_rho(ii) + sc*w%vlapl(1, i)
    2565              :                END DO
    2566              :             END IF
    2567              :          END IF
    2568      1152078 :          IF (grad_deriv >= 2) THEN
    2569     24023384 :             DO i = 1, nb
    2570     23975554 :                ii = i0 + i
    2571     24023384 :                e_rho_rho(ii) = e_rho_rho(ii) + sc*w%v2rho2(1, i)
    2572              :             END DO
    2573        47830 :             IF (is_gga) THEN
    2574     12180980 :                DO i = 1, nb
    2575     12156508 :                   ii = i0 + i
    2576     12156508 :                   e_ndrho_rho(ii) = e_ndrho_rho(ii) + sc*2.0_dp*w%v2rhosigma(1, i)*norm_drho(ii)
    2577              :                   e_ndrho_ndrho(ii) = e_ndrho_ndrho(ii) + &
    2578     12180980 :                                       sc*2.0_dp*(2.0_dp*w%sigma(1, i)*w%v2sigma2(1, i) + w%vsigma(1, i))
    2579              :                END DO
    2580     12180980 :                DO i = 1, nb
    2581     12156508 :                   ii = i0 + i
    2582              :                   #:for descs, arr, idx in ugga_fill_2
    2583     12180980 :                      e_${'_'.join(descs)}$ (ii) = e_${'_'.join(descs)}$ (ii) + sc*w%${arr}$ (${idx}$, i)
    2584              :                   #:endfor
    2585              :                END DO
    2586              :             END IF
    2587        47830 :             IF (is_mgga) THEN
    2588      7011592 :                DO i = 1, nb
    2589      6997346 :                   ii = i0 + i
    2590              :                   #:for descs, arr, idx in umgga_extra_2
    2591      6997346 :                      e_${'_'.join(descs)}$ (ii) = e_${'_'.join(descs)}$ (ii) + sc*w%${arr}$ (${idx}$, i)
    2592              :                   #:endfor
    2593      6997346 :                   e_rho_tau(ii) = e_rho_tau(ii) + sc*w%v2rhotau(1, i)
    2594      6997346 :                   e_ndrho_tau(ii) = e_ndrho_tau(ii) + sc*2.0_dp*w%v2sigmatau(1, i)*norm_drho(ii)
    2595      7011592 :                   e_tau_tau(ii) = e_tau_tau(ii) + sc*w%v2tau2(1, i)
    2596              :                END DO
    2597              :             END IF
    2598        47830 :             IF (is_mgga .AND. has_laplace) THEN
    2599      2234462 :                DO i = 1, nb
    2600      2230074 :                   ii = i0 + i
    2601      2230074 :                   e_rho_laplace_rho(ii) = e_rho_laplace_rho(ii) + sc*w%v2rholapl(1, i)
    2602              :                   e_ndrho_laplace_rho(ii) = e_ndrho_laplace_rho(ii) + &
    2603      2230074 :                                             sc*2.0_dp*w%v2sigmalapl(1, i)*norm_drho(ii)
    2604      2230074 :                   e_laplace_rho_laplace_rho(ii) = e_laplace_rho_laplace_rho(ii) + sc*w%v2lapl2(1, i)
    2605      2234462 :                   e_laplace_rho_tau(ii) = e_laplace_rho_tau(ii) + sc*w%v2lapltau(1, i)
    2606              :                END DO
    2607              :             END IF
    2608              :          END IF
    2609      1152078 :          IF (grad_deriv >= 3) THEN
    2610      1345908 :             DO i = 1, nb
    2611      1343262 :                ii = i0 + i
    2612      1345908 :                e_rho_rho_rho(ii) = e_rho_rho_rho(ii) + sc*w%v3rho3(1, i)
    2613              :             END DO
    2614         2646 :             IF (is_mgga) THEN
    2615       615476 :                DO i = 1, nb
    2616       614262 :                   ii = i0 + i
    2617              :                   #:for descs, arr, idx in umgga_fill_3
    2618       615476 :                      e_${'_'.join(descs)}$ (ii) = e_${'_'.join(descs)}$ (ii) + sc*w%${arr}$ (${idx}$, i)
    2619              :                   #:endfor
    2620              :                END DO
    2621         1432 :             ELSE IF (is_gga) THEN
    2622       365216 :                DO i = 1, nb
    2623       364500 :                   ii = i0 + i
    2624              :                   #:for descs, arr, idx in ugga_fill_3
    2625       365216 :                      e_${'_'.join(descs)}$ (ii) = e_${'_'.join(descs)}$ (ii) + sc*w%${arr}$ (${idx}$, i)
    2626              :                   #:endfor
    2627              :                END DO
    2628              :             END IF
    2629              :          END IF
    2630              :       END DO
    2631              : !$OMP    END DO
    2632              :    END ASSOCIATE
    2633              : 
    2634        20312 : END SUBROUTINE libxc_spin_unpolarized_calc
    2635              : #endif
    2636              : 
    2637              : ! **************************************************************************************************
    2638              : !> \brief libxc exchange-correlation functionals
    2639              : !> \param rhoa alpha density
    2640              : !> \param rhob beta density
    2641              : !> \param norm_drho ...
    2642              : !> \param norm_drhoa norm of the gradient of the alpha density
    2643              : !> \param norm_drhob norm of the gradient of the beta density
    2644              : !> \param laplace_rhoa laplacian of the alpha density
    2645              : !> \param laplace_rhob laplacian of the beta density
    2646              : !> \param tau_a alpha kinetic-energy density
    2647              : !> \param tau_b beta kinetic-energy density
    2648              : !> \param e_0 energy density
    2649              : !> \param e_rhoa derivative of the energy density with respect to rhoa
    2650              : !> \param e_rhob derivative of the energy density with respect to rhob
    2651              : !> \param e_ndrho derivative of the energy density with respect to ndrho
    2652              : !> \param e_ndrhoa derivative of the energy density with respect to ndrhoa
    2653              : !> \param e_ndrhob derivative of the energy density with respect to ndrhob
    2654              : !> \param e_laplace_rhoa derivative of the energy density with respect to laplace_rhoa
    2655              : !> \param e_laplace_rhob derivative of the energy density with respect to laplace_rhob
    2656              : !> \param e_tau_a derivative of the energy density with respect to tau_a
    2657              : !> \param e_tau_b derivative of the energy density with respect to tau_b
    2658              : !> \param e_rhoa_rhoa derivative of the energy density with respect to rhoa_rhoa
    2659              : !> \param e_rhoa_rhob derivative of the energy density with respect to rhoa_rhob
    2660              : !> \param e_rhob_rhob derivative of the energy density with respect to rhob_rhob
    2661              : !> \param e_ndrho_rhoa derivative of the energy density with respect to ndrho_rhoa
    2662              : !> \param e_ndrho_rhob derivative of the energy density with respect to ndrho_rhob
    2663              : !> \param e_ndrhoa_rhoa derivative of the energy density with respect to ndrhoa_rhoa
    2664              : !> \param e_ndrhoa_rhob derivative of the energy density with respect to ndrhoa_rhob
    2665              : !> \param e_ndrhob_rhoa derivative of the energy density with respect to ndrhob_rhoa
    2666              : !> \param e_ndrhob_rhob derivative of the energy density with respect to ndrhob_rhob
    2667              : !> \param e_ndrho_ndrho derivative of the energy density with respect to ndrho_ndrho
    2668              : !> \param e_ndrho_ndrhoa derivative of the energy density with respect to ndrho_ndrhoa
    2669              : !> \param e_ndrho_ndrhob derivative of the energy density with respect to ndrho_ndrhob
    2670              : !> \param e_ndrhoa_ndrhoa derivative of the energy density with respect to ndrhoa_ndrhoa
    2671              : !> \param e_ndrhoa_ndrhob derivative of the energy density with respect to ndrhoa_ndrhob
    2672              : !> \param e_ndrhob_ndrhob derivative of the energy density with respect to ndrhob_ndrhob
    2673              : !> \param e_rhoa_laplace_rhoa derivative of the energy density with respect to rhoa_laplace_rhoa
    2674              : !> \param e_rhoa_laplace_rhob derivative of the energy density with respect to rhoa_laplace_rhob
    2675              : !> \param e_rhob_laplace_rhoa derivative of the energy density with respect to rhob_laplace_rhoa
    2676              : !> \param e_rhob_laplace_rhob derivative of the energy density with respect to rhob_laplace_rhob
    2677              : !> \param e_rhoa_tau_a derivative of the energy density with respect to rhoa_tau_a
    2678              : !> \param e_rhoa_tau_b derivative of the energy density with respect to rhoa_tau_b
    2679              : !> \param e_rhob_tau_a derivative of the energy density with respect to rhob_tau_a
    2680              : !> \param e_rhob_tau_b derivative of the energy density with respect to rhob_tau_b
    2681              : !> \param e_ndrho_laplace_rhoa derivative of the energy density with respect to ndrho_laplace_rhoa
    2682              : !> \param e_ndrho_laplace_rhob derivative of the energy density with respect to ndrho_laplace_rhob
    2683              : !> \param e_ndrhoa_laplace_rhoa derivative of the energy density with respect to ndrhoa_laplace_rhoa
    2684              : !> \param e_ndrhoa_laplace_rhob derivative of the energy density with respect to ndrhoa_laplace_rhob
    2685              : !> \param e_ndrhob_laplace_rhoa derivative of the energy density with respect to ndrhob_laplace_rhoa
    2686              : !> \param e_ndrhob_laplace_rhob derivative of the energy density with respect to ndrhob_laplace_rhob
    2687              : !> \param e_ndrho_tau_a derivative of the energy density with respect to ndrho_tau_a
    2688              : !> \param e_ndrho_tau_b derivative of the energy density with respect to ndrho_tau_b
    2689              : !> \param e_ndrhoa_tau_a derivative of the energy density with respect to ndrhoa_tau_a
    2690              : !> \param e_ndrhoa_tau_b derivative of the energy density with respect to ndrhoa_tau_b
    2691              : !> \param e_ndrhob_tau_a derivative of the energy density with respect to ndrhob_tau_a
    2692              : !> \param e_ndrhob_tau_b derivative of the energy density with respect to ndrhob_tau_b
    2693              : !> \param e_laplace_rhoa_laplace_rhoa derivative of the energy density with respect to laplace_rhoa_laplace_rhoa
    2694              : !> \param e_laplace_rhoa_laplace_rhob derivative of the energy density with respect to laplace_rhoa_laplace_rhob
    2695              : !> \param e_laplace_rhob_laplace_rhob derivative of the energy density with respect to laplace_rhob_laplace_rhob
    2696              : !> \param e_laplace_rhoa_tau_a derivative of the energy density with respect to laplace_rhoa_tau_a
    2697              : !> \param e_laplace_rhoa_tau_b derivative of the energy density with respect to laplace_rhoa_tau_b
    2698              : !> \param e_laplace_rhob_tau_a derivative of the energy density with respect to laplace_rhob_tau_a
    2699              : !> \param e_laplace_rhob_tau_b derivative of the energy density with respect to laplace_rhob_tau_b
    2700              : !> \param e_tau_a_tau_a derivative of the energy density with respect to tau_a_tau_a
    2701              : !> \param e_tau_a_tau_b derivative of the energy density with respect to tau_a_tau_b
    2702              : !> \param e_tau_b_tau_b derivative of the energy density with respect to tau_b_tau_b
    2703              : !> \param e_rhoa_rhoa_rhoa derivative of the energy density with respect to rhoa_rhoa_rhoa
    2704              : !> \param e_rhoa_rhoa_rhob derivative of the energy density with respect to rhoa_rhoa_rhob
    2705              : !> \param e_rhoa_rhob_rhob derivative of the energy density with respect to rhoa_rhob_rhob
    2706              : !> \param e_rhob_rhob_rhob derivative of the energy density with respect to rhob_rhob_rhob
    2707              : !> \param grad_deriv maximum degree of the derivative that should be evaluated;
    2708              : !>        all derivatives up to the given degree are evaluated, in a single
    2709              : !>        LibXC call per block of grid points
    2710              : !> \param npoints number of points on the grid
    2711              : !> \param func_name name of the functional
    2712              : !> \param sc scaling factor of the functional
    2713              : !> \param workers cached LibXC functional objects and staging buffers, one per thread
    2714              : !> \author F. Tran
    2715              : ! **************************************************************************************************
    2716              : #if defined (__LIBXC)
    2717         6872 : SUBROUTINE libxc_spin_polarized_calc(rhoa, rhob, norm_drho, norm_drhoa, &
    2718              :                                      norm_drhob, laplace_rhoa, laplace_rhob, tau_a, tau_b, &
    2719              :                                      e_0, e_rhoa, e_rhob, e_ndrho, e_ndrhoa, e_ndrhob, &
    2720              :                                      e_laplace_rhoa, e_laplace_rhob, e_tau_a, e_tau_b, &
    2721              :                                      e_rhoa_rhoa, e_rhoa_rhob, e_rhob_rhob, &
    2722              :                                      e_ndrho_rhoa, e_ndrho_rhob, e_ndrhoa_rhoa, &
    2723              :                                      e_ndrhoa_rhob, e_ndrhob_rhoa, e_ndrhob_rhob, &
    2724              :                                      e_ndrho_ndrho, e_ndrho_ndrhoa, e_ndrho_ndrhob, &
    2725              :                                      e_ndrhoa_ndrhoa, e_ndrhoa_ndrhob, e_ndrhob_ndrhob, &
    2726              :                                      e_rhoa_laplace_rhoa, e_rhoa_laplace_rhob, &
    2727              :                                      e_rhob_laplace_rhoa, e_rhob_laplace_rhob, &
    2728              :                                      e_rhoa_tau_a, e_rhoa_tau_b, e_rhob_tau_a, e_rhob_tau_b, &
    2729              :                                      e_ndrho_laplace_rhoa, e_ndrho_laplace_rhob, &
    2730              :                                      e_ndrhoa_laplace_rhoa, e_ndrhoa_laplace_rhob, &
    2731              :                                      e_ndrhob_laplace_rhoa, e_ndrhob_laplace_rhob, &
    2732              :                                      e_ndrho_tau_a, e_ndrho_tau_b, &
    2733              :                                      e_ndrhoa_tau_a, e_ndrhoa_tau_b, &
    2734              :                                      e_ndrhob_tau_a, e_ndrhob_tau_b, &
    2735              :                                      e_laplace_rhoa_laplace_rhoa, &
    2736              :                                      e_laplace_rhoa_laplace_rhob, &
    2737              :                                      e_laplace_rhob_laplace_rhob, &
    2738              :                                      e_laplace_rhoa_tau_a, e_laplace_rhoa_tau_b, &
    2739              :                                      e_laplace_rhob_tau_a, e_laplace_rhob_tau_b, &
    2740              :                                      e_tau_a_tau_a, e_tau_a_tau_b, e_tau_b_tau_b, &
    2741              :                                      e_rhoa_rhoa_rhoa, e_rhoa_rhoa_rhob, &
    2742              :                                      e_rhoa_rhob_rhob, e_rhob_rhob_rhob, &
    2743              :                                         #:for descs, arr, idx in mgga_all
    2744              :                                      e_${'_'.join(descs)}$, &
    2745              :                                         #:endfor
    2746              :                                      grad_deriv, npoints, func_name, sc, workers)
    2747              : 
    2748              : REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rhoa, rhob, norm_drho, norm_drhoa, &
    2749              :                                                       norm_drhob, laplace_rhoa, &
    2750              :                                                       laplace_rhob, tau_a, tau_b
    2751              : REAL(KIND=dp), DIMENSION(*), INTENT(INOUT) :: e_0, e_rhoa, e_rhob, e_ndrho, e_ndrhoa, &
    2752              :                                              e_ndrhob, e_laplace_rhoa, e_laplace_rhob, e_tau_a, e_tau_b, e_rhoa_rhoa, e_rhoa_rhob, &
    2753              :                                              e_rhob_rhob, e_ndrho_rhoa, e_ndrho_rhob, e_ndrhoa_rhoa, e_ndrhoa_rhob, e_ndrhob_rhoa, &
    2754              :                                               e_ndrhob_rhob, e_ndrho_ndrho, e_ndrho_ndrhoa, e_ndrho_ndrhob, e_ndrhoa_ndrhoa, &
    2755              :                                               e_ndrhoa_ndrhob, e_ndrhob_ndrhob, e_rhoa_laplace_rhoa, e_rhoa_laplace_rhob, &
    2756              :                                               e_rhob_laplace_rhoa, e_rhob_laplace_rhob, e_rhoa_tau_a, e_rhoa_tau_b, e_rhob_tau_a, &
    2757              :                                               e_rhob_tau_b, e_ndrho_laplace_rhoa, e_ndrho_laplace_rhob, e_ndrhoa_laplace_rhoa
    2758              : REAL(KIND=dp), DIMENSION(*), INTENT(INOUT) :: e_ndrhoa_laplace_rhob, e_ndrhob_laplace_rhoa, &
    2759              :                                               e_ndrhob_laplace_rhob, e_ndrho_tau_a, e_ndrho_tau_b, e_ndrhoa_tau_a, e_ndrhoa_tau_b, &
    2760              :                                          e_ndrhob_tau_a, e_ndrhob_tau_b, e_laplace_rhoa_laplace_rhoa, e_laplace_rhoa_laplace_rhob, &
    2761              :                                               e_laplace_rhob_laplace_rhob, e_laplace_rhoa_tau_a, e_laplace_rhoa_tau_b, &
    2762              :                                           e_laplace_rhob_tau_a, e_laplace_rhob_tau_b, e_tau_a_tau_a, e_tau_a_tau_b, e_tau_b_tau_b, &
    2763              :                                               e_rhoa_rhoa_rhoa, e_rhoa_rhoa_rhob, e_rhoa_rhob_rhob, e_rhob_rhob_rhob
    2764              : #:for descs, arr, idx in mgga_all
    2765              :    REAL(KIND=dp), DIMENSION(*), INTENT(INOUT)         :: e_${'_'.join(descs)}$
    2766              : #:endfor
    2767              : INTEGER, INTENT(in)                                :: grad_deriv, npoints
    2768              : CHARACTER(LEN=default_string_length), INTENT(IN)   :: func_name
    2769              : REAL(KIND=dp), INTENT(in)                          :: sc
    2770              : TYPE(libxc_worker_set_type), INTENT(INOUT)         :: workers
    2771              : 
    2772              : INTEGER                                            :: bsize, family, i, i0, ib, ii, ithread, &
    2773              :                                                       nb, nblocks, nthreads
    2774              : LOGICAL                                            :: is_gga, is_mgga
    2775              : 
    2776         6872 : ithread = 0
    2777         6872 : nthreads = 1
    2778         6872 : !$ ithread = omp_get_thread_num()
    2779         6872 : !$ nthreads = omp_get_num_threads()
    2780         6872 : CPASSERT(ithread < SIZE(workers%worker))
    2781              : 
    2782              : ! See the spin-unpolarized calc: the device is activated per evaluation.
    2783              : 
    2784              : ! See the spin-unpolarized calc: on the GPU path the whole grid is evaluated
    2785              : ! in a single LibXC call, while the CPU/OpenMP path keeps its per-footprint
    2786              : ! block cap (shrunk so every thread gets a block on small grids).
    2787         6872 : IF (libxc_is_gpu()) THEN
    2788            0 :    bsize = npoints
    2789              : ELSE
    2790         6872 :    bsize = MAX(1, MIN(workers%worker(1)%nb, (npoints + nthreads - 1)/nthreads))
    2791              : END IF
    2792         6872 : nblocks = (npoints + bsize - 1)/bsize
    2793              : 
    2794         6872 : family = workers%family
    2795         6872 : CALL libxc_family_flags(family, is_gga, is_mgga, TRIM(func_name))
    2796              : 
    2797              : ! Density and tau cutoffs are applied by LibXC itself, as in the
    2798              : ! spin-unpolarized case.
    2799              : ASSOCIATE (w => workers%worker(ithread + 1), has_laplace => workers%has_laplace, &
    2800              :            no_exc => workers%no_exc, eps_rho => workers%epsilon_rho, &
    2801              :            eps_tau => workers%epsilon_tau)
    2802         6872 : !$OMP    DO
    2803              :    DO ib = 1, nblocks
    2804       205216 :       IF (libxc_is_gpu()) CALL libxc_worker_resize_cuda(w, workers%family, workers%nspin, npoints)
    2805       205216 :       i0 = (ib - 1)*bsize
    2806       205216 :       nb = MIN(bsize, npoints - i0)
    2807              : 
    2808              :       ! stage this block's inputs in LibXC's layout
    2809    101641356 :       DO i = 1, nb
    2810    101436140 :          ii = i0 + i
    2811    101436140 :          w%rho(1, i) = MAX(rhoa(ii), 0.0_dp)
    2812    101641356 :          w%rho(2, i) = MAX(rhob(ii), 0.0_dp)
    2813              :       END DO
    2814       205216 :       IF (is_gga) THEN
    2815              :          ! CP2K works with gradient norms, LibXC with their contractions.
    2816     46319130 :          DO i = 1, nb
    2817     46222384 :             ii = i0 + i
    2818     46222384 :             w%nda(i) = MAX(norm_drhoa(ii), EPSILON(0.0_dp)*1.e4_dp)
    2819     46222384 :             w%ndb(i) = MAX(norm_drhob(ii), EPSILON(0.0_dp)*1.e4_dp)
    2820     46222384 :             w%nd(i) = MAX(norm_drho(ii), EPSILON(0.0_dp)*1.e4_dp)
    2821     46222384 :             w%sigma(1, i) = w%nda(i)**2
    2822     46222384 :             w%sigma(3, i) = w%ndb(i)**2
    2823     46319130 :             w%sigma(2, i) = 0.5_dp*(w%nd(i)**2 - w%sigma(1, i) - w%sigma(3, i))
    2824              :          END DO
    2825              :       END IF
    2826       205216 :       IF (is_mgga) THEN
    2827     27145288 :          DO i = 1, nb
    2828     27086480 :             ii = i0 + i
    2829     27086480 :             w%lapl(1, i) = laplace_rhoa(ii)
    2830     27086480 :             w%lapl(2, i) = laplace_rhob(ii)
    2831     27086480 :             w%tau(1, i) = MAX(tau_a(ii), 0.0_dp)
    2832     27145288 :             w%tau(2, i) = MAX(tau_b(ii), 0.0_dp)
    2833              :          END DO
    2834              :          ! Apply the same continuous kinetic-density projection per spin channel.
    2835     27145288 :          DO i = 1, nb
    2836     27086480 :             w%tau(1, i) = libxc_c2_project_tau(w%rho(1, i), w%sigma(1, i), tau_a(i0 + i), eps_rho, eps_tau)
    2837     27145288 :             w%tau(2, i) = libxc_c2_project_tau(w%rho(2, i), w%sigma(3, i), tau_b(i0 + i), eps_rho, eps_tau)
    2838              :          END DO
    2839              :       END IF
    2840              : 
    2841              :       ! one LibXC call for the whole block, on the host or the device
    2842       205216 :       CALL libxc_worker_eval(w, workers%family, workers%nspin, grad_deriv, no_exc, nb)
    2843       205216 :       IF (grad_deriv >= 1 .AND. .NOT. no_exc) THEN
    2844     97697286 :          DO i = 1, nb
    2845     97697286 :             CALL libxc_spin_floor_pullback(w, i, grad_deriv, has_laplace, eps_rho)
    2846              :          END DO
    2847              :       END IF
    2848       205216 :       IF (is_mgga .AND. grad_deriv >= 1) THEN
    2849     23463874 :          DO i = 1, nb
    2850              :             CALL libxc_mgga_tau_pullback(w, i, [tau_a(i0 + i), tau_b(i0 + i)], 2, &
    2851     70288538 :                                          grad_deriv, has_laplace, eps_rho, eps_tau)
    2852              :          END DO
    2853              :       END IF
    2854       205216 :       IF (grad_deriv >= 1) THEN
    2855     97697286 :          DO i = 1, nb
    2856    292696982 :             CALL libxc_spin_density_pullback(w, i, [rhoa(i0 + i), rhob(i0 + i)], grad_deriv)
    2857              :          END DO
    2858              :       END IF
    2859              :       ! accumulate; one loop per group of derivatives, selected by the
    2860              :       ! order requested and the family
    2861    101641356 :       DO i = 1, nb
    2862    101436140 :          ii = i0 + i
    2863    101641356 :          e_0(ii) = e_0(ii) + sc*w%exc(i)*(w%rho(1, i) + w%rho(2, i))
    2864              :       END DO
    2865       205216 :       IF (grad_deriv >= 1) THEN
    2866     97697286 :          DO i = 1, nb
    2867     97499848 :             ii = i0 + i
    2868     97499848 :             e_rhoa(ii) = e_rhoa(ii) + sc*w%vrho(1, i)
    2869     97697286 :             e_rhob(ii) = e_rhob(ii) + sc*w%vrho(2, i)
    2870              :          END DO
    2871       197438 :          IF (is_gga) THEN
    2872     42375060 :             DO i = 1, nb
    2873     42286092 :                ii = i0 + i
    2874     42286092 :                e_ndrho(ii) = e_ndrho(ii) + sc*w%vsigma(2, i)*w%nd(i)
    2875              :                e_ndrhoa(ii) = e_ndrhoa(ii) + &
    2876     42286092 :                               sc*(2.0_dp*w%vsigma(1, i) - w%vsigma(2, i))*w%nda(i)
    2877              :                e_ndrhob(ii) = e_ndrhob(ii) + &
    2878     42375060 :                               sc*(2.0_dp*w%vsigma(3, i) - w%vsigma(2, i))*w%ndb(i)
    2879              :             END DO
    2880              :          END IF
    2881       197438 :          IF (is_mgga) THEN
    2882     23463874 :             DO i = 1, nb
    2883     23412332 :                ii = i0 + i
    2884     23412332 :                e_tau_a(ii) = e_tau_a(ii) + sc*w%vtau(1, i)
    2885     23463874 :                e_tau_b(ii) = e_tau_b(ii) + sc*w%vtau(2, i)
    2886              :             END DO
    2887              :          END IF
    2888       197438 :          IF (is_mgga .AND. has_laplace) THEN
    2889      3585088 :             DO i = 1, nb
    2890      3576960 :                ii = i0 + i
    2891      3576960 :                e_laplace_rhoa(ii) = e_laplace_rhoa(ii) + sc*w%vlapl(1, i)
    2892      3585088 :                e_laplace_rhob(ii) = e_laplace_rhob(ii) + sc*w%vlapl(2, i)
    2893              :             END DO
    2894              :          END IF
    2895              :       END IF
    2896       205216 :       IF (grad_deriv >= 2) THEN
    2897      5997916 :          DO i = 1, nb
    2898      5980960 :             ii = i0 + i
    2899      5980960 :             e_rhoa_rhoa(ii) = e_rhoa_rhoa(ii) + sc*w%v2rho2(1, i)
    2900      5980960 :             e_rhoa_rhob(ii) = e_rhoa_rhob(ii) + sc*w%v2rho2(2, i)
    2901      5997916 :             e_rhob_rhob(ii) = e_rhob_rhob(ii) + sc*w%v2rho2(3, i)
    2902              :          END DO
    2903        16956 :          IF (is_gga) THEN
    2904      3296000 :             DO i = 1, nb
    2905      3284736 :                ii = i0 + i
    2906      3284736 :                e_ndrho_rhoa(ii) = e_ndrho_rhoa(ii) + sc*w%v2rhosigma(2, i)*w%nd(i)
    2907      3284736 :                e_ndrho_rhob(ii) = e_ndrho_rhob(ii) + sc*w%v2rhosigma(5, i)*w%nd(i)
    2908              :                e_ndrhoa_rhoa(ii) = e_ndrhoa_rhoa(ii) + &
    2909      3284736 :                                    sc*(2.0_dp*w%v2rhosigma(1, i) - w%v2rhosigma(2, i))*w%nda(i)
    2910              :                e_ndrhoa_rhob(ii) = e_ndrhoa_rhob(ii) + &
    2911      3284736 :                                    sc*(2.0_dp*w%v2rhosigma(4, i) - w%v2rhosigma(5, i))*w%nda(i)
    2912              :                e_ndrhob_rhoa(ii) = e_ndrhob_rhoa(ii) + &
    2913      3284736 :                                    sc*(2.0_dp*w%v2rhosigma(3, i) - w%v2rhosigma(2, i))*w%ndb(i)
    2914              :                e_ndrhob_rhob(ii) = e_ndrhob_rhob(ii) + &
    2915      3284736 :                                    sc*(2.0_dp*w%v2rhosigma(6, i) - w%v2rhosigma(5, i))*w%ndb(i)
    2916              :                e_ndrho_ndrho(ii) = e_ndrho_ndrho(ii) + &
    2917      3284736 :                                    sc*(w%vsigma(2, i) + w%nd(i)**2*w%v2sigma2(4, i))
    2918              :                e_ndrho_ndrhoa(ii) = e_ndrho_ndrhoa(ii) + &
    2919      3284736 :                                     sc*(2.0_dp*w%v2sigma2(2, i) - w%v2sigma2(4, i))*w%nd(i)*w%nda(i)
    2920              :                e_ndrho_ndrhob(ii) = e_ndrho_ndrhob(ii) + &
    2921      3284736 :                                     sc*(2.0_dp*w%v2sigma2(5, i) - w%v2sigma2(4, i))*w%nd(i)*w%ndb(i)
    2922              :                e_ndrhoa_ndrhoa(ii) = e_ndrhoa_ndrhoa(ii) + &
    2923              :                                      sc*(2.0_dp*w%vsigma(1, i) - w%vsigma(2, i) + w%nda(i)**2*( &
    2924      3284736 :                                          4.0_dp*w%v2sigma2(1, i) - 4.0_dp*w%v2sigma2(2, i) + w%v2sigma2(4, i)))
    2925              :                e_ndrhoa_ndrhob(ii) = e_ndrhoa_ndrhob(ii) + &
    2926              :                                      sc*(4.0_dp*w%v2sigma2(3, i) - 2.0_dp*w%v2sigma2(2, i) - &
    2927      3284736 :                                          2.0_dp*w%v2sigma2(5, i) + w%v2sigma2(4, i))*w%nda(i)*w%ndb(i)
    2928              :                e_ndrhob_ndrhob(ii) = e_ndrhob_ndrhob(ii) + &
    2929              :                                      sc*(2.0_dp*w%vsigma(3, i) - w%vsigma(2, i) + w%ndb(i)**2*( &
    2930      3296000 :                                          4.0_dp*w%v2sigma2(6, i) - 4.0_dp*w%v2sigma2(5, i) + w%v2sigma2(4, i)))
    2931              :             END DO
    2932              :          END IF
    2933        16956 :          IF (is_mgga) THEN
    2934       804814 :             DO i = 1, nb
    2935       798824 :                ii = i0 + i
    2936       798824 :                e_rhoa_tau_a(ii) = e_rhoa_tau_a(ii) + sc*w%v2rhotau(1, i)
    2937       798824 :                e_rhoa_tau_b(ii) = e_rhoa_tau_b(ii) + sc*w%v2rhotau(2, i)
    2938       798824 :                e_rhob_tau_a(ii) = e_rhob_tau_a(ii) + sc*w%v2rhotau(3, i)
    2939       798824 :                e_rhob_tau_b(ii) = e_rhob_tau_b(ii) + sc*w%v2rhotau(4, i)
    2940       798824 :                e_ndrho_tau_a(ii) = e_ndrho_tau_a(ii) + sc*w%v2sigmatau(3, i)*w%nd(i)
    2941       798824 :                e_ndrho_tau_b(ii) = e_ndrho_tau_b(ii) + sc*w%v2sigmatau(4, i)*w%nd(i)
    2942              :                e_ndrhoa_tau_a(ii) = e_ndrhoa_tau_a(ii) + &
    2943       798824 :                                     sc*(2.0_dp*w%v2sigmatau(1, i) - w%v2sigmatau(3, i))*w%nda(i)
    2944              :                e_ndrhoa_tau_b(ii) = e_ndrhoa_tau_b(ii) + &
    2945       798824 :                                     sc*(2.0_dp*w%v2sigmatau(2, i) - w%v2sigmatau(4, i))*w%nda(i)
    2946              :                e_ndrhob_tau_a(ii) = e_ndrhob_tau_a(ii) + &
    2947       798824 :                                     sc*(2.0_dp*w%v2sigmatau(5, i) - w%v2sigmatau(3, i))*w%ndb(i)
    2948              :                e_ndrhob_tau_b(ii) = e_ndrhob_tau_b(ii) + &
    2949       798824 :                                     sc*(2.0_dp*w%v2sigmatau(6, i) - w%v2sigmatau(4, i))*w%ndb(i)
    2950       798824 :                e_tau_a_tau_a(ii) = e_tau_a_tau_a(ii) + sc*w%v2tau2(1, i)
    2951       798824 :                e_tau_a_tau_b(ii) = e_tau_a_tau_b(ii) + sc*w%v2tau2(2, i)
    2952       804814 :                e_tau_b_tau_b(ii) = e_tau_b_tau_b(ii) + sc*w%v2tau2(3, i)
    2953              :             END DO
    2954              :          END IF
    2955        16956 :          IF (is_mgga .AND. has_laplace) THEN
    2956       276030 :             DO i = 1, nb
    2957       274752 :                ii = i0 + i
    2958       274752 :                e_rhoa_laplace_rhoa(ii) = e_rhoa_laplace_rhoa(ii) + sc*w%v2rholapl(1, i)
    2959       274752 :                e_rhoa_laplace_rhob(ii) = e_rhoa_laplace_rhob(ii) + sc*w%v2rholapl(2, i)
    2960       274752 :                e_rhob_laplace_rhoa(ii) = e_rhob_laplace_rhoa(ii) + sc*w%v2rholapl(3, i)
    2961       274752 :                e_rhob_laplace_rhob(ii) = e_rhob_laplace_rhob(ii) + sc*w%v2rholapl(4, i)
    2962       274752 :                e_ndrho_laplace_rhoa(ii) = e_ndrho_laplace_rhoa(ii) + sc*w%v2sigmalapl(3, i)*w%nd(i)
    2963       274752 :                e_ndrho_laplace_rhob(ii) = e_ndrho_laplace_rhob(ii) + sc*w%v2sigmalapl(4, i)*w%nd(i)
    2964              :                e_ndrhoa_laplace_rhoa(ii) = e_ndrhoa_laplace_rhoa(ii) + &
    2965       274752 :                                            sc*(2.0_dp*w%v2sigmalapl(1, i) - w%v2sigmalapl(3, i))*w%nda(i)
    2966              :                e_ndrhoa_laplace_rhob(ii) = e_ndrhoa_laplace_rhob(ii) + &
    2967       274752 :                                            sc*(2.0_dp*w%v2sigmalapl(2, i) - w%v2sigmalapl(4, i))*w%nda(i)
    2968              :                e_ndrhob_laplace_rhoa(ii) = e_ndrhob_laplace_rhoa(ii) + &
    2969       274752 :                                            sc*(2.0_dp*w%v2sigmalapl(5, i) - w%v2sigmalapl(3, i))*w%ndb(i)
    2970              :                e_ndrhob_laplace_rhob(ii) = e_ndrhob_laplace_rhob(ii) + &
    2971       274752 :                                            sc*(2.0_dp*w%v2sigmalapl(6, i) - w%v2sigmalapl(4, i))*w%ndb(i)
    2972       274752 :                e_laplace_rhoa_laplace_rhoa(ii) = e_laplace_rhoa_laplace_rhoa(ii) + sc*w%v2lapl2(1, i)
    2973       274752 :                e_laplace_rhoa_laplace_rhob(ii) = e_laplace_rhoa_laplace_rhob(ii) + sc*w%v2lapl2(2, i)
    2974       274752 :                e_laplace_rhob_laplace_rhob(ii) = e_laplace_rhob_laplace_rhob(ii) + sc*w%v2lapl2(3, i)
    2975       274752 :                e_laplace_rhoa_tau_a(ii) = e_laplace_rhoa_tau_a(ii) + sc*w%v2lapltau(1, i)
    2976       274752 :                e_laplace_rhoa_tau_b(ii) = e_laplace_rhoa_tau_b(ii) + sc*w%v2lapltau(2, i)
    2977       274752 :                e_laplace_rhob_tau_a(ii) = e_laplace_rhob_tau_a(ii) + sc*w%v2lapltau(3, i)
    2978       276030 :                e_laplace_rhob_tau_b(ii) = e_laplace_rhob_tau_b(ii) + sc*w%v2lapltau(4, i)
    2979              :             END DO
    2980              :          END IF
    2981              :       END IF
    2982       205216 :       IF (grad_deriv >= 3) THEN
    2983       871468 :          DO i = 1, nb
    2984       869004 :             ii = i0 + i
    2985       869004 :             e_rhoa_rhoa_rhoa(ii) = e_rhoa_rhoa_rhoa(ii) + sc*w%v3rho3(1, i)
    2986       869004 :             e_rhoa_rhoa_rhob(ii) = e_rhoa_rhoa_rhob(ii) + sc*w%v3rho3(2, i)
    2987       869004 :             e_rhoa_rhob_rhob(ii) = e_rhoa_rhob_rhob(ii) + sc*w%v3rho3(3, i)
    2988       871468 :             e_rhob_rhob_rhob(ii) = e_rhob_rhob_rhob(ii) + sc*w%v3rho3(4, i)
    2989              :          END DO
    2990              :       END IF
    2991       205216 :       IF (grad_deriv >= 1 .AND. is_gga) THEN
    2992     42375060 :          DO i = 1, nb
    2993     42286092 :             ii = i0 + i
    2994              :             #:for descs, arr, idx in gamma_only_1
    2995     42375060 :                e_${'_'.join(descs)}$ (ii) = e_${'_'.join(descs)}$ (ii) + sc*w%${arr}$ (${idx}$, i)
    2996              :             #:endfor
    2997              :          END DO
    2998              :       END IF
    2999       205216 :       IF (grad_deriv >= 2 .AND. is_gga) THEN
    3000      3296000 :          DO i = 1, nb
    3001      3284736 :             ii = i0 + i
    3002              :             #:for descs, arr, idx in gamma_only_2
    3003      3296000 :                e_${'_'.join(descs)}$ (ii) = e_${'_'.join(descs)}$ (ii) + sc*w%${arr}$ (${idx}$, i)
    3004              :             #:endfor
    3005              :          END DO
    3006              :       END IF
    3007       205216 :       IF (grad_deriv >= 2 .AND. is_mgga) THEN
    3008       804814 :          DO i = 1, nb
    3009       798824 :             ii = i0 + i
    3010              :             #:for descs, arr, idx in [e for e in mgga_fill_2 if e not in gga_fill_2]
    3011       804814 :                e_${'_'.join(descs)}$ (ii) = e_${'_'.join(descs)}$ (ii) + sc*w%${arr}$ (${idx}$, i)
    3012              :             #:endfor
    3013              :          END DO
    3014              :       END IF
    3015       205216 :       IF (grad_deriv >= 3 .AND. is_mgga) THEN
    3016       140988 :          DO i = 1, nb
    3017       139980 :             ii = i0 + i
    3018              :             #:for descs, arr, idx in mgga_fill_3
    3019       140988 :                e_${'_'.join(descs)}$ (ii) = e_${'_'.join(descs)}$ (ii) + sc*w%${arr}$ (${idx}$, i)
    3020              :             #:endfor
    3021              :          END DO
    3022              :       END IF
    3023       205216 :       IF (grad_deriv >= 3 .AND. is_gga .AND. .NOT. is_mgga) THEN
    3024       365240 :          DO i = 1, nb
    3025       364512 :             ii = i0 + i
    3026              :             #:for descs, arr, idx in gamma_only_3
    3027       365240 :                e_${'_'.join(descs)}$ (ii) = e_${'_'.join(descs)}$ (ii) + sc*w%${arr}$ (${idx}$, i)
    3028              :             #:endfor
    3029              :          END DO
    3030              :       END IF
    3031              :    END DO
    3032              : !$OMP    END DO
    3033              : END ASSOCIATE
    3034              : 
    3035         6872 : END SUBROUTINE libxc_spin_polarized_calc
    3036              : #endif
    3037              : 
    3038       256140 : END MODULE xc_libxc
        

Generated by: LCOV version 2.0-1