LCOV - code coverage report
Current view: top level - src/xc - xc_libxc.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:66ce584) Lines: 94.4 % 1108 1046
Test Date: 2026-09-12 06:50:25 Functions: 83.3 % 24 20

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

Generated by: LCOV version 2.0-1