LCOV - code coverage report
Current view: top level - src/xc - xc_libxc.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:24d69ee) Lines: 92.2 % 962 887
Test Date: 2026-09-03 07:32:15 Functions: 81.0 % 21 17

            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              : MODULE xc_libxc
      29              :    USE bibliography, ONLY: Lehtola2018, &
      30              :                            Marques2012, &
      31              :                            cite_reference
      32              :    USE input_section_types, ONLY: section_add_keyword, &
      33              :                                   section_add_subsection, &
      34              :                                   section_create, &
      35              :                                   section_release, &
      36              :                                   section_type, &
      37              :                                   section_vals_type, &
      38              :                                   section_vals_val_get
      39              :    USE kinds, ONLY: default_string_length, &
      40              :                     dp
      41              :    USE xc_derivative_set_types, ONLY: xc_derivative_set_type, &
      42              :                                       xc_dset_get_derivative
      43              :    USE xc_derivative_types, ONLY: xc_derivative_get, &
      44              :                                   xc_derivative_type
      45              :    USE xc_rho_cflags_types, ONLY: xc_rho_cflags_type
      46              :    USE xc_rho_set_types, ONLY: xc_rho_set_get, &
      47              :                                xc_rho_set_type
      48              : #if defined (__LIBXC)
      49              :    USE input_keyword_types, ONLY: keyword_create, &
      50              :                                   keyword_release, &
      51              :                                   keyword_type
      52              :    USE iso_c_binding, ONLY: C_SIZE_T, C_INT, C_DOUBLE
      53              :    USE xc_derivative_desc, ONLY: &
      54              :       deriv_rho, deriv_rhoa, deriv_rhob, &
      55              :       deriv_norm_drhoa, deriv_norm_drhob, deriv_norm_drho, deriv_tau_a, deriv_tau_b, deriv_tau, &
      56              :       deriv_laplace_rho, deriv_laplace_rhoa, deriv_laplace_rhob
      57              :    USE xc_libxc_wrap, ONLY: xc_f03_func_t, &
      58              :                             xc_f03_func_init, &
      59              :                             xc_f03_func_end, &
      60              :                             xc_f03_func_info_t, &
      61              :                             xc_f03_functional_get_name, &
      62              :                             xc_f03_func_get_info, &
      63              :                             xc_f03_func_info_get_family, &
      64              :                             xc_f03_func_info_get_kind, &
      65              :                             xc_f03_func_info_get_n_ext_params, &
      66              :                             xc_f03_func_info_get_name, &
      67              :                             xc_f03_available_functional_numbers, &
      68              :                             xc_f03_available_functional_names, &
      69              :                             xc_f03_maximum_name_length, &
      70              :                             xc_f03_number_of_functionals, &
      71              :                             xc_f03_func_info_get_ext_params_name, &
      72              :                             xc_f03_func_info_get_ext_params_description, &
      73              :                             xc_f03_func_info_get_ext_params_default_value, &
      74              :                             xc_f03_gga_exc, &
      75              :                             xc_f03_gga_exc_vxc, &
      76              :                             xc_f03_gga_exc_vxc_fxc, &
      77              :                             xc_f03_gga_fxc, &
      78              :                             xc_f03_gga_vxc, &
      79              :                             xc_f03_gga_vxc_fxc, &
      80              :                             xc_f03_lda, &
      81              :                             xc_f03_lda_exc, &
      82              :                             xc_f03_lda_exc_vxc, &
      83              :                             xc_f03_lda_exc_vxc_fxc, &
      84              :                             xc_f03_lda_fxc, &
      85              :                             xc_f03_lda_kxc, &
      86              :                             xc_f03_lda_vxc, &
      87              :                             xc_f03_mgga, &
      88              :                             xc_f03_mgga_exc, &
      89              :                             xc_f03_mgga_exc_vxc, &
      90              :                             xc_f03_mgga_fxc, &
      91              :                             xc_f03_mgga_vxc, &
      92              :                             xc_f03_mgga_vxc_fxc, &
      93              :                             XC_POLARIZED, &
      94              :                             XC_UNPOLARIZED, &
      95              :                             XC_FAMILY_LDA, &
      96              :                             XC_FAMILY_GGA, &
      97              :                             XC_FAMILY_MGGA, &
      98              :                             XC_FAMILY_HYB_LDA, &
      99              :                             XC_FAMILY_HYB_GGA, &
     100              :                             XC_FAMILY_HYB_MGGA, &
     101              :                             XC_CORRELATION, &
     102              :                             XC_EXCHANGE, &
     103              :                             XC_EXCHANGE_CORRELATION, &
     104              :                             XC_KINETIC, &
     105              :                             xc_libxc_wrap_info_refs, &
     106              :                             xc_libxc_wrap_version, &
     107              :                             xc_libxc_wrap_library_reference, &
     108              :                             xc_libxc_wrap_functional_get_number, &
     109              :                             xc_libxc_wrap_info_needs_laplace, &
     110              :                             xc_libxc_wrap_info_no_exc, &
     111              :                             xc_libxc_wrap_set_thresholds, &
     112              :                             xc_f03_func_set_ext_params, &
     113              :                             xc_libxc_wrap_is_under_development, &
     114              :                             xc_libxc_get_reference_length, &
     115              :                             xc_libxc_check_functional
     116              : #endif
     117              : !$ USE OMP_LIB, ONLY: omp_get_max_threads, &
     118              : !$                    omp_get_num_threads, &
     119              : !$                    omp_get_thread_num
     120              : 
     121              : #include "../base/base_uses.f90"
     122              : 
     123              :    IMPLICIT NONE
     124              :    PRIVATE
     125              : 
     126              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_libxc'
     127              : 
     128              :    PUBLIC :: libxc_spin_unpolarized_info, libxc_spin_unpolarized_eval, &
     129              :              libxc_spin_polarized_info, libxc_spin_polarized_eval, &
     130              :              libxc_version_info, libxc_library_reference, &
     131              :              libxc_get_reference_length, libxc_add_sections, &
     132              :              libxc_check_existence_in_libxc, libxc_release_workers
     133              : 
     134              : #if defined (__LIBXC)
     135              :    ! Number of grid points handed to LibXC in a single call. LibXC amortizes its
     136              :    ! per-call work (argument checks, output initialization and, for functionals
     137              :    ! built by mixing components, a full allocate/free cycle of the component
     138              :    ! buffers) over the points in the call, so evaluating point by point paid that
     139              :    ! cost once per point. Blocking rather than passing the whole grid keeps the
     140              :    ! staging buffers inside the cache; the timing is flat between roughly 128 and
     141              :    ! 2048 points, so the exact value is not critical.
     142              :    INTEGER, PARAMETER, PRIVATE :: libxc_block_size = 512
     143              : 
     144              : ! **************************************************************************************************
     145              : !> \brief One LibXC functional object plus the buffers used to hand it a block of
     146              : !>        grid points. One of these is kept per OpenMP thread so that neither the
     147              : !>        functional object nor the buffers are rebuilt between batches.
     148              : ! **************************************************************************************************
     149              :    TYPE libxc_worker_type
     150              :       TYPE(xc_f03_func_t)                                :: func = xc_f03_func_t()
     151              :       TYPE(xc_f03_func_info_t)                           :: info = xc_f03_func_info_t()
     152              :       LOGICAL                                            :: is_init = .FALSE.
     153              :       ! staging buffers, dimensioned (component, point)
     154              :       REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE        :: rho, sigma, lapl, tau
     155              :       ! the floored gradient norms the spin-polarized chain rule is written in
     156              :       REAL(KIND=dp), DIMENSION(:), ALLOCATABLE           :: nd, nda, ndb
     157              :       REAL(KIND=dp), DIMENSION(:), ALLOCATABLE           :: exc
     158              :       REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE        :: vrho, vsigma, vlapl, vtau
     159              :       REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE        :: v2rho2, v2rhosigma, v2sigma2, &
     160              :                                                             v2rholapl, v2rhotau, v2sigmalapl, &
     161              :                                                             v2sigmatau, v2lapl2, v2lapltau, v2tau2
     162              :       REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE        :: v3rho3
     163              :    END TYPE libxc_worker_type
     164              : 
     165              : ! **************************************************************************************************
     166              : !> \brief All threads' workers for one distinct functional setup, together with
     167              : !>        the key that identifies that setup.
     168              : ! **************************************************************************************************
     169              :    TYPE libxc_worker_set_type
     170              :       INTEGER                                            :: func_id = -1
     171              :       INTEGER                                            :: nspin = -1
     172              :       INTEGER                                            :: family = -1
     173              :       LOGICAL                                            :: has_laplace = .FALSE.
     174              :       LOGICAL                                            :: no_exc = .FALSE.
     175              :       LOGICAL                                            :: has_params = .FALSE.
     176              :       REAL(KIND=dp)                                      :: epsilon_rho = -1.0_dp
     177              :       REAL(KIND=dp)                                      :: epsilon_tau = -1.0_dp
     178              :       REAL(KIND=dp), DIMENSION(:), ALLOCATABLE           :: params
     179              :       CHARACTER(LEN=128), DIMENSION(:), ALLOCATABLE      :: param_names
     180              :       TYPE(libxc_worker_type), DIMENSION(:), ALLOCATABLE :: worker
     181              :    END TYPE libxc_worker_set_type
     182              : 
     183              :    ! Workers are acquired from a serial region only (see libxc_get_workers), so
     184              :    ! the cache itself needs no locking.
     185              :    TYPE(libxc_worker_set_type), DIMENSION(:), ALLOCATABLE, TARGET, PRIVATE, SAVE :: libxc_cache
     186              : 
     187              :    ! Stands in for the derivative arrays a given evaluation does not produce.
     188              :    ! Those arguments still have to be associated with something, but they are
     189              :    ! never read or written; pointing them at the density instead would make an
     190              :    ! output argument alias a read-only input. Grown on demand and kept for the
     191              :    ! run rather than allocated per evaluation, and like the cache above it is
     192              :    ! only ever touched from a serial region.
     193              :    REAL(KIND=dp), DIMENSION(:), ALLOCATABLE, TARGET, PRIVATE, SAVE :: libxc_unused
     194              : #endif
     195              : 
     196              : CONTAINS
     197              : 
     198              : ! **************************************************************************************************
     199              : !> \brief This function checks whether a functional name belongs to LibXC
     200              : !> \param libxc_params (possible) LibXC input section
     201              : !> \return exists whether the functional exists in LibXC
     202              : ! **************************************************************************************************
     203         4266 :    FUNCTION libxc_check_existence_in_libxc(libxc_params) RESULT(exists)
     204              : 
     205              :       TYPE(section_vals_type), POINTER, INTENT(IN)         :: libxc_params
     206              :       LOGICAL                                  :: exists
     207              : 
     208              : #if defined (__LIBXC)
     209              : 
     210         4266 :       exists = xc_libxc_check_functional(libxc_params%section%name)
     211              : #else
     212              :       MARK_USED(libxc_params)
     213              :       exists = .FALSE.
     214              : #endif
     215              : 
     216         4266 :    END FUNCTION libxc_check_existence_in_libxc
     217              : 
     218              : ! **************************************************************************************************
     219              : !> \brief This function returns the maximum length of the reference string for a given LibXC functional
     220              : !> \param libxc_params LibXC input section
     221              : !> \param lsd spin polarized calculation
     222              : !> \return maximum length of the string
     223              : ! **************************************************************************************************
     224           98 :    FUNCTION libxc_get_reference_length(libxc_params, lsd) RESULT(length)
     225              : 
     226              :       TYPE(section_vals_type), POINTER, INTENT(IN)         :: libxc_params
     227              :       LOGICAL, INTENT(IN)                      :: lsd
     228              :       INTEGER                                  :: length
     229              : 
     230              : #if defined (__LIBXC)
     231              :       CHARACTER(len=*), PARAMETER :: routineN = 'libxc_get_reference_length'
     232              : 
     233              :       CHARACTER(LEN=default_string_length)     :: func_name
     234              :       INTEGER                                  :: func_id, handle
     235              :       TYPE(xc_f03_func_t)                      :: xc_func
     236              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     237              : 
     238           98 :       CALL timeset(routineN, handle)
     239              : 
     240           98 :       func_name = libxc_params%section%name
     241              : 
     242           98 :       func_id = xc_libxc_wrap_functional_get_number(func_name)
     243           98 :       IF (lsd) THEN
     244           46 :          CALL xc_f03_func_init(xc_func, func_id, XC_POLARIZED)
     245              :       ELSE
     246           52 :          CALL xc_f03_func_init(xc_func, func_id, XC_UNPOLARIZED)
     247              :       END IF
     248           98 :       xc_info = xc_f03_func_get_info(xc_func)
     249              : 
     250           98 :       length = xc_libxc_get_reference_length(xc_info)
     251              : 
     252           98 :       CALL xc_f03_func_end(xc_func)
     253              : 
     254           98 :       CALL timestop(handle)
     255              : #else
     256              :       MARK_USED(libxc_params)
     257              :       MARK_USED(lsd)
     258              :       length = 0
     259              :       CPABORT("In order to use LibXC you have to download and install it!")
     260              : #endif
     261              : 
     262           98 :    END FUNCTION libxc_get_reference_length
     263              : 
     264              : ! **************************************************************************************************
     265              : !> \brief ...
     266              : !> \param section ...
     267              : ! **************************************************************************************************
     268       108595 :    SUBROUTINE libxc_add_sections(section)
     269              : 
     270              :       TYPE(section_type), POINTER, INTENT(IN) :: section
     271              : 
     272              : #if defined (__LIBXC)
     273              :       CHARACTER(len=*), PARAMETER :: routineN = 'libxc_add_sections'
     274              : 
     275              :       TYPE(section_type), POINTER :: subsection
     276              :       TYPE(keyword_type), POINTER :: keyword
     277              :       INTEGER :: handle, no_func, len_name, ii, func_id, n_param, iparam
     278              :       REAL(KIND=C_DOUBLE) :: default_val
     279              :       CHARACTER(LEN=128) :: func_name, param_name, param_descr, description
     280              :       CHARACTER(LEN=2*default_string_length) :: warning
     281       108595 :       INTEGER(KIND=C_INT), DIMENSION(:), ALLOCATABLE :: func_ids
     282              :       TYPE(xc_f03_func_t)                      :: xc_func
     283              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     284              : 
     285       108595 :       CALL timeset(routineN, handle)
     286              : 
     287       108595 :       CPASSERT(ASSOCIATED(section))
     288       108595 :       NULLIFY (subsection, keyword)
     289              : 
     290       108595 :       no_func = xc_f03_number_of_functionals()
     291       108595 :       len_name = xc_f03_maximum_name_length()
     292              : 
     293       325785 :       ALLOCATE (func_ids(no_func))
     294              : 
     295       108595 :       CALL xc_f03_available_functional_numbers(func_ids)
     296              : 
     297     77428235 :       DO ii = 1, no_func
     298              : 
     299     77319640 :          func_id = func_ids(ii)
     300     77319640 :          IF (ii > 1) THEN
     301     77211045 :             IF (func_id == func_ids(ii - 1)) CYCLE
     302              :          END IF
     303     76233690 :          CALL xc_f03_func_init(xc_func, func_id, XC_UNPOLARIZED)
     304     76233690 :          xc_info = xc_f03_func_get_info(xc_func)
     305              : 
     306     76233690 :          func_name = xc_f03_functional_get_name(func_id)
     307     76233690 :          description = xc_f03_func_info_get_name(xc_info)
     308     76233690 :          n_param = xc_f03_func_info_get_n_ext_params(xc_info)
     309              : 
     310     76233690 :          NULLIFY (subsection)
     311              :          CALL section_create(subsection, __LOCATION__, name=TRIM(func_name), description=TRIM(description), &
     312     76233690 :                              n_keywords=2 + n_param, n_subsections=0, repeats=.FALSE.)
     313              : 
     314     76233690 :          IF (description(1:1) == "_") THEN
     315              :             warning = " This parameter is an internal parameter of the functional. Changing this "// &
     316            0 :                       "parameter effectively changes the functional."
     317              :          ELSE
     318     76233690 :             warning = " "
     319              :          END IF
     320              : 
     321     76233690 :          NULLIFY (keyword)
     322              :          CALL keyword_create(keyword, __LOCATION__, name="_SECTION_PARAMETERS_", &
     323              :                              description="Activates the functional."//TRIM(warning), &
     324     76233690 :                              lone_keyword_l_val=.TRUE., default_l_val=.FALSE.)
     325     76233690 :          CALL section_add_keyword(subsection, keyword)
     326     76233690 :          CALL keyword_release(keyword)
     327              : 
     328              :          CALL keyword_create(keyword, __LOCATION__, name="SCALE", description="Scales this functional", &
     329     76233690 :                              default_r_val=1.0_dp)
     330     76233690 :          CALL section_add_keyword(subsection, keyword)
     331     76233690 :          CALL keyword_release(keyword)
     332              : 
     333    464460815 :          DO iparam = 1, n_param
     334    388227125 :             param_name = xc_f03_func_info_get_ext_params_name(xc_info, iparam - 1)
     335    388227125 :             param_descr = xc_f03_func_info_get_ext_params_description(xc_info, iparam - 1)
     336    388227125 :             default_val = xc_f03_func_info_get_ext_params_default_value(xc_info, iparam - 1)
     337    388227125 :             NULLIFY (keyword)
     338              :             CALL keyword_create(keyword, __LOCATION__, name=TRIM(param_name), &
     339    388227125 :                                 description=TRIM(param_descr), default_r_val=default_val)
     340    388227125 :             CALL section_add_keyword(subsection, keyword)
     341    464460815 :             CALL keyword_release(keyword)
     342              :          END DO
     343              : 
     344     76233690 :          CALL section_add_subsection(section, subsection)
     345     76233690 :          CALL section_release(subsection)
     346              : 
     347     77428235 :          CALL xc_f03_func_end(xc_func)
     348              : 
     349              :       END DO
     350              : 
     351       108595 :       DEALLOCATE (func_ids)
     352              : 
     353       108595 :       CALL timestop(handle)
     354              : #else
     355              :       MARK_USED(section)
     356              : 
     357              : #endif
     358              : 
     359       108595 :    END SUBROUTINE libxc_add_sections
     360              : 
     361              : ! **************************************************************************************************
     362              : !> \brief info about the functional from libxc
     363              : !> \param libxc_params input parameter (functional name, scaling and parameters)
     364              : !> \param reference string with the reference of the actual functional
     365              : !> \param shortform string with the shortform of the functional name
     366              : !> \param needs the components needed by this functional are set to
     367              : !>        true (does not set the unneeded components to false)
     368              : !> \param max_deriv maximum implemented derivative of the xc functional
     369              : !> \param print_warn whether to print warning about development status of a functional
     370              : !> \param func_name_override optional LibXC functional name overriding the section name
     371              : !> \author F. Tran
     372              : ! **************************************************************************************************
     373        13390 :    SUBROUTINE libxc_spin_unpolarized_info(libxc_params, reference, shortform, needs, max_deriv, print_warn, &
     374              :                                           func_name_override)
     375              : 
     376              :       TYPE(section_vals_type), POINTER         :: libxc_params
     377              :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL  :: reference, shortform
     378              :       TYPE(xc_rho_cflags_type), &
     379              :          INTENT(inout), OPTIONAL               :: needs
     380              :       INTEGER, INTENT(out), OPTIONAL           :: max_deriv
     381              :       LOGICAL, INTENT(IN), OPTIONAL            :: print_warn
     382              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL   :: func_name_override
     383              : 
     384              : #if defined (__LIBXC)
     385              :       CHARACTER(LEN=128)                       :: s1, s2
     386              :       CHARACTER(LEN=default_string_length)     :: func_name
     387              :       INTEGER                                  :: func_id
     388              :       REAL(KIND=dp)                            :: func_scale
     389              :       TYPE(xc_f03_func_t)                      :: xc_func
     390              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     391              : 
     392        26692 :       IF (PRESENT(func_name_override)) THEN
     393           88 :          func_name = func_name_override
     394           88 :          func_scale = 1.0_dp
     395              :       ELSE
     396        13302 :          func_name = libxc_params%section%name
     397        13302 :          CALL section_vals_val_get(libxc_params, "scale", r_val=func_scale)
     398              :       END IF
     399              : 
     400        13390 :       CALL cite_reference(Marques2012)
     401        13390 :       CALL cite_reference(Lehtola2018)
     402              : 
     403        13390 :       IF (ABS(func_scale - 1.0_dp) < 1.0e-10_dp) func_scale = 1.0_dp
     404              : 
     405        13390 :       func_id = xc_libxc_wrap_functional_get_number(func_name)
     406        13390 :       CALL xc_f03_func_init(xc_func, func_id, XC_UNPOLARIZED)
     407        13390 :       xc_info = xc_f03_func_get_info(xc_func)
     408              : 
     409        13390 :       s1 = xc_f03_func_info_get_name(xc_info)
     410         9121 :       SELECT CASE (xc_f03_func_info_get_kind(xc_info))
     411         9121 :       CASE (XC_EXCHANGE); WRITE (s2, '(a)') "exchange"
     412         2491 :       CASE (XC_CORRELATION); WRITE (s2, '(a)') "correlation"
     413         1448 :       CASE (XC_EXCHANGE_CORRELATION); WRITE (s2, '(a)') "exchange-correlation"
     414          330 :       CASE (XC_KINETIC); WRITE (s2, '(a)') "kinetic"
     415              :       CASE default
     416        13390 :          CPABORT(TRIM(func_name)//": this XC_KIND is currently not supported.")
     417              :       END SELECT
     418        13390 :       IF (PRESENT(shortform)) THEN
     419           52 :          shortform = TRIM(s1)//' ('//TRIM(s2)//')'
     420              :       END IF
     421        13390 :       IF (PRESENT(reference)) THEN
     422           52 :          CALL xc_libxc_wrap_info_refs(xc_info, XC_UNPOLARIZED, func_scale, reference)
     423              :       END IF
     424        13390 :       IF (PRESENT(needs)) THEN
     425         5880 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
     426              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
     427         5880 :             needs%rho = .TRUE.
     428              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
     429         4504 :             needs%rho = .TRUE.
     430         4504 :             needs%norm_drho = .TRUE.
     431              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     432         2946 :             needs%rho = .TRUE.
     433         2946 :             needs%norm_drho = .TRUE.
     434         2946 :             needs%tau = .TRUE.
     435         2946 :             needs%laplace_rho = xc_libxc_wrap_info_needs_laplace(xc_info)
     436              :          CASE default
     437        13330 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
     438              :          END SELECT
     439              :       END IF
     440        13390 :       IF (PRESENT(max_deriv)) THEN
     441            0 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
     442              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
     443            0 :             max_deriv = 3
     444              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
     445           88 :             max_deriv = 2
     446              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     447            0 :             max_deriv = 2
     448              :          CASE default
     449           88 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
     450              :          END SELECT
     451              :       END IF
     452        13390 :       IF (PRESENT(print_warn)) THEN
     453            0 :          IF (print_warn .AND. xc_libxc_wrap_is_under_development(xc_info)) THEN
     454            0 :             CPWARN(TRIM(func_name)//" is under development. Use with caution.")
     455              :          END IF
     456              :       END IF
     457              : 
     458        13390 :       CALL xc_f03_func_end(xc_func)
     459              : #else
     460              :       MARK_USED(libxc_params)
     461              :       MARK_USED(reference)
     462              :       MARK_USED(shortform)
     463              :       MARK_USED(needs)
     464              :       MARK_USED(max_deriv)
     465              :       MARK_USED(print_warn)
     466              :       MARK_USED(func_name_override)
     467              : 
     468              :       CALL cp_abort(__LOCATION__, "Unknown functional! If you are asking "// &
     469              :                     "for a functional of the LibXC library, "// &
     470              :                     "you have to download and install the library!")
     471              : #endif
     472              : 
     473        13390 :    END SUBROUTINE libxc_spin_unpolarized_info
     474              : 
     475              : ! **************************************************************************************************
     476              : !> \brief info about the functional from libxc
     477              : !> \param libxc_params input parameter (functional name, scaling and parameters)
     478              : !> \param reference string with the reference of the actual functional
     479              : !> \param shortform string with the shortform of the functional name
     480              : !> \param needs the components needed by this functional are set to
     481              : !>        true (does not set the unneeded components to false)
     482              : !> \param max_deriv maximum implemented derivative of the xc functional
     483              : !> \param print_warn whether to print warning about development status of a functional
     484              : !> \param func_name_override optional LibXC functional name overriding the section name
     485              : !> \author F. Tran
     486              : ! **************************************************************************************************
     487         2476 :    SUBROUTINE libxc_spin_polarized_info(libxc_params, reference, shortform, needs, max_deriv, print_warn, &
     488              :                                         func_name_override)
     489              : 
     490              :       TYPE(section_vals_type), POINTER         :: libxc_params
     491              :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL  :: reference, shortform
     492              :       TYPE(xc_rho_cflags_type), &
     493              :          INTENT(inout), OPTIONAL               :: needs
     494              :       INTEGER, INTENT(out), OPTIONAL           :: max_deriv
     495              :       LOGICAL, INTENT(IN), OPTIONAL            :: print_warn
     496              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL   :: func_name_override
     497              : 
     498              : #if defined (__LIBXC)
     499              :       CHARACTER(LEN=128)                       :: s1, s2
     500              :       CHARACTER(LEN=default_string_length)     :: func_name
     501              :       INTEGER                                  :: func_id
     502              :       REAL(KIND=dp)                            :: func_scale
     503              :       TYPE(xc_f03_func_t)                      :: xc_func
     504              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     505              : 
     506         4944 :       IF (PRESENT(func_name_override)) THEN
     507            8 :          func_name = func_name_override
     508            8 :          func_scale = 1.0_dp
     509              :       ELSE
     510         2468 :          func_name = libxc_params%section%name
     511         2468 :          CALL section_vals_val_get(libxc_params, "scale", r_val=func_scale)
     512              :       END IF
     513              : 
     514         2476 :       CALL cite_reference(Marques2012)
     515         2476 :       CALL cite_reference(Lehtola2018)
     516              : 
     517         2476 :       IF (ABS(func_scale - 1.0_dp) < 1.0e-10_dp) func_scale = 1.0_dp
     518              : 
     519         2476 :       func_id = xc_libxc_wrap_functional_get_number(func_name)
     520         2476 :       CALL xc_f03_func_init(xc_func, func_id, XC_POLARIZED)
     521         2476 :       xc_info = xc_f03_func_get_info(xc_func)
     522              : 
     523         2476 :       s1 = xc_f03_func_info_get_name(xc_info)
     524         1158 :       SELECT CASE (xc_f03_func_info_get_kind(xc_info))
     525         1158 :       CASE (XC_EXCHANGE); WRITE (s2, '(a)') "exchange"
     526         1072 :       CASE (XC_CORRELATION); WRITE (s2, '(a)') "correlation"
     527          246 :       CASE (XC_EXCHANGE_CORRELATION); WRITE (s2, '(a)') "exchange-correlation"
     528            0 :       CASE (XC_KINETIC); WRITE (s2, '(a)') "kinetic"
     529              :       CASE default
     530         2476 :          CPABORT(TRIM(func_name)//": this XC_KIND is currently not supported.")
     531              :       END SELECT
     532         2476 :       IF (PRESENT(shortform)) THEN
     533           46 :          shortform = TRIM(s1)//' ('//TRIM(s2)//')'
     534              :       END IF
     535         2476 :       IF (PRESENT(reference)) THEN
     536           46 :          CALL xc_libxc_wrap_info_refs(xc_info, XC_POLARIZED, func_scale, reference)
     537              :       END IF
     538         2476 :       IF (PRESENT(needs)) THEN
     539         1016 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
     540              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
     541         1016 :             needs%rho_spin = .TRUE.
     542              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
     543          262 :             needs%rho_spin = .TRUE.
     544          262 :             needs%norm_drho = .TRUE.
     545          262 :             needs%norm_drho_spin = .TRUE.
     546              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     547         1152 :             needs%rho_spin = .TRUE.
     548         1152 :             needs%norm_drho = .TRUE.
     549         1152 :             needs%norm_drho_spin = .TRUE.
     550         1152 :             needs%tau_spin = .TRUE.
     551         1152 :             needs%laplace_rho_spin = xc_libxc_wrap_info_needs_laplace(xc_info)
     552              :          CASE default
     553         2430 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
     554              :          END SELECT
     555              :       END IF
     556         2476 :       IF (PRESENT(max_deriv)) THEN
     557            0 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
     558              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
     559            0 :             max_deriv = 3
     560              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
     561            8 :             max_deriv = 2
     562              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     563            0 :             max_deriv = 2
     564              :          CASE default
     565            8 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
     566              :          END SELECT
     567              :       END IF
     568         2476 :       IF (PRESENT(print_warn)) THEN
     569            0 :          IF (print_warn .AND. xc_libxc_wrap_is_under_development(xc_info)) THEN
     570            0 :             CPWARN(TRIM(func_name)//" is under development. Use with caution.")
     571              :          END IF
     572              :       END IF
     573              : 
     574         2476 :       CALL xc_f03_func_end(xc_func)
     575              : #else
     576              :       MARK_USED(libxc_params)
     577              :       MARK_USED(reference)
     578              :       MARK_USED(shortform)
     579              :       MARK_USED(needs)
     580              :       MARK_USED(max_deriv)
     581              :       MARK_USED(print_warn)
     582              :       MARK_USED(func_name_override)
     583              : 
     584              :       CALL cp_abort(__LOCATION__, "Unknown functional! If you are "// &
     585              :                     "asking for a functional of the LibXC library, "// &
     586              :                     "you have to download and install the library!")
     587              : #endif
     588              : 
     589         2476 :    END SUBROUTINE libxc_spin_polarized_info
     590              : 
     591              : ! **************************************************************************************************
     592              : !> \brief info about the LibXC version
     593              : !> \param version version string reported by the library at run time
     594              : !> \param compiled_version version of the LibXC headers CP2K was compiled against
     595              : !> \author A. Gloess (agloess)
     596              : ! **************************************************************************************************
     597           63 :    SUBROUTINE libxc_version_info(version, compiled_version)
     598              :       CHARACTER(LEN=*), INTENT(OUT)      :: version ! the string that is output
     599              :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL :: compiled_version
     600              : 
     601              : #if defined (__LIBXC)
     602           63 :       CALL xc_libxc_wrap_version(version, compiled_version)
     603              : #else
     604              :       version = "none"
     605              :       IF (PRESENT(compiled_version)) compiled_version = "none"
     606              :       CPABORT("In order to use libxc you need to download and install it")
     607              : #endif
     608              : 
     609           63 :    END SUBROUTINE libxc_version_info
     610              : 
     611              : ! **************************************************************************************************
     612              : !> \brief Returns the citation LibXC asks for the library itself.
     613              : !> \param reference bibliographic reference
     614              : !> \param doi digital object identifier of that reference
     615              : !> \author S. Lehtola
     616              : ! **************************************************************************************************
     617           63 :    SUBROUTINE libxc_library_reference(reference, doi)
     618              :       CHARACTER(LEN=*), INTENT(OUT)      :: reference, doi
     619              : 
     620              : #if defined (__LIBXC)
     621           63 :       CALL xc_libxc_wrap_library_reference(reference, doi)
     622              : #else
     623              :       reference = "none"
     624              :       doi = "none"
     625              :       CPABORT("In order to use libxc you need to download and install it")
     626              : #endif
     627              : 
     628           63 :    END SUBROUTINE libxc_library_reference
     629              : 
     630              : ! **************************************************************************************************
     631              : !> \brief Reads the external parameters of a LibXC functional from its input section.
     632              : !> \param libxc_params LibXC input section
     633              : !> \param param_names names of the external parameters, as reported by LibXC
     634              : !> \param params values read from the input
     635              : !> \author S. Lehtola
     636              : ! **************************************************************************************************
     637              : #if defined (__LIBXC)
     638        12440 :    SUBROUTINE libxc_read_params(libxc_params, param_names, params)
     639              :       TYPE(section_vals_type), INTENT(IN), POINTER       :: libxc_params
     640              :       CHARACTER(LEN=128), DIMENSION(:), INTENT(IN)       :: param_names
     641              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: params
     642              : 
     643              :       INTEGER                                            :: i
     644              : 
     645        76952 :       DO i = 1, SIZE(param_names)
     646        76952 :          CALL section_vals_val_get(libxc_params, TRIM(param_names(i)), r_val=params(i))
     647              :       END DO
     648              : 
     649        12440 :    END SUBROUTINE libxc_read_params
     650              : 
     651              : ! **************************************************************************************************
     652              : !> \brief Allocates the staging buffers of a single worker.
     653              : !> \param worker the worker
     654              : !> \param family LibXC functional family
     655              : !> \param nspin XC_UNPOLARIZED or XC_POLARIZED
     656              : !> \author S. Lehtola
     657              : !> \note The buffers follow LibXC's own layout, i.e. the leading dimension is the
     658              : !>       number of components of the quantity and the points run along the second
     659              : !>       dimension. They are allocated once per worker and reused for every batch.
     660              : ! **************************************************************************************************
     661          470 :    SUBROUTINE libxc_worker_alloc(worker, family, nspin)
     662              :       TYPE(libxc_worker_type), INTENT(INOUT)             :: worker
     663              :       INTEGER, INTENT(IN)                                :: family, nspin
     664              : 
     665              :       INTEGER                                            :: nb, nl, np, ns
     666              : 
     667          470 :       nb = libxc_block_size
     668              :       ! number of components per point, cf. the LibXC manual
     669          470 :       IF (nspin == XC_POLARIZED) THEN
     670              :          np = 2   ! rho, vrho, lapl, tau, vlapl, vtau
     671              :          ns = 3   ! sigma, vsigma, v2rho2, v2lapl2, v2tau2
     672              :          nl = 4   ! v2rholapl, v2rhotau, v2lapltau, v3rho3
     673              :       ELSE
     674          328 :          np = 1
     675          328 :          ns = 1
     676          328 :          nl = 1
     677              :       END IF
     678              : 
     679          940 :       ALLOCATE (worker%rho(np, nb))
     680          470 :       ALLOCATE (worker%exc(nb))
     681          940 :       ALLOCATE (worker%vrho(np, nb))
     682          940 :       ALLOCATE (worker%v2rho2(ns, nb))
     683          940 :       ALLOCATE (worker%v3rho3(nl, nb))
     684              : 
     685          770 :       SELECT CASE (family)
     686              :       CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA, XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     687          300 :          ALLOCATE (worker%sigma(ns, nb))
     688          300 :          ALLOCATE (worker%vsigma(ns, nb))
     689          300 :          IF (nspin == XC_POLARIZED) THEN
     690           74 :             ALLOCATE (worker%nd(nb), worker%nda(nb), worker%ndb(nb))
     691              :          END IF
     692          826 :          ALLOCATE (worker%v2rhosigma(MERGE(6, 1, nspin == XC_POLARIZED), nb))
     693         1070 :          ALLOCATE (worker%v2sigma2(MERGE(6, 1, nspin == XC_POLARIZED), nb))
     694              :       END SELECT
     695              : 
     696          126 :       SELECT CASE (family)
     697              :       CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
     698          252 :          ALLOCATE (worker%lapl(np, nb))
     699          252 :          ALLOCATE (worker%tau(np, nb))
     700          252 :          ALLOCATE (worker%vlapl(np, nb))
     701          252 :          ALLOCATE (worker%vtau(np, nb))
     702          252 :          ALLOCATE (worker%v2rholapl(nl, nb))
     703          252 :          ALLOCATE (worker%v2rhotau(nl, nb))
     704          346 :          ALLOCATE (worker%v2sigmalapl(MERGE(6, 1, nspin == XC_POLARIZED), nb))
     705          252 :          ALLOCATE (worker%v2sigmatau(MERGE(6, 1, nspin == XC_POLARIZED), nb))
     706          126 :          ALLOCATE (worker%v2lapl2(ns, nb))
     707          252 :          ALLOCATE (worker%v2lapltau(nl, nb))
     708          126 :          ALLOCATE (worker%v2tau2(ns, nb))
     709              :          ! LibXC leaves vlapl untouched for functionals that do not use the
     710              :          ! Laplacian, and CP2K then ignores it; zero it once so it never holds
     711              :          ! uninitialized memory.
     712       146004 :          worker%vlapl = 0.0_dp
     713              :       END SELECT
     714              : 
     715          470 :    END SUBROUTINE libxc_worker_alloc
     716              : 
     717              : ! **************************************************************************************************
     718              : !> \brief Makes sure the placeholder for unproduced derivatives holds npoints values.
     719              : !> \param npoints number of grid points in this evaluation
     720              : !> \author S. Lehtola
     721              : ! **************************************************************************************************
     722        20450 :    SUBROUTINE libxc_reserve_unused(npoints)
     723              :       INTEGER, INTENT(IN)                                :: npoints
     724              : 
     725        20450 :       IF (ALLOCATED(libxc_unused)) THEN
     726        20170 :          IF (SIZE(libxc_unused) >= npoints) RETURN
     727            2 :          DEALLOCATE (libxc_unused)
     728              :       END IF
     729          846 :       ALLOCATE (libxc_unused(npoints))
     730              : 
     731              :    END SUBROUTINE libxc_reserve_unused
     732              : 
     733              : ! **************************************************************************************************
     734              : !> \brief Returns the cache slot holding the per-thread workers for a functional.
     735              : !> \param func_name LibXC functional name
     736              : !> \param nspin XC_UNPOLARIZED or XC_POLARIZED
     737              : !> \param libxc_params LibXC input section, or null when no parameters are to be set
     738              : !> \param epsilon_rho density cutoff
     739              : !> \param epsilon_tau kinetic energy density cutoff
     740              : !> \return index into libxc_cache
     741              : !> \author S. Lehtola
     742              : !> \note Must be called from a serial region: it is the only writer of the cache,
     743              : !>       and keeping it serial is what makes the cache lock-free. The workers it
     744              : !>       returns are then used concurrently, one per thread.
     745              : ! **************************************************************************************************
     746        20450 :    FUNCTION libxc_get_workers(func_name, nspin, libxc_params, epsilon_rho, epsilon_tau) RESULT(idx)
     747              :       CHARACTER(LEN=*), INTENT(IN)                       :: func_name
     748              :       INTEGER, INTENT(IN)                                :: nspin
     749              :       TYPE(section_vals_type), INTENT(IN), POINTER       :: libxc_params
     750              :       REAL(KIND=dp), INTENT(IN)                          :: epsilon_rho, epsilon_tau
     751              :       INTEGER                                            :: idx
     752              : 
     753              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'libxc_get_workers'
     754              : 
     755              :       INTEGER                                            :: func_id, handle, i, ithread, n_params, &
     756              :                                                             nthreads
     757              :       LOGICAL                                            :: has_params
     758        20450 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: params
     759              :       TYPE(libxc_worker_set_type), ALLOCATABLE, &
     760        20450 :          DIMENSION(:)                                    :: tmp_cache
     761              : 
     762        20450 :       CALL timeset(routineN, handle)
     763              : 
     764        20450 :       func_id = xc_libxc_wrap_functional_get_number(func_name)
     765        20450 :       has_params = ASSOCIATED(libxc_params)
     766              : 
     767        20450 :       nthreads = 1
     768        20450 : !$    nthreads = omp_get_max_threads()
     769              : 
     770        20450 :       IF (.NOT. ALLOCATED(libxc_cache)) ALLOCATE (libxc_cache(0))
     771              : 
     772        20450 :       idx = 0
     773        28396 :       DO i = 1, SIZE(libxc_cache)
     774              :          IF (libxc_cache(i)%func_id == func_id .AND. &
     775        27926 :              libxc_cache(i)%nspin == nspin .AND. &
     776          470 :              (libxc_cache(i)%has_params .EQV. has_params)) THEN
     777              :             IF (libxc_cache(i)%epsilon_rho == epsilon_rho .AND. &
     778        19980 :                 libxc_cache(i)%epsilon_tau == epsilon_tau .AND. &
     779              :                 SIZE(libxc_cache(i)%worker) >= nthreads) THEN
     780              :                idx = i
     781              :                EXIT
     782              :             END IF
     783              :          END IF
     784              :       END DO
     785              : 
     786        20450 :       IF (idx == 0) THEN
     787              :          ! Grow the cache by one slot and build the workers for it.
     788          470 :          CALL MOVE_ALLOC(libxc_cache, tmp_cache)
     789         2198 :          ALLOCATE (libxc_cache(SIZE(tmp_cache) + 1))
     790          788 :          DO i = 1, SIZE(tmp_cache)
     791          788 :             CALL libxc_move_worker_set(tmp_cache(i), libxc_cache(i))
     792              :          END DO
     793         1258 :          DEALLOCATE (tmp_cache)
     794          470 :          idx = SIZE(libxc_cache)
     795              : 
     796              :          ASSOCIATE (ws => libxc_cache(idx))
     797          470 :             ws%func_id = func_id
     798          470 :             ws%nspin = nspin
     799          470 :             ws%has_params = has_params
     800          470 :             ws%epsilon_rho = epsilon_rho
     801          470 :             ws%epsilon_tau = epsilon_tau
     802         1880 :             ALLOCATE (ws%worker(nthreads))
     803              : 
     804          940 :             DO ithread = 1, nthreads
     805          470 :                CALL xc_f03_func_init(ws%worker(ithread)%func, func_id, nspin)
     806          470 :                ws%worker(ithread)%info = xc_f03_func_get_info(ws%worker(ithread)%func)
     807          940 :                ws%worker(ithread)%is_init = .TRUE.
     808              :             END DO
     809              : 
     810          470 :             ws%family = xc_f03_func_info_get_family(ws%worker(1)%info)
     811          470 :             ws%has_laplace = xc_libxc_wrap_info_needs_laplace(ws%worker(1)%info)
     812          470 :             ws%no_exc = xc_libxc_wrap_info_no_exc(ws%worker(1)%info)
     813              : 
     814              :             ! Remember the parameter names so that later evaluations can re-read
     815              :             ! the input without another functional object to ask for them.
     816          470 :             n_params = 0
     817          470 :             IF (has_params) n_params = xc_f03_func_info_get_n_ext_params(ws%worker(1)%info)
     818         1312 :             ALLOCATE (ws%params(n_params))
     819         1312 :             ALLOCATE (ws%param_names(n_params))
     820         2366 :             DO i = 1, n_params
     821         2366 :                ws%param_names(i) = xc_f03_func_info_get_ext_params_name(ws%worker(1)%info, i - 1)
     822              :             END DO
     823          470 :             IF (n_params > 0) THEN
     824          372 :                CALL libxc_read_params(libxc_params, ws%param_names, ws%params)
     825          744 :                DO ithread = 1, nthreads
     826          744 :                   CALL xc_f03_func_set_ext_params(ws%worker(ithread)%func, ws%params)
     827              :                END DO
     828              :             END IF
     829              : 
     830         1410 :             DO ithread = 1, nthreads
     831              :                CALL xc_libxc_wrap_set_thresholds(ws%worker(ithread)%func, ws%worker(ithread)%info, &
     832          470 :                                                  epsilon_rho, epsilon_tau)
     833          940 :                CALL libxc_worker_alloc(ws%worker(ithread), ws%family, nspin)
     834              :             END DO
     835              :          END ASSOCIATE
     836              :       ELSE
     837              :          ! Cached slot: the input section may in principle carry different
     838              :          ! parameter values than the ones the workers were last set up with, so
     839              :          ! re-read them and push them through only when they actually changed.
     840              :          ASSOCIATE (ws => libxc_cache(idx))
     841        19980 :             n_params = SIZE(ws%params)
     842        19980 :             IF (n_params > 0) THEN
     843        36204 :                ALLOCATE (params(n_params))
     844        12068 :                CALL libxc_read_params(libxc_params, ws%param_names, params)
     845        74684 :                IF (ANY(params /= ws%params)) THEN
     846            0 :                   ws%params(:) = params(:)
     847            0 :                   DO ithread = 1, SIZE(ws%worker)
     848            0 :                      CALL xc_f03_func_set_ext_params(ws%worker(ithread)%func, ws%params)
     849              :                      ! re-assert the cutoffs: setting parameters runs the
     850              :                      ! functional's own callback, which is free to rebuild the
     851              :                      ! component functionals a mixed functional is made of
     852              :                      CALL xc_libxc_wrap_set_thresholds(ws%worker(ithread)%func, &
     853              :                                                        ws%worker(ithread)%info, &
     854            0 :                                                        ws%epsilon_rho, ws%epsilon_tau)
     855              :                   END DO
     856              :                END IF
     857        12068 :                DEALLOCATE (params)
     858              :             END IF
     859              :          END ASSOCIATE
     860              :       END IF
     861              : 
     862        20450 :       CALL timestop(handle)
     863              : 
     864        20450 :    END FUNCTION libxc_get_workers
     865              : 
     866              : ! **************************************************************************************************
     867              : !> \brief Moves a worker set to a new cache slot without touching LibXC.
     868              : !> \param from source slot, left empty
     869              : !> \param to destination slot
     870              : !> \author S. Lehtola
     871              : !> \note Used when the cache array grows. The LibXC objects are opaque handles, so
     872              : !>       they survive being moved; only the Fortran allocatables need transferring.
     873              : ! **************************************************************************************************
     874          318 :    SUBROUTINE libxc_move_worker_set(from, to)
     875              :       TYPE(libxc_worker_set_type), INTENT(INOUT)         :: from, to
     876              : 
     877          318 :       to%func_id = from%func_id
     878          318 :       to%nspin = from%nspin
     879          318 :       to%family = from%family
     880          318 :       to%has_laplace = from%has_laplace
     881          318 :       to%no_exc = from%no_exc
     882          318 :       to%has_params = from%has_params
     883          318 :       to%epsilon_rho = from%epsilon_rho
     884          318 :       to%epsilon_tau = from%epsilon_tau
     885          318 :       IF (ALLOCATED(from%params)) CALL MOVE_ALLOC(from%params, to%params)
     886          318 :       IF (ALLOCATED(from%param_names)) CALL MOVE_ALLOC(from%param_names, to%param_names)
     887          318 :       IF (ALLOCATED(from%worker)) CALL MOVE_ALLOC(from%worker, to%worker)
     888              : 
     889          318 :    END SUBROUTINE libxc_move_worker_set
     890              : #endif
     891              : 
     892              : ! **************************************************************************************************
     893              : !> \brief Destroys all cached LibXC functional objects.
     894              : !> \author S. Lehtola
     895              : !> \note Call once at the end of a run. The workers are deliberately kept alive
     896              : !>       across SCF steps and across calculations, so nothing else releases them.
     897              : ! **************************************************************************************************
     898        11241 :    SUBROUTINE libxc_release_workers()
     899              : 
     900              : #if defined (__LIBXC)
     901              :       INTEGER                                            :: i, ithread
     902              : 
     903        11241 :       IF (.NOT. ALLOCATED(libxc_cache)) RETURN
     904              : 
     905          750 :       DO i = 1, SIZE(libxc_cache)
     906          470 :          IF (.NOT. ALLOCATED(libxc_cache(i)%worker)) CYCLE
     907         1220 :          DO ithread = 1, SIZE(libxc_cache(i)%worker)
     908          940 :             IF (libxc_cache(i)%worker(ithread)%is_init) THEN
     909          470 :                CALL xc_f03_func_end(libxc_cache(i)%worker(ithread)%func)
     910          470 :                libxc_cache(i)%worker(ithread)%is_init = .FALSE.
     911              :             END IF
     912              :          END DO
     913              :       END DO
     914         1220 :       DEALLOCATE (libxc_cache)
     915          280 :       IF (ALLOCATED(libxc_unused)) DEALLOCATE (libxc_unused)
     916              : #endif
     917              : 
     918              :    END SUBROUTINE libxc_release_workers
     919              : 
     920              : ! **************************************************************************************************
     921              : !> \brief evaluates the functional from libxc
     922              : !> \param rho_set the density where you want to evaluate the functional
     923              : !> \param deriv_set place where to store the functional derivatives (they are
     924              : !>        added to the derivatives)
     925              : !> \param grad_deriv degree of the derivative that should be evaluated;
     926              : !>        all derivatives up to the given degree are evaluated, in a single
     927              : !>        LibXC call per block of grid points
     928              : !> \param libxc_params input parameter (functional name, scaling and parameters)
     929              : !> \param func_name_override optional LibXC functional name overriding the section name
     930              : !> \author F. Tran
     931              : ! **************************************************************************************************
     932        17700 :    SUBROUTINE libxc_spin_unpolarized_eval(rho_set, deriv_set, grad_deriv, libxc_params, func_name_override)
     933              : 
     934              :       TYPE(xc_rho_set_type), INTENT(IN)        :: rho_set
     935              :       TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
     936              :       INTEGER, INTENT(in)                      :: grad_deriv
     937              :       TYPE(section_vals_type), POINTER         :: libxc_params
     938              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL   :: func_name_override
     939              : 
     940              : #if defined (__LIBXC)
     941              :       CHARACTER(len=*), PARAMETER :: routineN = 'libxc_spin_unpolarized_eval'
     942              : 
     943              :       CHARACTER(LEN=default_string_length)     :: func_name
     944              :       INTEGER                                  :: handle, iw, npoints
     945              :       INTEGER, DIMENSION(2, 3)                 :: bo
     946              :       LOGICAL                                  :: has_laplace
     947              :       REAL(KIND=dp)                            :: epsilon_rho, epsilon_tau, func_scale
     948              :       TYPE(libxc_worker_set_type), POINTER     :: workers
     949              :       TYPE(section_vals_type), POINTER         :: no_params
     950        17700 :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: dummy, e_0, e_laplace_rho, &
     951        17700 :                                                                 e_laplace_rho_laplace_rho, e_laplace_rho_tau, e_ndrho, &
     952        17700 :                                                               e_ndrho_laplace_rho, e_ndrho_ndrho, e_ndrho_rho, e_ndrho_tau, e_rho, &
     953        17700 :                                                                 e_rho_laplace_rho, e_rho_rho, e_rho_rho_rho, e_rho_tau, e_tau, &
     954        17700 :                                                                 e_tau_tau, laplace_rho, norm_drho, rho, tau
     955              :       TYPE(xc_derivative_type), POINTER        :: deriv
     956              :       TYPE(xc_f03_func_info_t)                 :: xc_info
     957              : 
     958        17700 :       CALL timeset(routineN, handle)
     959              : 
     960              :       ! Only "everything up to grad_deriv" is supported. Asking for a single
     961              :       ! derivative order in isolation is rejected here rather than further down,
     962              :       ! where it would quietly evaluate nothing at all.
     963        17700 :       IF (grad_deriv < 0) THEN
     964            0 :          CPABORT("Evaluating a single derivative order is not supported.")
     965              :       END IF
     966        17700 :       IF (grad_deriv > 3) THEN
     967            0 :          CPABORT("derivatives larger than 3 not implemented")
     968              :       END IF
     969              : 
     970        17700 :       has_laplace = .FALSE.
     971        17700 :       NULLIFY (dummy)
     972        17700 :       NULLIFY (workers)
     973        17700 :       NULLIFY (rho, norm_drho, laplace_rho, tau)
     974              : 
     975        17700 :       IF (PRESENT(func_name_override)) THEN
     976            0 :          func_name = func_name_override
     977            0 :          func_scale = 1.0_dp
     978              :       ELSE
     979        17700 :          func_name = libxc_params%section%name
     980        17700 :          CALL section_vals_val_get(libxc_params, "scale", r_val=func_scale)
     981              :       END IF
     982              : 
     983        17700 :       IF (ABS(func_scale - 1.0_dp) < 1.0e-10_dp) func_scale = 1.0_dp
     984              : 
     985              :       CALL xc_rho_set_get(rho_set, can_return_null=.TRUE., &
     986              :                           rho=rho, norm_drho=norm_drho, laplace_rho=laplace_rho, &
     987              :                           rho_cutoff=epsilon_rho, tau_cutoff=epsilon_tau, &
     988        17700 :                           tau=tau, local_bounds=bo)
     989              : 
     990        17700 :       npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
     991              : 
     992              :       ! One functional object per thread, kept across calls. The cutoffs are part
     993              :       ! of the worker setup because LibXC does the screening itself.
     994        17700 :       IF (PRESENT(func_name_override)) THEN
     995              :          ! an overriding name carries no input section, so no parameters are set
     996            0 :          NULLIFY (no_params)
     997            0 :          iw = libxc_get_workers(func_name, XC_UNPOLARIZED, no_params, epsilon_rho, epsilon_tau)
     998              :       ELSE
     999        17700 :          iw = libxc_get_workers(func_name, XC_UNPOLARIZED, libxc_params, epsilon_rho, epsilon_tau)
    1000              :       END IF
    1001        17700 :       workers => libxc_cache(iw)
    1002        17700 :       xc_info = workers%worker(1)%info
    1003        17700 :       has_laplace = workers%has_laplace
    1004              : 
    1005              :       ! see libxc_unused: the arguments the requested order does not produce are
    1006              :       ! never touched, but they still have to point somewhere
    1007        17700 :       CALL libxc_reserve_unused(npoints)
    1008        17700 :       dummy(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)) => libxc_unused(1:npoints)
    1009              : 
    1010              :       ! due to assumed shape array usage in next routine
    1011        17700 :       IF (.NOT. ASSOCIATED(norm_drho)) norm_drho => rho
    1012        17700 :       IF (.NOT. ASSOCIATED(tau)) tau => rho
    1013              : 
    1014              :       ! only some MGGA functionals really need the Laplacian,
    1015              :       ! all others can work with rho (read-only) as dummy
    1016        17700 :       IF (.NOT. has_laplace) laplace_rho => rho
    1017              : 
    1018        17700 :       e_0 => dummy
    1019        17700 :       e_rho => dummy
    1020        17700 :       e_ndrho => dummy
    1021        17700 :       e_laplace_rho => dummy
    1022        17700 :       e_tau => dummy
    1023        17700 :       e_rho_rho => dummy
    1024        17700 :       e_ndrho_rho => dummy
    1025        17700 :       e_ndrho_ndrho => dummy
    1026        17700 :       e_rho_laplace_rho => dummy
    1027        17700 :       e_rho_tau => dummy
    1028        17700 :       e_ndrho_laplace_rho => dummy
    1029        17700 :       e_ndrho_tau => dummy
    1030        17700 :       e_laplace_rho_laplace_rho => dummy
    1031        17700 :       e_laplace_rho_tau => dummy
    1032        17700 :       e_tau_tau => dummy
    1033        17700 :       e_rho_rho_rho => dummy
    1034              : 
    1035        17700 :       IF (grad_deriv >= 0) THEN
    1036              :          deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
    1037        17700 :                                          allocate_deriv=.TRUE.)
    1038        17700 :          CALL xc_derivative_get(deriv, deriv_data=e_0)
    1039              :       END IF
    1040        17700 :       IF (grad_deriv >= 1) THEN
    1041        10210 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1042              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1043              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho], &
    1044        10210 :                                             allocate_deriv=.TRUE.)
    1045        10210 :             CALL xc_derivative_get(deriv, deriv_data=e_rho)
    1046              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1047              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho], &
    1048         5126 :                                             allocate_deriv=.TRUE.)
    1049         5126 :             CALL xc_derivative_get(deriv, deriv_data=e_rho)
    1050              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
    1051         5126 :                                             allocate_deriv=.TRUE.)
    1052         5126 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
    1053              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1054              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho], &
    1055         2110 :                                             allocate_deriv=.TRUE.)
    1056         2110 :             CALL xc_derivative_get(deriv, deriv_data=e_rho)
    1057              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
    1058         2110 :                                             allocate_deriv=.TRUE.)
    1059         2110 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
    1060              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau], &
    1061         2110 :                                             allocate_deriv=.TRUE.)
    1062         2110 :             CALL xc_derivative_get(deriv, deriv_data=e_tau)
    1063         2110 :             IF (has_laplace) THEN
    1064              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho], &
    1065          522 :                                                allocate_deriv=.TRUE.)
    1066          522 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rho)
    1067              :             END IF
    1068              :          CASE default
    1069        17446 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1070              :          END SELECT
    1071              :       END IF
    1072        17700 :       IF (grad_deriv >= 2) THEN
    1073         1488 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1074              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1075              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho], &
    1076         1488 :                                             allocate_deriv=.TRUE.)
    1077         1488 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho)
    1078              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1079              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho], &
    1080          606 :                                             allocate_deriv=.TRUE.)
    1081          606 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho)
    1082              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rho], &
    1083          606 :                                             allocate_deriv=.TRUE.)
    1084          606 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rho)
    1085              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho], &
    1086          606 :                                             allocate_deriv=.TRUE.)
    1087          606 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
    1088              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1089              :             ! not implemented ...
    1090              : 
    1091              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho], &
    1092          148 :                                             allocate_deriv=.TRUE.)
    1093          148 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho)
    1094              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rho], &
    1095          148 :                                             allocate_deriv=.TRUE.)
    1096          148 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rho)
    1097              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho], &
    1098          148 :                                             allocate_deriv=.TRUE.)
    1099          148 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
    1100              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_tau], &
    1101          148 :                                             allocate_deriv=.TRUE.)
    1102          148 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_tau)
    1103              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau], &
    1104          148 :                                             allocate_deriv=.TRUE.)
    1105          148 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_tau)
    1106              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_tau], &
    1107          148 :                                             allocate_deriv=.TRUE.)
    1108          148 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_tau)
    1109          148 :             IF (has_laplace) THEN
    1110              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_laplace_rho], &
    1111           62 :                                                allocate_deriv=.TRUE.)
    1112           62 :                CALL xc_derivative_get(deriv, deriv_data=e_rho_laplace_rho)
    1113              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_laplace_rho], &
    1114           62 :                                                allocate_deriv=.TRUE.)
    1115           62 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrho_laplace_rho)
    1116              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_laplace_rho], &
    1117           62 :                                                allocate_deriv=.TRUE.)
    1118           62 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rho_laplace_rho)
    1119              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_tau], &
    1120           62 :                                                allocate_deriv=.TRUE.)
    1121           62 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rho_tau)
    1122              :             END IF
    1123              :          CASE default
    1124         2242 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1125              :          END SELECT
    1126              :       END IF
    1127        17700 :       IF (grad_deriv >= 3) THEN
    1128            0 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1129              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1130              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho, deriv_rho], &
    1131            0 :                                             allocate_deriv=.TRUE.)
    1132            0 :             CALL xc_derivative_get(deriv, deriv_data=e_rho_rho_rho)
    1133              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA, XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1134            0 :             CPABORT("derivatives larger than 2 not implemented")
    1135              :          CASE default
    1136            0 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1137              :          END SELECT
    1138              :       END IF
    1139              : 
    1140              : !$OMP PARALLEL DEFAULT(NONE), &
    1141              : !$OMP SHARED(rho,norm_drho,laplace_rho,tau,e_0,e_rho,e_ndrho,e_laplace_rho),&
    1142              : !$OMP SHARED(e_tau,e_rho_rho,e_ndrho_rho,e_ndrho_ndrho,e_rho_laplace_rho),&
    1143              : !$OMP SHARED(e_rho_tau,e_ndrho_laplace_rho,e_ndrho_tau,e_laplace_rho_laplace_rho),&
    1144              : !$OMP SHARED(e_laplace_rho_tau,e_tau_tau,e_rho_rho_rho),&
    1145              : !$OMP SHARED(grad_deriv,npoints),&
    1146        17700 : !$OMP SHARED(func_name,func_scale,workers)
    1147              : 
    1148              :       CALL libxc_spin_unpolarized_calc(rho=rho, norm_drho=norm_drho, &
    1149              :                                        laplace_rho=laplace_rho, tau=tau, &
    1150              :                                        e_0=e_0, e_rho=e_rho, e_ndrho=e_ndrho, e_laplace_rho=e_laplace_rho, &
    1151              :                                        e_tau=e_tau, e_rho_rho=e_rho_rho, e_ndrho_rho=e_ndrho_rho, &
    1152              :                                        e_ndrho_ndrho=e_ndrho_ndrho, e_rho_laplace_rho=e_rho_laplace_rho, &
    1153              :                                        e_rho_tau=e_rho_tau, e_ndrho_laplace_rho=e_ndrho_laplace_rho, &
    1154              :                                        e_ndrho_tau=e_ndrho_tau, e_laplace_rho_laplace_rho=e_laplace_rho_laplace_rho, &
    1155              :                                        e_laplace_rho_tau=e_laplace_rho_tau, e_tau_tau=e_tau_tau, &
    1156              :                                        e_rho_rho_rho=e_rho_rho_rho, &
    1157              :                                        grad_deriv=grad_deriv, npoints=npoints, &
    1158              :                                        func_name=func_name, sc=func_scale, workers=workers)
    1159              : 
    1160              : !$OMP END PARALLEL
    1161              : 
    1162        17700 :       NULLIFY (dummy)
    1163        17700 :       NULLIFY (workers)
    1164              : 
    1165        17700 :       CALL timestop(handle)
    1166              : #else
    1167              :       MARK_USED(rho_set)
    1168              :       MARK_USED(deriv_set)
    1169              :       MARK_USED(grad_deriv)
    1170              :       MARK_USED(libxc_params)
    1171              :       MARK_USED(func_name_override)
    1172              :       CALL cp_abort(__LOCATION__, "Unknown functional! If you are asking "// &
    1173              :                     "for a functional of the LibXC library, "// &
    1174              :                     "you have to download and install the library!")
    1175              : #endif
    1176        17700 :    END SUBROUTINE libxc_spin_unpolarized_eval
    1177              : 
    1178              : ! **************************************************************************************************
    1179              : !> \brief evaluates the functional from libxc
    1180              : !> \param rho_set the density where you want to evaluate the functional
    1181              : !> \param deriv_set place where to store the functional derivatives (they are
    1182              : !>        added to the derivatives)
    1183              : !> \param grad_deriv degree of the derivative that should be evaluated;
    1184              : !>        all derivatives up to the given degree are evaluated, in a single
    1185              : !>        LibXC call per block of grid points
    1186              : !> \param libxc_params input parameter (functional name, scaling and parameters)
    1187              : !> \param func_name_override optional LibXC functional name overriding the section name
    1188              : !> \author F. Tran
    1189              : ! **************************************************************************************************
    1190         2750 :    SUBROUTINE libxc_spin_polarized_eval(rho_set, deriv_set, grad_deriv, libxc_params, func_name_override)
    1191              : 
    1192              :       TYPE(xc_rho_set_type), INTENT(IN)        :: rho_set
    1193              :       TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
    1194              :       INTEGER, INTENT(in)                      :: grad_deriv
    1195              :       TYPE(section_vals_type), POINTER         :: libxc_params
    1196              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL   :: func_name_override
    1197              : 
    1198              : #if defined (__LIBXC)
    1199              :       CHARACTER(len=*), PARAMETER :: routineN = 'libxc_spin_polarized_eval'
    1200              : 
    1201              :       CHARACTER(LEN=default_string_length)     :: func_name
    1202              :       INTEGER                                  :: handle, iw, npoints
    1203              :       INTEGER, DIMENSION(2, 3)                 :: bo
    1204              :       LOGICAL                                  :: has_laplace
    1205              :       REAL(KIND=dp)                            :: epsilon_rho, epsilon_tau, func_scale
    1206              :       TYPE(libxc_worker_set_type), POINTER     :: workers
    1207              :       TYPE(section_vals_type), POINTER         :: no_params
    1208         2750 :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: dummy, e_0, e_laplace_rhoa, &
    1209         2750 :                                                                 e_laplace_rhoa_laplace_rhoa, e_laplace_rhoa_laplace_rhob, &
    1210         2750 :                                                                 e_laplace_rhoa_tau_a, e_laplace_rhoa_tau_b, e_laplace_rhob, &
    1211         2750 :                                                                 e_laplace_rhob_laplace_rhob, e_laplace_rhob_tau_a, &
    1212         2750 :                                                                 e_laplace_rhob_tau_b, e_ndrho, e_ndrho_laplace_rhoa, &
    1213         2750 :                                                               e_ndrho_laplace_rhob, e_ndrho_ndrho, e_ndrho_ndrhoa, e_ndrho_ndrhob, &
    1214         2750 :                                                                e_ndrho_rhoa, e_ndrho_rhob, e_ndrho_tau_a, e_ndrho_tau_b, e_ndrhoa, &
    1215         2750 :                                                                 e_ndrhoa_laplace_rhoa, e_ndrhoa_laplace_rhob, e_ndrhoa_ndrhoa, &
    1216         2750 :                                                                 e_ndrhoa_ndrhob, e_ndrhoa_rhoa, e_ndrhoa_rhob, e_ndrhoa_tau_a, &
    1217         2750 :                                                                 e_ndrhoa_tau_b, e_ndrhob
    1218         2750 :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: e_ndrhob_laplace_rhoa, &
    1219         2750 :                                                              e_ndrhob_laplace_rhob, e_ndrhob_ndrhob, e_ndrhob_rhoa, e_ndrhob_rhob, &
    1220         2750 :                                                                 e_ndrhob_tau_a, e_ndrhob_tau_b, e_rhoa, e_rhoa_laplace_rhoa, &
    1221         2750 :                                                              e_rhoa_laplace_rhob, e_rhoa_rhoa, e_rhoa_rhoa_rhoa, e_rhoa_rhoa_rhob, &
    1222         2750 :                                                                 e_rhoa_rhob, e_rhoa_rhob_rhob, e_rhoa_tau_a, e_rhoa_tau_b, e_rhob, &
    1223         2750 :                                                                 e_rhob_laplace_rhoa, e_rhob_laplace_rhob, e_rhob_rhob, &
    1224         2750 :                                                              e_rhob_rhob_rhob, e_rhob_tau_a, e_rhob_tau_b, e_tau_a, e_tau_a_tau_a, &
    1225         2750 :                                                                 e_tau_a_tau_b, e_tau_b, e_tau_b_tau_b, laplace_rhoa, laplace_rhob, &
    1226         2750 :                                                                 norm_drho, norm_drhoa, norm_drhob, rhoa, rhob, tau_a, tau_b
    1227              :       TYPE(xc_derivative_type), POINTER        :: deriv
    1228              :       TYPE(xc_f03_func_info_t)                 :: xc_info
    1229              : 
    1230         2750 :       CALL timeset(routineN, handle)
    1231              : 
    1232              :       ! Only "everything up to grad_deriv" is supported. Asking for a single
    1233              :       ! derivative order in isolation is rejected here rather than further down,
    1234              :       ! where it would quietly evaluate nothing at all.
    1235         2750 :       IF (grad_deriv < 0) THEN
    1236            0 :          CPABORT("Evaluating a single derivative order is not supported.")
    1237              :       END IF
    1238         2750 :       IF (grad_deriv > 3) THEN
    1239            0 :          CPABORT("derivatives larger than 3 not implemented")
    1240              :       END IF
    1241              : 
    1242         2750 :       NULLIFY (dummy)
    1243         2750 :       NULLIFY (workers)
    1244         2750 :       NULLIFY (rhoa, rhob, norm_drho, norm_drhoa, norm_drhob, laplace_rhoa, &
    1245         2750 :                laplace_rhob, tau_a, tau_b)
    1246              : 
    1247         2750 :       IF (PRESENT(func_name_override)) THEN
    1248            0 :          func_name = func_name_override
    1249            0 :          func_scale = 1.0_dp
    1250              :       ELSE
    1251         2750 :          func_name = libxc_params%section%name
    1252         2750 :          CALL section_vals_val_get(libxc_params, "scale", r_val=func_scale)
    1253              :       END IF
    1254              : 
    1255         2750 :       IF (ABS(func_scale - 1.0_dp) < 1.0e-10_dp) func_scale = 1.0_dp
    1256              : 
    1257              :       CALL xc_rho_set_get(rho_set, can_return_null=.TRUE., &
    1258              :                           rhoa=rhoa, rhob=rhob, norm_drho=norm_drho, &
    1259              :                           norm_drhoa=norm_drhoa, norm_drhob=norm_drhob, &
    1260              :                           laplace_rhoa=laplace_rhoa, laplace_rhob=laplace_rhob, &
    1261              :                           rho_cutoff=epsilon_rho, tau_cutoff=epsilon_tau, &
    1262         2750 :                           tau_a=tau_a, tau_b=tau_b, local_bounds=bo)
    1263              : 
    1264         2750 :       npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
    1265              : 
    1266              :       ! One functional object per thread, kept across calls. The cutoffs are part
    1267              :       ! of the worker setup because LibXC does the screening itself.
    1268         2750 :       IF (PRESENT(func_name_override)) THEN
    1269              :          ! an overriding name carries no input section, so no parameters are set
    1270            0 :          NULLIFY (no_params)
    1271            0 :          iw = libxc_get_workers(func_name, XC_POLARIZED, no_params, epsilon_rho, epsilon_tau)
    1272              :       ELSE
    1273         2750 :          iw = libxc_get_workers(func_name, XC_POLARIZED, libxc_params, epsilon_rho, epsilon_tau)
    1274              :       END IF
    1275         2750 :       workers => libxc_cache(iw)
    1276         2750 :       xc_info = workers%worker(1)%info
    1277         2750 :       has_laplace = workers%has_laplace
    1278              : 
    1279              :       ! see libxc_unused: the arguments the requested order does not produce are
    1280              :       ! never touched, but they still have to point somewhere
    1281         2750 :       CALL libxc_reserve_unused(npoints)
    1282         2750 :       dummy(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)) => libxc_unused(1:npoints)
    1283              : 
    1284              :       ! due to assumed shape array usage in next routine
    1285         2750 :       IF (.NOT. ASSOCIATED(norm_drho)) norm_drho => rhoa
    1286         2750 :       IF (.NOT. ASSOCIATED(norm_drhoa)) norm_drhoa => rhoa
    1287         2750 :       IF (.NOT. ASSOCIATED(norm_drhob)) norm_drhob => rhoa
    1288         2750 :       IF (.NOT. ASSOCIATED(tau_a)) tau_a => rhoa
    1289         2750 :       IF (.NOT. ASSOCIATED(tau_b)) tau_b => rhoa
    1290              : 
    1291              :       ! only some MGGA functionals really need the Laplacian,
    1292              :       ! all others can work with rhoa (read-only) as dummy
    1293         2750 :       IF (.NOT. has_laplace) laplace_rhoa => rhoa
    1294         2562 :       IF (.NOT. has_laplace) laplace_rhob => rhoa
    1295              : 
    1296         2750 :       e_0 => dummy
    1297         2750 :       e_rhoa => dummy
    1298         2750 :       e_rhob => dummy
    1299         2750 :       e_ndrho => dummy
    1300         2750 :       e_ndrhoa => dummy
    1301         2750 :       e_ndrhob => dummy
    1302         2750 :       e_laplace_rhoa => dummy
    1303         2750 :       e_laplace_rhob => dummy
    1304         2750 :       e_tau_a => dummy
    1305         2750 :       e_tau_b => dummy
    1306         2750 :       e_rhoa_rhoa => dummy
    1307         2750 :       e_rhoa_rhob => dummy
    1308         2750 :       e_rhob_rhob => dummy
    1309         2750 :       e_ndrho_rhoa => dummy
    1310         2750 :       e_ndrho_rhob => dummy
    1311         2750 :       e_ndrhoa_rhoa => dummy
    1312         2750 :       e_ndrhoa_rhob => dummy
    1313         2750 :       e_ndrhob_rhoa => dummy
    1314         2750 :       e_ndrhob_rhob => dummy
    1315         2750 :       e_ndrho_ndrho => dummy
    1316         2750 :       e_ndrho_ndrhoa => dummy
    1317         2750 :       e_ndrho_ndrhob => dummy
    1318         2750 :       e_ndrhoa_ndrhoa => dummy
    1319         2750 :       e_ndrhoa_ndrhob => dummy
    1320         2750 :       e_ndrhob_ndrhob => dummy
    1321         2750 :       e_rhoa_laplace_rhoa => dummy
    1322         2750 :       e_rhoa_laplace_rhob => dummy
    1323         2750 :       e_rhob_laplace_rhoa => dummy
    1324         2750 :       e_rhob_laplace_rhob => dummy
    1325         2750 :       e_rhoa_tau_a => dummy
    1326         2750 :       e_rhoa_tau_b => dummy
    1327         2750 :       e_rhob_tau_a => dummy
    1328         2750 :       e_rhob_tau_b => dummy
    1329         2750 :       e_ndrho_laplace_rhoa => dummy
    1330         2750 :       e_ndrho_laplace_rhob => dummy
    1331         2750 :       e_ndrhoa_laplace_rhoa => dummy
    1332         2750 :       e_ndrhoa_laplace_rhob => dummy
    1333         2750 :       e_ndrhob_laplace_rhoa => dummy
    1334         2750 :       e_ndrhob_laplace_rhob => dummy
    1335         2750 :       e_ndrho_tau_a => dummy
    1336         2750 :       e_ndrho_tau_b => dummy
    1337         2750 :       e_ndrhoa_tau_a => dummy
    1338         2750 :       e_ndrhoa_tau_b => dummy
    1339         2750 :       e_ndrhob_tau_a => dummy
    1340         2750 :       e_ndrhob_tau_b => dummy
    1341         2750 :       e_laplace_rhoa_laplace_rhoa => dummy
    1342         2750 :       e_laplace_rhoa_laplace_rhob => dummy
    1343         2750 :       e_laplace_rhob_laplace_rhob => dummy
    1344         2750 :       e_laplace_rhoa_tau_a => dummy
    1345         2750 :       e_laplace_rhoa_tau_b => dummy
    1346         2750 :       e_laplace_rhob_tau_a => dummy
    1347         2750 :       e_laplace_rhob_tau_b => dummy
    1348         2750 :       e_tau_a_tau_a => dummy
    1349         2750 :       e_tau_a_tau_b => dummy
    1350         2750 :       e_tau_b_tau_b => dummy
    1351         2750 :       e_rhoa_rhoa_rhoa => dummy
    1352         2750 :       e_rhoa_rhoa_rhob => dummy
    1353         2750 :       e_rhoa_rhob_rhob => dummy
    1354         2750 :       e_rhob_rhob_rhob => dummy
    1355              : 
    1356         2750 :       IF (grad_deriv >= 0) THEN
    1357              :          deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
    1358         2750 :                                          allocate_deriv=.TRUE.)
    1359         2750 :          CALL xc_derivative_get(deriv, deriv_data=e_0)
    1360              :       END IF
    1361         2750 :       IF (grad_deriv >= 1) THEN
    1362         1376 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1363              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1364              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa], &
    1365         1376 :                                             allocate_deriv=.TRUE.)
    1366         1376 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa)
    1367              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob], &
    1368         1376 :                                             allocate_deriv=.TRUE.)
    1369         1376 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob)
    1370              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1371              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa], &
    1372          386 :                                             allocate_deriv=.TRUE.)
    1373          386 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa)
    1374              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob], &
    1375          386 :                                             allocate_deriv=.TRUE.)
    1376          386 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob)
    1377              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
    1378          386 :                                             allocate_deriv=.TRUE.)
    1379          386 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
    1380              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa], &
    1381          386 :                                             allocate_deriv=.TRUE.)
    1382          386 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa)
    1383              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob], &
    1384          386 :                                             allocate_deriv=.TRUE.)
    1385          386 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob)
    1386              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1387              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa], &
    1388          942 :                                             allocate_deriv=.TRUE.)
    1389          942 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa)
    1390              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob], &
    1391          942 :                                             allocate_deriv=.TRUE.)
    1392          942 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob)
    1393              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
    1394          942 :                                             allocate_deriv=.TRUE.)
    1395          942 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
    1396              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa], &
    1397          942 :                                             allocate_deriv=.TRUE.)
    1398          942 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa)
    1399              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob], &
    1400          942 :                                             allocate_deriv=.TRUE.)
    1401          942 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob)
    1402              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_a], &
    1403          942 :                                             allocate_deriv=.TRUE.)
    1404          942 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_a)
    1405              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_b], &
    1406          942 :                                             allocate_deriv=.TRUE.)
    1407          942 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_b)
    1408          942 :             IF (has_laplace) THEN
    1409              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa], &
    1410          180 :                                                allocate_deriv=.TRUE.)
    1411          180 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa)
    1412              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob], &
    1413          180 :                                                allocate_deriv=.TRUE.)
    1414          180 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhob)
    1415              :             END IF
    1416              :          CASE default
    1417         2704 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1418              :          END SELECT
    1419              :       END IF
    1420         2750 :       IF (grad_deriv >= 2) THEN
    1421           38 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1422              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1423              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa], &
    1424           38 :                                             allocate_deriv=.TRUE.)
    1425           38 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa)
    1426              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob], &
    1427           38 :                                             allocate_deriv=.TRUE.)
    1428           38 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhob)
    1429              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob], &
    1430           38 :                                             allocate_deriv=.TRUE.)
    1431           38 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_rhob)
    1432              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1433              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa], &
    1434           34 :                                             allocate_deriv=.TRUE.)
    1435           34 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa)
    1436              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob], &
    1437           34 :                                             allocate_deriv=.TRUE.)
    1438           34 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhob)
    1439              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob], &
    1440           34 :                                             allocate_deriv=.TRUE.)
    1441           34 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_rhob)
    1442              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa], &
    1443           34 :                                             allocate_deriv=.TRUE.)
    1444           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rhoa)
    1445              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob], &
    1446           34 :                                             allocate_deriv=.TRUE.)
    1447           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rhob)
    1448              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa], &
    1449           34 :                                             allocate_deriv=.TRUE.)
    1450           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_rhoa)
    1451              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob], &
    1452           34 :                                             allocate_deriv=.TRUE.)
    1453           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_rhob)
    1454              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhoa], &
    1455           34 :                                             allocate_deriv=.TRUE.)
    1456           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_rhoa)
    1457              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhob], &
    1458           34 :                                             allocate_deriv=.TRUE.)
    1459           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_rhob)
    1460              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho], &
    1461           34 :                                             allocate_deriv=.TRUE.)
    1462           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
    1463              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa], &
    1464           34 :                                             allocate_deriv=.TRUE.)
    1465           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrhoa)
    1466              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob], &
    1467           34 :                                             allocate_deriv=.TRUE.)
    1468           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrhob)
    1469              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa], &
    1470           34 :                                             allocate_deriv=.TRUE.)
    1471           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_ndrhoa)
    1472              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob], &
    1473           34 :                                             allocate_deriv=.TRUE.)
    1474           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_ndrhob)
    1475              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhob], &
    1476           34 :                                             allocate_deriv=.TRUE.)
    1477           34 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_ndrhob)
    1478              :          CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1479              : 
    1480              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa], &
    1481           14 :                                             allocate_deriv=.TRUE.)
    1482           14 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa)
    1483              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob], &
    1484           14 :                                             allocate_deriv=.TRUE.)
    1485           14 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhob)
    1486              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob], &
    1487           14 :                                             allocate_deriv=.TRUE.)
    1488           14 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_rhob)
    1489              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa], &
    1490           14 :                                             allocate_deriv=.TRUE.)
    1491           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rhoa)
    1492              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob], &
    1493           14 :                                             allocate_deriv=.TRUE.)
    1494           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_rhob)
    1495              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa], &
    1496           14 :                                             allocate_deriv=.TRUE.)
    1497           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_rhoa)
    1498              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob], &
    1499           14 :                                             allocate_deriv=.TRUE.)
    1500           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_rhob)
    1501              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhoa], &
    1502           14 :                                             allocate_deriv=.TRUE.)
    1503           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_rhoa)
    1504              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhob], &
    1505           14 :                                             allocate_deriv=.TRUE.)
    1506           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_rhob)
    1507              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho], &
    1508           14 :                                             allocate_deriv=.TRUE.)
    1509           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrho)
    1510              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa], &
    1511           14 :                                             allocate_deriv=.TRUE.)
    1512           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrhoa)
    1513              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob], &
    1514           14 :                                             allocate_deriv=.TRUE.)
    1515           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_ndrhob)
    1516              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa], &
    1517           14 :                                             allocate_deriv=.TRUE.)
    1518           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_ndrhoa)
    1519              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob], &
    1520           14 :                                             allocate_deriv=.TRUE.)
    1521           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_ndrhob)
    1522              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhob], &
    1523           14 :                                             allocate_deriv=.TRUE.)
    1524           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_ndrhob)
    1525              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_a], &
    1526           14 :                                             allocate_deriv=.TRUE.)
    1527           14 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_tau_a)
    1528              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_b], &
    1529           14 :                                             allocate_deriv=.TRUE.)
    1530           14 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_tau_b)
    1531              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_tau_a], &
    1532           14 :                                             allocate_deriv=.TRUE.)
    1533           14 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_tau_a)
    1534              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_tau_b], &
    1535           14 :                                             allocate_deriv=.TRUE.)
    1536           14 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_tau_b)
    1537              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_a], &
    1538           14 :                                             allocate_deriv=.TRUE.)
    1539           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_tau_a)
    1540              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_b], &
    1541           14 :                                             allocate_deriv=.TRUE.)
    1542           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrho_tau_b)
    1543              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_a], &
    1544           14 :                                             allocate_deriv=.TRUE.)
    1545           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_tau_a)
    1546              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_b], &
    1547           14 :                                             allocate_deriv=.TRUE.)
    1548           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_tau_b)
    1549              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_tau_a], &
    1550           14 :                                             allocate_deriv=.TRUE.)
    1551           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_tau_a)
    1552              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_tau_b], &
    1553           14 :                                             allocate_deriv=.TRUE.)
    1554           14 :             CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_tau_b)
    1555              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_a], &
    1556           14 :                                             allocate_deriv=.TRUE.)
    1557           14 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_a_tau_a)
    1558              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_b], &
    1559           14 :                                             allocate_deriv=.TRUE.)
    1560           14 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_a_tau_b)
    1561              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_tau_b], &
    1562           14 :                                             allocate_deriv=.TRUE.)
    1563           14 :             CALL xc_derivative_get(deriv, deriv_data=e_tau_b_tau_b)
    1564           14 :             IF (has_laplace) THEN
    1565              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhoa], &
    1566            6 :                                                allocate_deriv=.TRUE.)
    1567            6 :                CALL xc_derivative_get(deriv, deriv_data=e_rhoa_laplace_rhoa)
    1568              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhob], &
    1569            6 :                                                allocate_deriv=.TRUE.)
    1570            6 :                CALL xc_derivative_get(deriv, deriv_data=e_rhoa_laplace_rhob)
    1571              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_laplace_rhoa], &
    1572            6 :                                                allocate_deriv=.TRUE.)
    1573            6 :                CALL xc_derivative_get(deriv, deriv_data=e_rhob_laplace_rhoa)
    1574              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_laplace_rhob], &
    1575            6 :                                                allocate_deriv=.TRUE.)
    1576            6 :                CALL xc_derivative_get(deriv, deriv_data=e_rhob_laplace_rhob)
    1577              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_laplace_rhoa], &
    1578            6 :                                                allocate_deriv=.TRUE.)
    1579            6 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrho_laplace_rhoa)
    1580              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_laplace_rhob], &
    1581            6 :                                                allocate_deriv=.TRUE.)
    1582            6 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrho_laplace_rhob)
    1583              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_laplace_rhoa], &
    1584            6 :                                                allocate_deriv=.TRUE.)
    1585            6 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_laplace_rhoa)
    1586              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_laplace_rhob], &
    1587            6 :                                                allocate_deriv=.TRUE.)
    1588            6 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa_laplace_rhob)
    1589              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_laplace_rhoa], &
    1590            6 :                                                allocate_deriv=.TRUE.)
    1591            6 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_laplace_rhoa)
    1592              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_laplace_rhob], &
    1593            6 :                                                allocate_deriv=.TRUE.)
    1594            6 :                CALL xc_derivative_get(deriv, deriv_data=e_ndrhob_laplace_rhob)
    1595              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_laplace_rhoa], &
    1596            6 :                                                allocate_deriv=.TRUE.)
    1597            6 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa_laplace_rhoa)
    1598              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_laplace_rhob], &
    1599            6 :                                                allocate_deriv=.TRUE.)
    1600            6 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa_laplace_rhob)
    1601              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_laplace_rhob], &
    1602            6 :                                                allocate_deriv=.TRUE.)
    1603            6 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhob_laplace_rhob)
    1604              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_a], &
    1605            6 :                                                allocate_deriv=.TRUE.)
    1606            6 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa_tau_a)
    1607              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_b], &
    1608            6 :                                                allocate_deriv=.TRUE.)
    1609            6 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa_tau_b)
    1610              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_tau_a], &
    1611            6 :                                                allocate_deriv=.TRUE.)
    1612            6 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhob_tau_a)
    1613              :                deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_tau_b], &
    1614            6 :                                                allocate_deriv=.TRUE.)
    1615            6 :                CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhob_tau_b)
    1616              :             END IF
    1617              :          CASE default
    1618           86 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1619              :          END SELECT
    1620              :       END IF
    1621         2750 :       IF (grad_deriv >= 3) THEN
    1622            0 :          SELECT CASE (xc_f03_func_info_get_family(xc_info))
    1623              :          CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1624              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa, deriv_rhoa], &
    1625            0 :                                             allocate_deriv=.TRUE.)
    1626            0 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa_rhoa)
    1627              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa, deriv_rhob], &
    1628            0 :                                             allocate_deriv=.TRUE.)
    1629            0 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhoa_rhob)
    1630              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob, deriv_rhob], &
    1631            0 :                                             allocate_deriv=.TRUE.)
    1632            0 :             CALL xc_derivative_get(deriv, deriv_data=e_rhoa_rhob_rhob)
    1633              :             deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob, deriv_rhob], &
    1634            0 :                                             allocate_deriv=.TRUE.)
    1635            0 :             CALL xc_derivative_get(deriv, deriv_data=e_rhob_rhob_rhob)
    1636              :          CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA, XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1637            0 :             CPABORT("derivatives larger than 2 not implemented")
    1638              :          CASE default
    1639            0 :             CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1640              :          END SELECT
    1641              :       END IF
    1642              : 
    1643              : !$OMP PARALLEL DEFAULT(NONE), &
    1644              : !$OMP SHARED(rhoa,rhob,norm_drho,norm_drhoa,norm_drhob),&
    1645              : !$OMP SHARED(laplace_rhoa,laplace_rhob,tau_a,tau_b),&
    1646              : !$OMP SHARED(e_0,e_rhoa,e_rhob,e_ndrho,e_ndrhoa,e_ndrhob),&
    1647              : !$OMP SHARED(e_laplace_rhoa,e_laplace_rhob,e_tau_a,e_tau_b),&
    1648              : !$OMP SHARED(e_rhoa_rhoa,e_rhoa_rhob,e_rhob_rhob),&
    1649              : !$OMP SHARED(e_ndrho_rhoa,e_ndrho_rhob),&
    1650              : !$OMP SHARED(e_ndrhoa_rhoa,e_ndrhoa_rhob,e_ndrhob_rhoa,e_ndrhob_rhob),&
    1651              : !$OMP SHARED(e_ndrho_ndrho,e_ndrho_ndrhoa,e_ndrho_ndrhob),&
    1652              : !$OMP SHARED(e_ndrhoa_ndrhoa,e_ndrhoa_ndrhob,e_ndrhob_ndrhob),&
    1653              : !$OMP SHARED(e_rhoa_laplace_rhoa,e_rhoa_laplace_rhob,e_rhob_laplace_rhoa,e_rhob_laplace_rhob),&
    1654              : !$OMP SHARED(e_rhoa_tau_a,e_rhoa_tau_b,e_rhob_tau_a,e_rhob_tau_b),&
    1655              : !$OMP SHARED(e_ndrho_laplace_rhoa,e_ndrho_laplace_rhob),&
    1656              : !$OMP SHARED(e_ndrhoa_laplace_rhoa,e_ndrhoa_laplace_rhob,e_ndrhob_laplace_rhoa,e_ndrhob_laplace_rhob),&
    1657              : !$OMP SHARED(e_ndrho_tau_a,e_ndrho_tau_b),&
    1658              : !$OMP SHARED(e_ndrhoa_tau_a,e_ndrhoa_tau_b,e_ndrhob_tau_a,e_ndrhob_tau_b),&
    1659              : !$OMP SHARED(e_laplace_rhoa_laplace_rhoa,e_laplace_rhoa_laplace_rhob,e_laplace_rhob_laplace_rhob),&
    1660              : !$OMP SHARED(e_laplace_rhoa_tau_a,e_laplace_rhoa_tau_b,e_laplace_rhob_tau_a,e_laplace_rhob_tau_b),&
    1661              : !$OMP SHARED(e_tau_a_tau_a,e_tau_a_tau_b,e_tau_b_tau_b),&
    1662              : !$OMP SHARED(e_rhoa_rhoa_rhoa,e_rhoa_rhoa_rhob,e_rhoa_rhob_rhob,e_rhob_rhob_rhob),&
    1663              : !$OMP SHARED(grad_deriv,npoints),&
    1664         2750 : !$OMP SHARED(func_name,func_scale,workers)
    1665              : 
    1666              :       CALL libxc_spin_polarized_calc(rhoa=rhoa, rhob=rhob, norm_drho=norm_drho, &
    1667              :                                      norm_drhoa=norm_drhoa, norm_drhob=norm_drhob, laplace_rhoa=laplace_rhoa, &
    1668              :                                      laplace_rhob=laplace_rhob, tau_a=tau_a, tau_b=tau_b, &
    1669              :                                      e_0=e_0, e_rhoa=e_rhoa, e_rhob=e_rhob, e_ndrho=e_ndrho, &
    1670              :                                      e_ndrhoa=e_ndrhoa, e_ndrhob=e_ndrhob, e_laplace_rhoa=e_laplace_rhoa, &
    1671              :                                      e_laplace_rhob=e_laplace_rhob, e_tau_a=e_tau_a, e_tau_b=e_tau_b, &
    1672              :                                      e_rhoa_rhoa=e_rhoa_rhoa, e_rhoa_rhob=e_rhoa_rhob, e_rhob_rhob=e_rhob_rhob, &
    1673              :                                      e_ndrho_rhoa=e_ndrho_rhoa, e_ndrho_rhob=e_ndrho_rhob, &
    1674              :                                      e_ndrhoa_rhoa=e_ndrhoa_rhoa, e_ndrhoa_rhob=e_ndrhoa_rhob, &
    1675              :                                      e_ndrhob_rhoa=e_ndrhob_rhoa, e_ndrhob_rhob=e_ndrhob_rhob, &
    1676              :                                      e_ndrho_ndrho=e_ndrho_ndrho, e_ndrho_ndrhoa=e_ndrho_ndrhoa, &
    1677              :                                      e_ndrho_ndrhob=e_ndrho_ndrhob, e_ndrhoa_ndrhoa=e_ndrhoa_ndrhoa, &
    1678              :                                      e_ndrhoa_ndrhob=e_ndrhoa_ndrhob, e_ndrhob_ndrhob=e_ndrhob_ndrhob, &
    1679              :                                      e_rhoa_laplace_rhoa=e_rhoa_laplace_rhoa, &
    1680              :                                      e_rhoa_laplace_rhob=e_rhoa_laplace_rhob, &
    1681              :                                      e_rhob_laplace_rhoa=e_rhob_laplace_rhoa, &
    1682              :                                      e_rhob_laplace_rhob=e_rhob_laplace_rhob, &
    1683              :                                      e_rhoa_tau_a=e_rhoa_tau_a, e_rhoa_tau_b=e_rhoa_tau_b, &
    1684              :                                      e_rhob_tau_a=e_rhob_tau_a, e_rhob_tau_b=e_rhob_tau_b, &
    1685              :                                      e_ndrho_laplace_rhoa=e_ndrho_laplace_rhoa, &
    1686              :                                      e_ndrho_laplace_rhob=e_ndrho_laplace_rhob, &
    1687              :                                      e_ndrhoa_laplace_rhoa=e_ndrhoa_laplace_rhoa, &
    1688              :                                      e_ndrhoa_laplace_rhob=e_ndrhoa_laplace_rhob, &
    1689              :                                      e_ndrhob_laplace_rhoa=e_ndrhob_laplace_rhoa, &
    1690              :                                      e_ndrhob_laplace_rhob=e_ndrhob_laplace_rhob, &
    1691              :                                      e_ndrho_tau_a=e_ndrho_tau_a, e_ndrho_tau_b=e_ndrho_tau_b, &
    1692              :                                      e_ndrhoa_tau_a=e_ndrhoa_tau_a, e_ndrhoa_tau_b=e_ndrhoa_tau_b, &
    1693              :                                      e_ndrhob_tau_a=e_ndrhob_tau_a, e_ndrhob_tau_b=e_ndrhob_tau_b, &
    1694              :                                      e_laplace_rhoa_laplace_rhoa=e_laplace_rhoa_laplace_rhoa, &
    1695              :                                      e_laplace_rhoa_laplace_rhob=e_laplace_rhoa_laplace_rhob, &
    1696              :                                      e_laplace_rhob_laplace_rhob=e_laplace_rhob_laplace_rhob, &
    1697              :                                      e_laplace_rhoa_tau_a=e_laplace_rhoa_tau_a, &
    1698              :                                      e_laplace_rhoa_tau_b=e_laplace_rhoa_tau_b, &
    1699              :                                      e_laplace_rhob_tau_a=e_laplace_rhob_tau_a, &
    1700              :                                      e_laplace_rhob_tau_b=e_laplace_rhob_tau_b, &
    1701              :                                      e_tau_a_tau_a=e_tau_a_tau_a, &
    1702              :                                      e_tau_a_tau_b=e_tau_a_tau_b, &
    1703              :                                      e_tau_b_tau_b=e_tau_b_tau_b, &
    1704              :                                      e_rhoa_rhoa_rhoa=e_rhoa_rhoa_rhoa, &
    1705              :                                      e_rhoa_rhoa_rhob=e_rhoa_rhoa_rhob, &
    1706              :                                      e_rhoa_rhob_rhob=e_rhoa_rhob_rhob, &
    1707              :                                      e_rhob_rhob_rhob=e_rhob_rhob_rhob, &
    1708              :                                      grad_deriv=grad_deriv, npoints=npoints, &
    1709              :                                      func_name=func_name, sc=func_scale, workers=workers)
    1710              : 
    1711              : !$OMP END PARALLEL
    1712              : 
    1713         2750 :       NULLIFY (dummy)
    1714         2750 :       NULLIFY (workers)
    1715              : 
    1716         2750 :       CALL timestop(handle)
    1717              : #else
    1718              :       MARK_USED(rho_set)
    1719              :       MARK_USED(deriv_set)
    1720              :       MARK_USED(grad_deriv)
    1721              :       MARK_USED(libxc_params)
    1722              :       MARK_USED(func_name_override)
    1723              : 
    1724              :       CALL cp_abort(__LOCATION__, "Unknown functional! If you are asking "// &
    1725              :                     "for a functional of the LibXC library, "// &
    1726              :                     "you have to download and install the library!")
    1727              : #endif
    1728         2750 :    END SUBROUTINE libxc_spin_polarized_eval
    1729              : 
    1730              : ! **************************************************************************************************
    1731              : !> \brief libxc exchange-correlation functionals
    1732              : !> \param rho density
    1733              : !> \param norm_drho norm of the gradient of the density
    1734              : !> \param laplace_rho laplacian of the density
    1735              : !> \param tau kinetic-energy density
    1736              : !> \param e_0 energy density
    1737              : !> \param e_rho derivative of the energy density with respect to rho
    1738              : !> \param e_ndrho derivative of the energy density with respect to ndrho
    1739              : !> \param e_laplace_rho derivative of the energy density with respect to laplace_rho
    1740              : !> \param e_tau derivative of the energy density with respect to tau
    1741              : !> \param e_rho_rho derivative of the energy density with respect to rho_rho
    1742              : !> \param e_ndrho_rho derivative of the energy density with respect to ndrho_rho
    1743              : !> \param e_ndrho_ndrho derivative of the energy density with respect to ndrho_ndrho
    1744              : !> \param e_rho_laplace_rho derivative of the energy density with respect to rho_laplace_rho
    1745              : !> \param e_rho_tau derivative of the energy density with respect to rho_tau
    1746              : !> \param e_ndrho_laplace_rho derivative of the energy density with respect to ndrho_laplace_rho
    1747              : !> \param e_ndrho_tau derivative of the energy density with respect to ndrho_tau
    1748              : !> \param e_laplace_rho_laplace_rho derivative of the energy density with respect to laplace_rho_laplace_rho
    1749              : !> \param e_laplace_rho_tau derivative of the energy density with respect to laplace_rho_tau
    1750              : !> \param e_tau_tau derivative of the energy density with respect to tau_tau
    1751              : !> \param e_rho_rho_rho derivative of the energy density with respect to rho_rho_rho
    1752              : !> \param grad_deriv degree of the derivative that should be evaluated;
    1753              : !>        all derivatives up to the given degree are evaluated, in a single
    1754              : !>        LibXC call per block of grid points
    1755              : !> \param npoints number of points on the grid
    1756              : !> \param func_name name of the functional
    1757              : !> \param sc scaling factor of the functional
    1758              : !> \param workers cached LibXC functional objects and staging buffers, one per thread
    1759              : !> \author F. Tran
    1760              : ! **************************************************************************************************
    1761              : #if defined (__LIBXC)
    1762        17700 :    SUBROUTINE libxc_spin_unpolarized_calc(rho, norm_drho, laplace_rho, tau, &
    1763              :                                           e_0, e_rho, e_ndrho, e_laplace_rho, e_tau, e_rho_rho, e_ndrho_rho, &
    1764              :                                           e_ndrho_ndrho, e_rho_laplace_rho, e_rho_tau, e_ndrho_laplace_rho, &
    1765              :                                           e_ndrho_tau, e_laplace_rho_laplace_rho, e_laplace_rho_tau, &
    1766              :                                           e_tau_tau, e_rho_rho_rho, &
    1767              :                                           grad_deriv, npoints, func_name, sc, workers)
    1768              : 
    1769              :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rho, norm_drho, laplace_rho, tau
    1770              :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT) :: e_0, e_rho, e_ndrho, e_laplace_rho, e_tau, &
    1771              :          e_rho_rho, e_ndrho_rho, e_ndrho_ndrho, e_rho_laplace_rho, e_rho_tau, e_ndrho_laplace_rho, &
    1772              :          e_ndrho_tau, e_laplace_rho_laplace_rho, e_laplace_rho_tau, e_tau_tau, e_rho_rho_rho
    1773              :       INTEGER, INTENT(in)                                :: grad_deriv, npoints
    1774              :       CHARACTER(LEN=default_string_length), INTENT(IN)   :: func_name
    1775              :       REAL(KIND=dp), INTENT(in)                          :: sc
    1776              :       TYPE(libxc_worker_set_type), INTENT(INOUT)         :: workers
    1777              : 
    1778              :       INTEGER                                            :: bsize, family, i, i0, ib, ii, ithread, &
    1779              :                                                             nb, nblocks, nthreads
    1780              :       INTEGER(C_SIZE_T)                                  :: np
    1781              :       LOGICAL                                            :: is_gga, is_mgga
    1782              : 
    1783        17700 :       ithread = 0
    1784        17700 :       nthreads = 1
    1785        17700 : !$    ithread = omp_get_thread_num()
    1786        17700 : !$    nthreads = omp_get_num_threads()
    1787        17700 :       CPASSERT(ithread < SIZE(workers%worker))
    1788              : 
    1789              :       ! Blocks are capped by libxc_block_size, which is what the staging buffers
    1790              :       ! were allocated for, but shrunk when there are too few points to give every
    1791              :       ! thread a block of its own: small atomic grids would otherwise all be
    1792              :       ! evaluated by thread 0.
    1793        17700 :       bsize = MAX(1, MIN(libxc_block_size, (npoints + nthreads - 1)/nthreads))
    1794        17700 :       nblocks = (npoints + bsize - 1)/bsize
    1795              : 
    1796        17700 :       family = workers%family
    1797              :       SELECT CASE (family)
    1798              :       CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    1799              :          is_gga = .FALSE.
    1800         5268 :          is_mgga = .FALSE.
    1801              :       CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    1802         5268 :          is_gga = .TRUE.
    1803         5268 :          is_mgga = .FALSE.
    1804              :       CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    1805         2138 :          is_gga = .TRUE.
    1806         2138 :          is_mgga = .TRUE.
    1807              :       CASE default
    1808            0 :          is_gga = .FALSE.
    1809            0 :          is_mgga = .FALSE.
    1810        17700 :          CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    1811              :       END SELECT
    1812              : 
    1813              :       ! Points below the density cutoff need no test here. The cutoffs were handed
    1814              :       ! to the functional object in xc_libxc_wrap_set_thresholds, and LibXC leaves
    1815              :       ! the outputs of the points it screens at zero, so accumulating them is a
    1816              :       ! no-op.
    1817              :       ASSOCIATE (w => workers%worker(ithread + 1), has_laplace => workers%has_laplace, &
    1818              :                  no_exc => workers%no_exc, eps_rho => workers%epsilon_rho, &
    1819              :                  eps_tau => workers%epsilon_tau)
    1820        17700 : !$OMP    DO
    1821              :          DO ib = 1, nblocks
    1822      1018131 :             i0 = (ib - 1)*bsize
    1823      1018131 :             nb = MIN(bsize, npoints - i0)
    1824      1018131 :             np = INT(nb, KIND=C_SIZE_T)
    1825              : 
    1826              :             ! stage this block's inputs in LibXC's layout
    1827    520450624 :             DO i = 1, nb
    1828    520450624 :                w%rho(1, i) = rho(i0 + i)
    1829              :             END DO
    1830      1018131 :             IF (is_gga) THEN
    1831    273501950 :                DO i = 1, nb
    1832    273501950 :                   w%sigma(1, i) = norm_drho(i0 + i)**2
    1833              :                END DO
    1834              :             END IF
    1835      1018131 :             IF (is_mgga) THEN
    1836    102686484 :                DO i = 1, nb
    1837    102485437 :                   ii = i0 + i
    1838    102485437 :                   w%lapl(1, i) = laplace_rho(ii)
    1839    102686484 :                   w%tau(1, i) = tau(ii)
    1840              :                END DO
    1841              :                ! Meta-GGAs are screened on the kinetic energy density as well as on the
    1842              :                ! density, and LibXC only screens on the latter. A point failing the tau
    1843              :                ! test is handed over with zero density, which makes LibXC screen it out
    1844              :                ! and leave its outputs at zero: what skipping it used to achieve. The
    1845              :                ! Fermi hole curvature bound tau >= sigma/(8*rho) follows in the same pass,
    1846              :                ! with the denominator floored at the cutoff so the division stays defined
    1847              :                ! for the points that are about to be screened.
    1848    102686484 :                DO i = 1, nb
    1849    102485437 :                   IF (w%tau(1, i) <= eps_tau) w%rho(1, i) = 0.0_dp
    1850              :                   w%tau(1, i) = MAX(w%tau(1, i), &
    1851    102686484 :                                     w%sigma(1, i)/(8.0_dp*MAX(w%rho(1, i), eps_rho)))
    1852              :                END DO
    1853              :             END IF
    1854              : 
    1855              :             ! one LibXC call for the whole block
    1856              :             IF (is_mgga) THEN
    1857       202091 :                SELECT CASE (grad_deriv)
    1858              :                CASE (0)
    1859         1044 :                   CALL xc_f03_mgga_exc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), w%exc(1))
    1860              :                CASE (1)
    1861       191303 :                   IF (no_exc) THEN
    1862              :                      CALL xc_f03_mgga_vxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), &
    1863            0 :                                           w%vrho(1, 1), w%vsigma(1, 1), w%vlapl(1, 1), w%vtau(1, 1))
    1864            0 :                      w%exc(1:nb) = 0.0_dp
    1865              :                   ELSE
    1866              :                      CALL xc_f03_mgga_exc_vxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), &
    1867       191303 :                                               w%exc(1), w%vrho(1, 1), w%vsigma(1, 1), w%vlapl(1, 1), w%vtau(1, 1))
    1868              :                   END IF
    1869              :                CASE (2)
    1870       201047 :                   IF (no_exc) THEN
    1871              :                      CALL xc_f03_mgga_vxc_fxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), &
    1872              :                                               w%vrho(1, 1), w%vsigma(1, 1), w%vlapl(1, 1), w%vtau(1, 1), &
    1873              :                                               w%v2rho2(1, 1), w%v2rhosigma(1, 1), w%v2rholapl(1, 1), &
    1874              :                                               w%v2rhotau(1, 1), w%v2sigma2(1, 1), w%v2sigmalapl(1, 1), &
    1875            0 :                                               w%v2sigmatau(1, 1), w%v2lapl2(1, 1), w%v2lapltau(1, 1), w%v2tau2(1, 1))
    1876            0 :                      w%exc(1:nb) = 0.0_dp
    1877              :                   ELSE
    1878              :                      CALL xc_f03_mgga(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), &
    1879              :                                       w%exc(1), w%vrho(1, 1), w%vsigma(1, 1), w%vlapl(1, 1), w%vtau(1, 1), &
    1880              :                                       w%v2rho2(1, 1), w%v2rhosigma(1, 1), w%v2rholapl(1, 1), &
    1881              :                                       w%v2rhotau(1, 1), w%v2sigma2(1, 1), w%v2sigmalapl(1, 1), &
    1882         8700 :                                       w%v2sigmatau(1, 1), w%v2lapl2(1, 1), w%v2lapltau(1, 1), w%v2tau2(1, 1))
    1883              :                   END IF
    1884              :                END SELECT
    1885       817084 :             ELSE IF (is_gga) THEN
    1886       346132 :                SELECT CASE (grad_deriv)
    1887              :                CASE (0)
    1888        11962 :                   CALL xc_f03_gga_exc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%exc(1))
    1889              :                CASE (1)
    1890       316224 :                   IF (no_exc) THEN
    1891            0 :                      CALL xc_f03_gga_vxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%vrho(1, 1), w%vsigma(1, 1))
    1892            0 :                      w%exc(1:nb) = 0.0_dp
    1893              :                   ELSE
    1894              :                      CALL xc_f03_gga_exc_vxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), &
    1895       316224 :                                              w%exc(1), w%vrho(1, 1), w%vsigma(1, 1))
    1896              :                   END IF
    1897              :                CASE (2)
    1898       334170 :                   IF (no_exc) THEN
    1899              :                      CALL xc_f03_gga_vxc_fxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), &
    1900              :                                              w%vrho(1, 1), w%vsigma(1, 1), &
    1901            0 :                                              w%v2rho2(1, 1), w%v2rhosigma(1, 1), w%v2sigma2(1, 1))
    1902            0 :                      w%exc(1:nb) = 0.0_dp
    1903              :                   ELSE
    1904              :                      CALL xc_f03_gga_exc_vxc_fxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), &
    1905              :                                                  w%exc(1), w%vrho(1, 1), w%vsigma(1, 1), &
    1906         5984 :                                                  w%v2rho2(1, 1), w%v2rhosigma(1, 1), w%v2sigma2(1, 1))
    1907              :                   END IF
    1908              :                END SELECT
    1909              :             ELSE
    1910       495456 :                SELECT CASE (grad_deriv)
    1911              :                CASE (0)
    1912        12542 :                   CALL xc_f03_lda_exc(w%func, np, w%rho(1, 1), w%exc(1))
    1913              :                CASE (1)
    1914       450640 :                   CALL xc_f03_lda_exc_vxc(w%func, np, w%rho(1, 1), w%exc(1), w%vrho(1, 1))
    1915              :                CASE (2)
    1916              :                   CALL xc_f03_lda_exc_vxc_fxc(w%func, np, w%rho(1, 1), &
    1917        19732 :                                               w%exc(1), w%vrho(1, 1), w%v2rho2(1, 1))
    1918              :                CASE (3)
    1919              :                   CALL xc_f03_lda(w%func, np, w%rho(1, 1), &
    1920       482914 :                                   w%exc(1), w%vrho(1, 1), w%v2rho2(1, 1), w%v3rho3(1, 1))
    1921              :                END SELECT
    1922              :             END IF
    1923              : 
    1924              :             ! accumulate; each derivative is added by exactly one loop, selected by
    1925              :             ! the order requested and the family, not by a per-branch copy of the whole
    1926              :             ! block scaffolding
    1927      1018131 :             IF (grad_deriv >= 0) THEN
    1928    520450624 :                DO i = 1, nb
    1929    519432493 :                   ii = i0 + i
    1930    520450624 :                   e_0(ii) = e_0(ii) + sc*w%exc(i)*rho(ii)
    1931              :                END DO
    1932              :             END IF
    1933      1018131 :             IF (grad_deriv >= 1) THEN
    1934    507383128 :                DO i = 1, nb
    1935    506390545 :                   ii = i0 + i
    1936    507383128 :                   e_rho(ii) = e_rho(ii) + sc*w%vrho(1, i)
    1937              :                END DO
    1938       992583 :                IF (is_gga) THEN
    1939    266857950 :                   DO i = 1, nb
    1940    266335739 :                      ii = i0 + i
    1941    266857950 :                      e_ndrho(ii) = e_ndrho(ii) + sc*2.0_dp*w%vsigma(1, i)*norm_drho(ii)
    1942              :                   END DO
    1943              :                END IF
    1944       992583 :                IF (is_mgga) THEN
    1945    102159440 :                   DO i = 1, nb
    1946    101959437 :                      ii = i0 + i
    1947    102159440 :                      e_tau(ii) = e_tau(ii) + sc*w%vtau(1, i)
    1948              :                   END DO
    1949              :                END IF
    1950       200003 :                IF (is_mgga .AND. has_laplace) THEN
    1951      9918194 :                   DO i = 1, nb
    1952      9898632 :                      ii = i0 + i
    1953      9918194 :                      e_laplace_rho(ii) = e_laplace_rho(ii) + sc*w%vlapl(1, i)
    1954              :                   END DO
    1955              :                END IF
    1956              :             END IF
    1957      1018131 :             IF (grad_deriv >= 2) THEN
    1958     17477900 :                DO i = 1, nb
    1959     17443484 :                   ii = i0 + i
    1960     17477900 :                   e_rho_rho(ii) = e_rho_rho(ii) + sc*w%v2rho2(1, i)
    1961              :                END DO
    1962        34416 :                IF (is_gga) THEN
    1963      7461668 :                   DO i = 1, nb
    1964      7446984 :                      ii = i0 + i
    1965      7446984 :                      e_ndrho_rho(ii) = e_ndrho_rho(ii) + sc*2.0_dp*w%v2rhosigma(1, i)*norm_drho(ii)
    1966              :                      e_ndrho_ndrho(ii) = e_ndrho_ndrho(ii) + &
    1967      7461668 :                                          sc*2.0_dp*(2.0_dp*w%sigma(1, i)*w%v2sigma2(1, i) + w%vsigma(1, i))
    1968              :                   END DO
    1969              :                END IF
    1970        34416 :                IF (is_mgga) THEN
    1971      4433996 :                   DO i = 1, nb
    1972      4425296 :                      ii = i0 + i
    1973      4425296 :                      e_rho_tau(ii) = e_rho_tau(ii) + sc*w%v2rhotau(1, i)
    1974      4425296 :                      e_ndrho_tau(ii) = e_ndrho_tau(ii) + sc*2.0_dp*w%v2sigmatau(1, i)*norm_drho(ii)
    1975      4433996 :                      e_tau_tau(ii) = e_tau_tau(ii) + sc*w%v2tau2(1, i)
    1976              :                   END DO
    1977              :                END IF
    1978         8700 :                IF (is_mgga .AND. has_laplace) THEN
    1979      1321422 :                   DO i = 1, nb
    1980      1318824 :                      ii = i0 + i
    1981      1318824 :                      e_rho_laplace_rho(ii) = e_rho_laplace_rho(ii) + sc*w%v2rholapl(1, i)
    1982              :                      e_ndrho_laplace_rho(ii) = e_ndrho_laplace_rho(ii) + &
    1983      1318824 :                                                sc*2.0_dp*w%v2sigmalapl(1, i)*norm_drho(ii)
    1984      1318824 :                      e_laplace_rho_laplace_rho(ii) = e_laplace_rho_laplace_rho(ii) + sc*w%v2lapl2(1, i)
    1985      1321422 :                      e_laplace_rho_tau(ii) = e_laplace_rho_tau(ii) + sc*w%v2lapltau(1, i)
    1986              :                   END DO
    1987              :                END IF
    1988              :             END IF
    1989      1018131 :             IF (grad_deriv >= 3) THEN
    1990            0 :                DO i = 1, nb
    1991            0 :                   ii = i0 + i
    1992            0 :                   e_rho_rho_rho(ii) = e_rho_rho_rho(ii) + sc*w%v3rho3(1, i)
    1993              :                END DO
    1994              :             END IF
    1995              :          END DO
    1996              : !$OMP    END DO
    1997              :       END ASSOCIATE
    1998              : 
    1999        17700 :    END SUBROUTINE libxc_spin_unpolarized_calc
    2000              : #endif
    2001              : 
    2002              : ! **************************************************************************************************
    2003              : !> \brief libxc exchange-correlation functionals
    2004              : !> \param rhoa alpha density
    2005              : !> \param rhob beta density
    2006              : !> \param norm_drho ...
    2007              : !> \param norm_drhoa norm of the gradient of the alpha density
    2008              : !> \param norm_drhob norm of the gradient of the beta density
    2009              : !> \param laplace_rhoa laplacian of the alpha density
    2010              : !> \param laplace_rhob laplacian of the beta density
    2011              : !> \param tau_a alpha kinetic-energy density
    2012              : !> \param tau_b beta kinetic-energy density
    2013              : !> \param e_0 energy density
    2014              : !> \param e_rhoa derivative of the energy density with respect to rhoa
    2015              : !> \param e_rhob derivative of the energy density with respect to rhob
    2016              : !> \param e_ndrho derivative of the energy density with respect to ndrho
    2017              : !> \param e_ndrhoa derivative of the energy density with respect to ndrhoa
    2018              : !> \param e_ndrhob derivative of the energy density with respect to ndrhob
    2019              : !> \param e_laplace_rhoa derivative of the energy density with respect to laplace_rhoa
    2020              : !> \param e_laplace_rhob derivative of the energy density with respect to laplace_rhob
    2021              : !> \param e_tau_a derivative of the energy density with respect to tau_a
    2022              : !> \param e_tau_b derivative of the energy density with respect to tau_b
    2023              : !> \param e_rhoa_rhoa derivative of the energy density with respect to rhoa_rhoa
    2024              : !> \param e_rhoa_rhob derivative of the energy density with respect to rhoa_rhob
    2025              : !> \param e_rhob_rhob derivative of the energy density with respect to rhob_rhob
    2026              : !> \param e_ndrho_rhoa derivative of the energy density with respect to ndrho_rhoa
    2027              : !> \param e_ndrho_rhob derivative of the energy density with respect to ndrho_rhob
    2028              : !> \param e_ndrhoa_rhoa derivative of the energy density with respect to ndrhoa_rhoa
    2029              : !> \param e_ndrhoa_rhob derivative of the energy density with respect to ndrhoa_rhob
    2030              : !> \param e_ndrhob_rhoa derivative of the energy density with respect to ndrhob_rhoa
    2031              : !> \param e_ndrhob_rhob derivative of the energy density with respect to ndrhob_rhob
    2032              : !> \param e_ndrho_ndrho derivative of the energy density with respect to ndrho_ndrho
    2033              : !> \param e_ndrho_ndrhoa derivative of the energy density with respect to ndrho_ndrhoa
    2034              : !> \param e_ndrho_ndrhob derivative of the energy density with respect to ndrho_ndrhob
    2035              : !> \param e_ndrhoa_ndrhoa derivative of the energy density with respect to ndrhoa_ndrhoa
    2036              : !> \param e_ndrhoa_ndrhob derivative of the energy density with respect to ndrhoa_ndrhob
    2037              : !> \param e_ndrhob_ndrhob derivative of the energy density with respect to ndrhob_ndrhob
    2038              : !> \param e_rhoa_laplace_rhoa derivative of the energy density with respect to rhoa_laplace_rhoa
    2039              : !> \param e_rhoa_laplace_rhob derivative of the energy density with respect to rhoa_laplace_rhob
    2040              : !> \param e_rhob_laplace_rhoa derivative of the energy density with respect to rhob_laplace_rhoa
    2041              : !> \param e_rhob_laplace_rhob derivative of the energy density with respect to rhob_laplace_rhob
    2042              : !> \param e_rhoa_tau_a derivative of the energy density with respect to rhoa_tau_a
    2043              : !> \param e_rhoa_tau_b derivative of the energy density with respect to rhoa_tau_b
    2044              : !> \param e_rhob_tau_a derivative of the energy density with respect to rhob_tau_a
    2045              : !> \param e_rhob_tau_b derivative of the energy density with respect to rhob_tau_b
    2046              : !> \param e_ndrho_laplace_rhoa derivative of the energy density with respect to ndrho_laplace_rhoa
    2047              : !> \param e_ndrho_laplace_rhob derivative of the energy density with respect to ndrho_laplace_rhob
    2048              : !> \param e_ndrhoa_laplace_rhoa derivative of the energy density with respect to ndrhoa_laplace_rhoa
    2049              : !> \param e_ndrhoa_laplace_rhob derivative of the energy density with respect to ndrhoa_laplace_rhob
    2050              : !> \param e_ndrhob_laplace_rhoa derivative of the energy density with respect to ndrhob_laplace_rhoa
    2051              : !> \param e_ndrhob_laplace_rhob derivative of the energy density with respect to ndrhob_laplace_rhob
    2052              : !> \param e_ndrho_tau_a derivative of the energy density with respect to ndrho_tau_a
    2053              : !> \param e_ndrho_tau_b derivative of the energy density with respect to ndrho_tau_b
    2054              : !> \param e_ndrhoa_tau_a derivative of the energy density with respect to ndrhoa_tau_a
    2055              : !> \param e_ndrhoa_tau_b derivative of the energy density with respect to ndrhoa_tau_b
    2056              : !> \param e_ndrhob_tau_a derivative of the energy density with respect to ndrhob_tau_a
    2057              : !> \param e_ndrhob_tau_b derivative of the energy density with respect to ndrhob_tau_b
    2058              : !> \param e_laplace_rhoa_laplace_rhoa derivative of the energy density with respect to laplace_rhoa_laplace_rhoa
    2059              : !> \param e_laplace_rhoa_laplace_rhob derivative of the energy density with respect to laplace_rhoa_laplace_rhob
    2060              : !> \param e_laplace_rhob_laplace_rhob derivative of the energy density with respect to laplace_rhob_laplace_rhob
    2061              : !> \param e_laplace_rhoa_tau_a derivative of the energy density with respect to laplace_rhoa_tau_a
    2062              : !> \param e_laplace_rhoa_tau_b derivative of the energy density with respect to laplace_rhoa_tau_b
    2063              : !> \param e_laplace_rhob_tau_a derivative of the energy density with respect to laplace_rhob_tau_a
    2064              : !> \param e_laplace_rhob_tau_b derivative of the energy density with respect to laplace_rhob_tau_b
    2065              : !> \param e_tau_a_tau_a derivative of the energy density with respect to tau_a_tau_a
    2066              : !> \param e_tau_a_tau_b derivative of the energy density with respect to tau_a_tau_b
    2067              : !> \param e_tau_b_tau_b derivative of the energy density with respect to tau_b_tau_b
    2068              : !> \param e_rhoa_rhoa_rhoa derivative of the energy density with respect to rhoa_rhoa_rhoa
    2069              : !> \param e_rhoa_rhoa_rhob derivative of the energy density with respect to rhoa_rhoa_rhob
    2070              : !> \param e_rhoa_rhob_rhob derivative of the energy density with respect to rhoa_rhob_rhob
    2071              : !> \param e_rhob_rhob_rhob derivative of the energy density with respect to rhob_rhob_rhob
    2072              : !> \param grad_deriv degree of the derivative that should be evaluated;
    2073              : !>        all derivatives up to the given degree are evaluated, in a single
    2074              : !>        LibXC call per block of grid points
    2075              : !> \param npoints number of points on the grid
    2076              : !> \param func_name name of the functional
    2077              : !> \param sc scaling factor of the functional
    2078              : !> \param workers cached LibXC functional objects and staging buffers, one per thread
    2079              : !> \author F. Tran
    2080              : ! **************************************************************************************************
    2081              : #if defined (__LIBXC)
    2082         2750 :    SUBROUTINE libxc_spin_polarized_calc(rhoa, rhob, norm_drho, norm_drhoa, &
    2083              :                                         norm_drhob, laplace_rhoa, laplace_rhob, tau_a, tau_b, &
    2084              :                                         e_0, e_rhoa, e_rhob, e_ndrho, e_ndrhoa, e_ndrhob, &
    2085              :                                         e_laplace_rhoa, e_laplace_rhob, e_tau_a, e_tau_b, &
    2086              :                                         e_rhoa_rhoa, e_rhoa_rhob, e_rhob_rhob, &
    2087              :                                         e_ndrho_rhoa, e_ndrho_rhob, e_ndrhoa_rhoa, &
    2088              :                                         e_ndrhoa_rhob, e_ndrhob_rhoa, e_ndrhob_rhob, &
    2089              :                                         e_ndrho_ndrho, e_ndrho_ndrhoa, e_ndrho_ndrhob, &
    2090              :                                         e_ndrhoa_ndrhoa, e_ndrhoa_ndrhob, e_ndrhob_ndrhob, &
    2091              :                                         e_rhoa_laplace_rhoa, e_rhoa_laplace_rhob, &
    2092              :                                         e_rhob_laplace_rhoa, e_rhob_laplace_rhob, &
    2093              :                                         e_rhoa_tau_a, e_rhoa_tau_b, e_rhob_tau_a, e_rhob_tau_b, &
    2094              :                                         e_ndrho_laplace_rhoa, e_ndrho_laplace_rhob, &
    2095              :                                         e_ndrhoa_laplace_rhoa, e_ndrhoa_laplace_rhob, &
    2096              :                                         e_ndrhob_laplace_rhoa, e_ndrhob_laplace_rhob, &
    2097              :                                         e_ndrho_tau_a, e_ndrho_tau_b, &
    2098              :                                         e_ndrhoa_tau_a, e_ndrhoa_tau_b, &
    2099              :                                         e_ndrhob_tau_a, e_ndrhob_tau_b, &
    2100              :                                         e_laplace_rhoa_laplace_rhoa, &
    2101              :                                         e_laplace_rhoa_laplace_rhob, &
    2102              :                                         e_laplace_rhob_laplace_rhob, &
    2103              :                                         e_laplace_rhoa_tau_a, e_laplace_rhoa_tau_b, &
    2104              :                                         e_laplace_rhob_tau_a, e_laplace_rhob_tau_b, &
    2105              :                                         e_tau_a_tau_a, e_tau_a_tau_b, e_tau_b_tau_b, &
    2106              :                                         e_rhoa_rhoa_rhoa, e_rhoa_rhoa_rhob, &
    2107              :                                         e_rhoa_rhob_rhob, e_rhob_rhob_rhob, &
    2108              :                                         grad_deriv, npoints, func_name, sc, workers)
    2109              : 
    2110              :       REAL(KIND=dp), DIMENSION(*), INTENT(IN)            :: rhoa, rhob, norm_drho, norm_drhoa, &
    2111              :                                                             norm_drhob, laplace_rhoa, &
    2112              :                                                             laplace_rhob, tau_a, tau_b
    2113              :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT) :: e_0, e_rhoa, e_rhob, e_ndrho, e_ndrhoa, &
    2114              :          e_ndrhob, e_laplace_rhoa, e_laplace_rhob, e_tau_a, e_tau_b, e_rhoa_rhoa, e_rhoa_rhob, &
    2115              :          e_rhob_rhob, e_ndrho_rhoa, e_ndrho_rhob, e_ndrhoa_rhoa, e_ndrhoa_rhob, e_ndrhob_rhoa, &
    2116              :          e_ndrhob_rhob, e_ndrho_ndrho, e_ndrho_ndrhoa, e_ndrho_ndrhob, e_ndrhoa_ndrhoa, &
    2117              :          e_ndrhoa_ndrhob, e_ndrhob_ndrhob, e_rhoa_laplace_rhoa, e_rhoa_laplace_rhob, &
    2118              :          e_rhob_laplace_rhoa, e_rhob_laplace_rhob, e_rhoa_tau_a, e_rhoa_tau_b, e_rhob_tau_a, &
    2119              :          e_rhob_tau_b, e_ndrho_laplace_rhoa, e_ndrho_laplace_rhob, e_ndrhoa_laplace_rhoa
    2120              :       REAL(KIND=dp), DIMENSION(*), INTENT(INOUT) :: e_ndrhoa_laplace_rhob, e_ndrhob_laplace_rhoa, &
    2121              :          e_ndrhob_laplace_rhob, e_ndrho_tau_a, e_ndrho_tau_b, e_ndrhoa_tau_a, e_ndrhoa_tau_b, &
    2122              :          e_ndrhob_tau_a, e_ndrhob_tau_b, e_laplace_rhoa_laplace_rhoa, e_laplace_rhoa_laplace_rhob, &
    2123              :          e_laplace_rhob_laplace_rhob, e_laplace_rhoa_tau_a, e_laplace_rhoa_tau_b, &
    2124              :          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, &
    2125              :          e_rhoa_rhoa_rhoa, e_rhoa_rhoa_rhob, e_rhoa_rhob_rhob, e_rhob_rhob_rhob
    2126              :       INTEGER, INTENT(in)                                :: grad_deriv, npoints
    2127              :       CHARACTER(LEN=default_string_length), INTENT(IN)   :: func_name
    2128              :       REAL(KIND=dp), INTENT(in)                          :: sc
    2129              :       TYPE(libxc_worker_set_type), INTENT(INOUT)         :: workers
    2130              : 
    2131              :       INTEGER                                            :: bsize, family, i, i0, ib, ii, ithread, &
    2132              :                                                             nb, nblocks, nthreads
    2133              :       INTEGER(C_SIZE_T)                                  :: np
    2134              :       LOGICAL                                            :: is_gga, is_mgga
    2135              : 
    2136         2750 :       ithread = 0
    2137         2750 :       nthreads = 1
    2138         2750 : !$    ithread = omp_get_thread_num()
    2139         2750 : !$    nthreads = omp_get_num_threads()
    2140         2750 :       CPASSERT(ithread < SIZE(workers%worker))
    2141              : 
    2142         2750 :       bsize = MAX(1, MIN(libxc_block_size, (npoints + nthreads - 1)/nthreads))
    2143         2750 :       nblocks = (npoints + bsize - 1)/bsize
    2144              : 
    2145         2750 :       family = workers%family
    2146              :       SELECT CASE (family)
    2147              :       CASE (XC_FAMILY_LDA, XC_FAMILY_HYB_LDA)
    2148              :          is_gga = .FALSE.
    2149          402 :          is_mgga = .FALSE.
    2150              :       CASE (XC_FAMILY_GGA, XC_FAMILY_HYB_GGA)
    2151          402 :          is_gga = .TRUE.
    2152          402 :          is_mgga = .FALSE.
    2153              :       CASE (XC_FAMILY_MGGA, XC_FAMILY_HYB_MGGA)
    2154          972 :          is_gga = .TRUE.
    2155          972 :          is_mgga = .TRUE.
    2156              :       CASE default
    2157            0 :          is_gga = .FALSE.
    2158            0 :          is_mgga = .FALSE.
    2159         2750 :          CPABORT(TRIM(func_name)//": this XC_FAMILY is currently not supported.")
    2160              :       END SELECT
    2161              : 
    2162              :       ! As in the spin-unpolarized case the density and kinetic energy density
    2163              :       ! cutoffs are applied by LibXC itself.
    2164              :       ASSOCIATE (w => workers%worker(ithread + 1), has_laplace => workers%has_laplace, &
    2165              :                  no_exc => workers%no_exc, eps_rho => workers%epsilon_rho, &
    2166              :                  eps_tau => workers%epsilon_tau)
    2167         2750 : !$OMP    DO
    2168              :          DO ib = 1, nblocks
    2169       154032 :             i0 = (ib - 1)*bsize
    2170       154032 :             nb = MIN(bsize, npoints - i0)
    2171       154032 :             np = INT(nb, KIND=C_SIZE_T)
    2172              : 
    2173              :             ! stage this block's inputs in LibXC's layout
    2174     78715696 :             DO i = 1, nb
    2175     78561664 :                ii = i0 + i
    2176     78561664 :                w%rho(1, i) = MAX(rhoa(ii), 0.0_dp)
    2177     78715696 :                w%rho(2, i) = MAX(rhob(ii), 0.0_dp)
    2178              :             END DO
    2179       154032 :             IF (is_gga) THEN
    2180              :                ! CP2K works with the norms of the gradients, LibXC with their contractions
    2181     18077738 :                DO i = 1, nb
    2182     18042076 :                   ii = i0 + i
    2183     18042076 :                   w%nda(i) = MAX(norm_drhoa(ii), EPSILON(0.0_dp)*1.e4_dp)
    2184     18042076 :                   w%ndb(i) = MAX(norm_drhob(ii), EPSILON(0.0_dp)*1.e4_dp)
    2185     18042076 :                   w%nd(i) = MAX(norm_drho(ii), EPSILON(0.0_dp)*1.e4_dp)
    2186     18042076 :                   w%sigma(1, i) = w%nda(i)**2
    2187     18042076 :                   w%sigma(3, i) = w%ndb(i)**2
    2188     18077738 :                   w%sigma(2, i) = 0.5_dp*(w%nd(i)**2 - w%sigma(1, i) - w%sigma(3, i))
    2189              :                END DO
    2190              :             END IF
    2191       154032 :             IF (is_mgga) THEN
    2192      9495912 :                DO i = 1, nb
    2193      9477048 :                   ii = i0 + i
    2194      9477048 :                   w%lapl(1, i) = laplace_rhoa(ii)
    2195      9477048 :                   w%lapl(2, i) = laplace_rhob(ii)
    2196      9477048 :                   w%tau(1, i) = MAX(tau_a(ii), 0.0_dp)
    2197      9495912 :                   w%tau(2, i) = MAX(tau_b(ii), 0.0_dp)
    2198              :                END DO
    2199              :                ! screening on tau and the Fermi hole curvature bound, per spin channel;
    2200              :                ! see the spin-unpolarized routine. The tau test is on the sum of the two
    2201              :                ! channels, as the density test is.
    2202      9495912 :                DO i = 1, nb
    2203      9477048 :                   IF (w%tau(1, i) + w%tau(2, i) <= eps_tau) THEN
    2204        10732 :                      w%rho(1, i) = 0.0_dp
    2205        10732 :                      w%rho(2, i) = 0.0_dp
    2206              :                   END IF
    2207              :                   w%tau(1, i) = MAX(w%tau(1, i), &
    2208      9477048 :                                     w%sigma(1, i)/(8.0_dp*MAX(w%rho(1, i), eps_rho)))
    2209              :                   w%tau(2, i) = MAX(w%tau(2, i), &
    2210      9495912 :                                     w%sigma(3, i)/(8.0_dp*MAX(w%rho(2, i), eps_rho)))
    2211              :                END DO
    2212              :             END IF
    2213              : 
    2214              :             ! one LibXC call for the whole block
    2215              :             IF (is_mgga) THEN
    2216        19492 :                SELECT CASE (grad_deriv)
    2217              :                CASE (0)
    2218          628 :                   CALL xc_f03_mgga_exc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), w%exc(1))
    2219              :                CASE (1)
    2220        18040 :                   IF (no_exc) THEN
    2221              :                      CALL xc_f03_mgga_vxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), &
    2222            0 :                                           w%vrho(1, 1), w%vsigma(1, 1), w%vlapl(1, 1), w%vtau(1, 1))
    2223            0 :                      w%exc(1:nb) = 0.0_dp
    2224              :                   ELSE
    2225              :                      CALL xc_f03_mgga_exc_vxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), &
    2226        18040 :                                               w%exc(1), w%vrho(1, 1), w%vsigma(1, 1), w%vlapl(1, 1), w%vtau(1, 1))
    2227              :                   END IF
    2228              :                CASE (2)
    2229        18864 :                   IF (no_exc) THEN
    2230              :                      CALL xc_f03_mgga_vxc_fxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), &
    2231              :                                               w%vrho(1, 1), w%vsigma(1, 1), w%vlapl(1, 1), w%vtau(1, 1), &
    2232              :                                               w%v2rho2(1, 1), w%v2rhosigma(1, 1), w%v2rholapl(1, 1), &
    2233              :                                               w%v2rhotau(1, 1), w%v2sigma2(1, 1), w%v2sigmalapl(1, 1), &
    2234            0 :                                               w%v2sigmatau(1, 1), w%v2lapl2(1, 1), w%v2lapltau(1, 1), w%v2tau2(1, 1))
    2235            0 :                      w%exc(1:nb) = 0.0_dp
    2236              :                   ELSE
    2237              :                      CALL xc_f03_mgga(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%lapl(1, 1), w%tau(1, 1), &
    2238              :                                       w%exc(1), w%vrho(1, 1), w%vsigma(1, 1), w%vlapl(1, 1), w%vtau(1, 1), &
    2239              :                                       w%v2rho2(1, 1), w%v2rhosigma(1, 1), w%v2rholapl(1, 1), &
    2240              :                                       w%v2rhotau(1, 1), w%v2sigma2(1, 1), w%v2sigmalapl(1, 1), &
    2241          196 :                                       w%v2sigmatau(1, 1), w%v2lapl2(1, 1), w%v2lapltau(1, 1), w%v2tau2(1, 1))
    2242              :                   END IF
    2243              :                END SELECT
    2244       135168 :             ELSE IF (is_gga) THEN
    2245        17310 :                SELECT CASE (grad_deriv)
    2246              :                CASE (0)
    2247          512 :                   CALL xc_f03_gga_exc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%exc(1))
    2248              :                CASE (1)
    2249        14968 :                   IF (no_exc) THEN
    2250            0 :                      CALL xc_f03_gga_vxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), w%vrho(1, 1), w%vsigma(1, 1))
    2251            0 :                      w%exc(1:nb) = 0.0_dp
    2252              :                   ELSE
    2253              :                      CALL xc_f03_gga_exc_vxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), &
    2254        14968 :                                              w%exc(1), w%vrho(1, 1), w%vsigma(1, 1))
    2255              :                   END IF
    2256              :                CASE (2)
    2257        16798 :                   IF (no_exc) THEN
    2258              :                      CALL xc_f03_gga_vxc_fxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), &
    2259              :                                              w%vrho(1, 1), w%vsigma(1, 1), &
    2260            0 :                                              w%v2rho2(1, 1), w%v2rhosigma(1, 1), w%v2sigma2(1, 1))
    2261            0 :                      w%exc(1:nb) = 0.0_dp
    2262              :                   ELSE
    2263              :                      CALL xc_f03_gga_exc_vxc_fxc(w%func, np, w%rho(1, 1), w%sigma(1, 1), &
    2264              :                                                  w%exc(1), w%vrho(1, 1), w%vsigma(1, 1), &
    2265         1318 :                                                  w%v2rho2(1, 1), w%v2rhosigma(1, 1), w%v2sigma2(1, 1))
    2266              :                   END IF
    2267              :                END SELECT
    2268              :             ELSE
    2269       118370 :                SELECT CASE (grad_deriv)
    2270              :                CASE (0)
    2271            0 :                   CALL xc_f03_lda_exc(w%func, np, w%rho(1, 1), w%exc(1))
    2272              :                CASE (1)
    2273       116634 :                   CALL xc_f03_lda_exc_vxc(w%func, np, w%rho(1, 1), w%exc(1), w%vrho(1, 1))
    2274              :                CASE (2)
    2275              :                   CALL xc_f03_lda_exc_vxc_fxc(w%func, np, w%rho(1, 1), &
    2276         1736 :                                               w%exc(1), w%vrho(1, 1), w%v2rho2(1, 1))
    2277              :                CASE (3)
    2278              :                   CALL xc_f03_lda(w%func, np, w%rho(1, 1), &
    2279       118370 :                                   w%exc(1), w%vrho(1, 1), w%v2rho2(1, 1), w%v3rho3(1, 1))
    2280              :                END SELECT
    2281              :             END IF
    2282              : 
    2283              :             ! accumulate; one loop per group of derivatives, selected by the order
    2284              :             ! requested and the family
    2285       154032 :             IF (grad_deriv >= 0) THEN
    2286     78715696 :                DO i = 1, nb
    2287     78561664 :                   ii = i0 + i
    2288     78715696 :                   e_0(ii) = e_0(ii) + sc*w%exc(i)*(w%rho(1, i) + w%rho(2, i))
    2289              :                END DO
    2290              :             END IF
    2291       154032 :             IF (grad_deriv >= 1) THEN
    2292     78137496 :                DO i = 1, nb
    2293     77984604 :                   ii = i0 + i
    2294     77984604 :                   e_rhoa(ii) = e_rhoa(ii) + sc*w%vrho(1, i)
    2295     78137496 :                   e_rhob(ii) = e_rhob(ii) + sc*w%vrho(2, i)
    2296              :                END DO
    2297       152892 :                IF (is_gga) THEN
    2298     17499538 :                   DO i = 1, nb
    2299     17465016 :                      ii = i0 + i
    2300     17465016 :                      e_ndrho(ii) = e_ndrho(ii) + sc*w%vsigma(2, i)*w%nd(i)
    2301              :                      e_ndrhoa(ii) = e_ndrhoa(ii) + &
    2302     17465016 :                                     sc*(2.0_dp*w%vsigma(1, i) - w%vsigma(2, i))*w%nda(i)
    2303              :                      e_ndrhob(ii) = e_ndrhob(ii) + &
    2304     17499538 :                                     sc*(2.0_dp*w%vsigma(3, i) - w%vsigma(2, i))*w%ndb(i)
    2305              :                   END DO
    2306              :                END IF
    2307       152892 :                IF (is_mgga) THEN
    2308      9180368 :                   DO i = 1, nb
    2309      9162132 :                      ii = i0 + i
    2310      9162132 :                      e_tau_a(ii) = e_tau_a(ii) + sc*w%vtau(1, i)
    2311      9180368 :                      e_tau_b(ii) = e_tau_b(ii) + sc*w%vtau(2, i)
    2312              :                   END DO
    2313              :                END IF
    2314        18236 :                IF (is_mgga .AND. has_laplace) THEN
    2315      1246680 :                   DO i = 1, nb
    2316      1244160 :                      ii = i0 + i
    2317      1244160 :                      e_laplace_rhoa(ii) = e_laplace_rhoa(ii) + sc*w%vlapl(1, i)
    2318      1246680 :                      e_laplace_rhob(ii) = e_laplace_rhob(ii) + sc*w%vlapl(2, i)
    2319              :                   END DO
    2320              :                END IF
    2321              :             END IF
    2322       154032 :             IF (grad_deriv >= 2) THEN
    2323      1636402 :                DO i = 1, nb
    2324      1633152 :                   ii = i0 + i
    2325      1633152 :                   e_rhoa_rhoa(ii) = e_rhoa_rhoa(ii) + sc*w%v2rho2(1, i)
    2326      1633152 :                   e_rhoa_rhob(ii) = e_rhoa_rhob(ii) + sc*w%v2rho2(2, i)
    2327      1636402 :                   e_rhob_rhob(ii) = e_rhob_rhob(ii) + sc*w%v2rho2(3, i)
    2328              :                END DO
    2329         3250 :                IF (is_gga) THEN
    2330       761318 :                   DO i = 1, nb
    2331       759804 :                      ii = i0 + i
    2332       759804 :                      e_ndrho_rhoa(ii) = e_ndrho_rhoa(ii) + sc*w%v2rhosigma(2, i)*w%nd(i)
    2333       759804 :                      e_ndrho_rhob(ii) = e_ndrho_rhob(ii) + sc*w%v2rhosigma(5, i)*w%nd(i)
    2334              :                      e_ndrhoa_rhoa(ii) = e_ndrhoa_rhoa(ii) + &
    2335       759804 :                                          sc*(2.0_dp*w%v2rhosigma(1, i) - w%v2rhosigma(2, i))*w%nda(i)
    2336              :                      e_ndrhoa_rhob(ii) = e_ndrhoa_rhob(ii) + &
    2337       759804 :                                          sc*(2.0_dp*w%v2rhosigma(4, i) - w%v2rhosigma(5, i))*w%nda(i)
    2338              :                      e_ndrhob_rhoa(ii) = e_ndrhob_rhoa(ii) + &
    2339       759804 :                                          sc*(2.0_dp*w%v2rhosigma(3, i) - w%v2rhosigma(2, i))*w%ndb(i)
    2340              :                      e_ndrhob_rhob(ii) = e_ndrhob_rhob(ii) + &
    2341       759804 :                                          sc*(2.0_dp*w%v2rhosigma(6, i) - w%v2rhosigma(5, i))*w%ndb(i)
    2342              :                      e_ndrho_ndrho(ii) = e_ndrho_ndrho(ii) + &
    2343       759804 :                                          sc*(w%vsigma(2, i) + w%nd(i)**2*w%v2sigma2(4, i))
    2344              :                      e_ndrho_ndrhoa(ii) = e_ndrho_ndrhoa(ii) + &
    2345       759804 :                                           sc*(2.0_dp*w%v2sigma2(2, i) - w%v2sigma2(4, i))*w%nd(i)*w%nda(i)
    2346              :                      e_ndrho_ndrhob(ii) = e_ndrho_ndrhob(ii) + &
    2347       759804 :                                           sc*(2.0_dp*w%v2sigma2(5, i) - w%v2sigma2(4, i))*w%nd(i)*w%ndb(i)
    2348              :                      e_ndrhoa_ndrhoa(ii) = e_ndrhoa_ndrhoa(ii) + &
    2349              :                                            sc*(2.0_dp*w%vsigma(1, i) - w%vsigma(2, i) + w%nda(i)**2*( &
    2350       759804 :                                                4.0_dp*w%v2sigma2(1, i) - 4.0_dp*w%v2sigma2(2, i) + w%v2sigma2(4, i)))
    2351              :                      e_ndrhoa_ndrhob(ii) = e_ndrhoa_ndrhob(ii) + &
    2352              :                                            sc*(4.0_dp*w%v2sigma2(3, i) - 2.0_dp*w%v2sigma2(2, i) - &
    2353       759804 :                                                2.0_dp*w%v2sigma2(5, i) + w%v2sigma2(4, i))*w%nda(i)*w%ndb(i)
    2354              :                      e_ndrhob_ndrhob(ii) = e_ndrhob_ndrhob(ii) + &
    2355              :                                            sc*(2.0_dp*w%vsigma(3, i) - w%vsigma(2, i) + w%ndb(i)**2*( &
    2356       761318 :                                                4.0_dp*w%v2sigma2(6, i) - 4.0_dp*w%v2sigma2(5, i) + w%v2sigma2(4, i)))
    2357              :                   END DO
    2358              :                END IF
    2359         3250 :                IF (is_mgga) THEN
    2360        96964 :                   DO i = 1, nb
    2361        96768 :                      ii = i0 + i
    2362        96768 :                      e_rhoa_tau_a(ii) = e_rhoa_tau_a(ii) + sc*w%v2rhotau(1, i)
    2363        96768 :                      e_rhoa_tau_b(ii) = e_rhoa_tau_b(ii) + sc*w%v2rhotau(2, i)
    2364        96768 :                      e_rhob_tau_a(ii) = e_rhob_tau_a(ii) + sc*w%v2rhotau(3, i)
    2365        96768 :                      e_rhob_tau_b(ii) = e_rhob_tau_b(ii) + sc*w%v2rhotau(4, i)
    2366        96768 :                      e_ndrho_tau_a(ii) = e_ndrho_tau_a(ii) + sc*w%v2sigmatau(3, i)*w%nd(i)
    2367        96768 :                      e_ndrho_tau_b(ii) = e_ndrho_tau_b(ii) + sc*w%v2sigmatau(4, i)*w%nd(i)
    2368              :                      e_ndrhoa_tau_a(ii) = e_ndrhoa_tau_a(ii) + &
    2369        96768 :                                           sc*(2.0_dp*w%v2sigmatau(1, i) - w%v2sigmatau(3, i))*w%nda(i)
    2370              :                      e_ndrhoa_tau_b(ii) = e_ndrhoa_tau_b(ii) + &
    2371        96768 :                                           sc*(2.0_dp*w%v2sigmatau(2, i) - w%v2sigmatau(4, i))*w%nda(i)
    2372              :                      e_ndrhob_tau_a(ii) = e_ndrhob_tau_a(ii) + &
    2373        96768 :                                           sc*(2.0_dp*w%v2sigmatau(5, i) - w%v2sigmatau(3, i))*w%ndb(i)
    2374              :                      e_ndrhob_tau_b(ii) = e_ndrhob_tau_b(ii) + &
    2375        96768 :                                           sc*(2.0_dp*w%v2sigmatau(6, i) - w%v2sigmatau(4, i))*w%ndb(i)
    2376        96768 :                      e_tau_a_tau_a(ii) = e_tau_a_tau_a(ii) + sc*w%v2tau2(1, i)
    2377        96768 :                      e_tau_a_tau_b(ii) = e_tau_a_tau_b(ii) + sc*w%v2tau2(2, i)
    2378        96964 :                      e_tau_b_tau_b(ii) = e_tau_b_tau_b(ii) + sc*w%v2tau2(3, i)
    2379              :                   END DO
    2380              :                END IF
    2381          196 :                IF (is_mgga .AND. has_laplace) THEN
    2382        41556 :                   DO i = 1, nb
    2383        41472 :                      ii = i0 + i
    2384        41472 :                      e_rhoa_laplace_rhoa(ii) = e_rhoa_laplace_rhoa(ii) + sc*w%v2rholapl(1, i)
    2385        41472 :                      e_rhoa_laplace_rhob(ii) = e_rhoa_laplace_rhob(ii) + sc*w%v2rholapl(2, i)
    2386        41472 :                      e_rhob_laplace_rhoa(ii) = e_rhob_laplace_rhoa(ii) + sc*w%v2rholapl(3, i)
    2387        41472 :                      e_rhob_laplace_rhob(ii) = e_rhob_laplace_rhob(ii) + sc*w%v2rholapl(4, i)
    2388        41472 :                      e_ndrho_laplace_rhoa(ii) = e_ndrho_laplace_rhoa(ii) + sc*w%v2sigmalapl(3, i)*w%nd(i)
    2389        41472 :                      e_ndrho_laplace_rhob(ii) = e_ndrho_laplace_rhob(ii) + sc*w%v2sigmalapl(4, i)*w%nd(i)
    2390              :                      e_ndrhoa_laplace_rhoa(ii) = e_ndrhoa_laplace_rhoa(ii) + &
    2391        41472 :                                                  sc*(2.0_dp*w%v2sigmalapl(1, i) - w%v2sigmalapl(3, i))*w%nda(i)
    2392              :                      e_ndrhoa_laplace_rhob(ii) = e_ndrhoa_laplace_rhob(ii) + &
    2393        41472 :                                                  sc*(2.0_dp*w%v2sigmalapl(2, i) - w%v2sigmalapl(4, i))*w%nda(i)
    2394              :                      e_ndrhob_laplace_rhoa(ii) = e_ndrhob_laplace_rhoa(ii) + &
    2395        41472 :                                                  sc*(2.0_dp*w%v2sigmalapl(5, i) - w%v2sigmalapl(3, i))*w%ndb(i)
    2396              :                      e_ndrhob_laplace_rhob(ii) = e_ndrhob_laplace_rhob(ii) + &
    2397        41472 :                                                  sc*(2.0_dp*w%v2sigmalapl(6, i) - w%v2sigmalapl(4, i))*w%ndb(i)
    2398        41472 :                      e_laplace_rhoa_laplace_rhoa(ii) = e_laplace_rhoa_laplace_rhoa(ii) + sc*w%v2lapl2(1, i)
    2399        41472 :                      e_laplace_rhoa_laplace_rhob(ii) = e_laplace_rhoa_laplace_rhob(ii) + sc*w%v2lapl2(2, i)
    2400        41472 :                      e_laplace_rhob_laplace_rhob(ii) = e_laplace_rhob_laplace_rhob(ii) + sc*w%v2lapl2(3, i)
    2401        41472 :                      e_laplace_rhoa_tau_a(ii) = e_laplace_rhoa_tau_a(ii) + sc*w%v2lapltau(1, i)
    2402        41472 :                      e_laplace_rhoa_tau_b(ii) = e_laplace_rhoa_tau_b(ii) + sc*w%v2lapltau(2, i)
    2403        41472 :                      e_laplace_rhob_tau_a(ii) = e_laplace_rhob_tau_a(ii) + sc*w%v2lapltau(3, i)
    2404        41556 :                      e_laplace_rhob_tau_b(ii) = e_laplace_rhob_tau_b(ii) + sc*w%v2lapltau(4, i)
    2405              :                   END DO
    2406              :                END IF
    2407              :             END IF
    2408       154032 :             IF (grad_deriv >= 3) THEN
    2409            0 :                DO i = 1, nb
    2410            0 :                   ii = i0 + i
    2411            0 :                   e_rhoa_rhoa_rhoa(ii) = e_rhoa_rhoa_rhoa(ii) + sc*w%v3rho3(1, i)
    2412            0 :                   e_rhoa_rhoa_rhob(ii) = e_rhoa_rhoa_rhob(ii) + sc*w%v3rho3(2, i)
    2413            0 :                   e_rhoa_rhob_rhob(ii) = e_rhoa_rhob_rhob(ii) + sc*w%v3rho3(3, i)
    2414            0 :                   e_rhob_rhob_rhob(ii) = e_rhob_rhob_rhob(ii) + sc*w%v3rho3(4, i)
    2415              :                END DO
    2416              :             END IF
    2417              :          END DO
    2418              : !$OMP    END DO
    2419              :       END ASSOCIATE
    2420              : 
    2421         2750 :    END SUBROUTINE libxc_spin_polarized_calc
    2422              : #endif
    2423              : 
    2424            0 : END MODULE xc_libxc
        

Generated by: LCOV version 2.0-1