LCOV - code coverage report
Current view: top level - src - qs_vxc_atom.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:cccd2f3) Lines: 76.5 % 1307 1000
Test Date: 2026-05-06 07:07:47 Functions: 80.0 % 15 12

            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 routines that build the integrals of the Vxc potential calculated
      10              : !>      for the atomic density in the basis set of spherical primitives
      11              : ! **************************************************************************************************
      12              : MODULE qs_vxc_atom
      13              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      14              :                                               get_atomic_kind
      15              :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      16              :                                               gto_basis_set_type
      17              :    USE cp_control_types,                ONLY: dft_control_type
      18              :    USE input_constants,                 ONLY: xc_none
      19              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      20              :                                               section_vals_type,&
      21              :                                               section_vals_val_get
      22              :    USE kinds,                           ONLY: dp
      23              :    USE memory_utilities,                ONLY: reallocate
      24              :    USE message_passing,                 ONLY: mp_para_env_type
      25              :    USE orbital_pointers,                ONLY: indso,&
      26              :                                               nsoset
      27              :    USE paw_basis_types,                 ONLY: get_paw_basis_info
      28              :    USE qs_environment_types,            ONLY: get_qs_env,&
      29              :                                               qs_environment_type
      30              :    USE qs_grid_atom,                    ONLY: grid_atom_type
      31              :    USE qs_harmonics_atom,               ONLY: get_none0_cg_list,&
      32              :                                               harmonics_atom_type
      33              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      34              :                                               has_nlcc,&
      35              :                                               qs_kind_type
      36              :    USE qs_linres_types,                 ONLY: nablavks_atom_type
      37              :    USE qs_rho_atom_types,               ONLY: get_rho_atom,&
      38              :                                               rho_atom_coeff,&
      39              :                                               rho_atom_type
      40              :    USE util,                            ONLY: get_limit
      41              :    USE xc_atom,                         ONLY: fill_rho_set,&
      42              :                                               vxc_of_r_epr,&
      43              :                                               vxc_of_r_new,&
      44              :                                               xc_2nd_deriv_of_r,&
      45              :                                               xc_rho_set_atom_update
      46              :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
      47              :                                               xc_dset_create,&
      48              :                                               xc_dset_release,&
      49              :                                               xc_dset_zero_all
      50              :    USE xc_derivatives,                  ONLY: xc_functionals_get_needs
      51              :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      52              :    USE xc_rho_set_types,                ONLY: xc_rho_set_create,&
      53              :                                               xc_rho_set_release,&
      54              :                                               xc_rho_set_type
      55              : #include "./base/base_uses.f90"
      56              : 
      57              :    IMPLICIT NONE
      58              : 
      59              :    PRIVATE
      60              : 
      61              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_vxc_atom'
      62              : 
      63              :    TYPE tau_basis_cache_type
      64              :       INTEGER                                            :: maxso = 0, na = 0, nr = 0, nsatbas = 0, &
      65              :                                                             nset = 0
      66              :       INTEGER, DIMENSION(:), POINTER                     :: lmax => NULL(), lmin => NULL(), &
      67              :                                                             n2oindex => NULL(), npgf => NULL(), &
      68              :                                                             o2nindex => NULL()
      69              :       REAL(dp), DIMENSION(:, :), POINTER                 :: zet => NULL()
      70              :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: grad
      71              :    END TYPE tau_basis_cache_type
      72              : 
      73              :    PUBLIC :: calculate_vxc_atom, &
      74              :              calculate_vxc_atom_epr, &
      75              :              calculate_xc_2nd_deriv_atom, &
      76              :              calc_rho_angular, &
      77              :              calculate_gfxc_atom, &
      78              :              gfxc_atom_diff, &
      79              :              gaVxcgb_noGC
      80              : 
      81              : CONTAINS
      82              : 
      83              : ! **************************************************************************************************
      84              : !> \brief ...
      85              : !> \param qs_env ...
      86              : !> \param energy_only ...
      87              : !> \param exc1 the on-body ex energy contribution
      88              : !> \param adiabatic_rescale_factor ...
      89              : !> \param kind_set_external provides a non-default kind_set to use
      90              : !> \param rho_atom_set_external provides a non-default atomic density set to use
      91              : !> \param xc_section_external provides an external non-default XC
      92              : ! **************************************************************************************************
      93        29294 :    SUBROUTINE calculate_vxc_atom(qs_env, energy_only, exc1, &
      94              :                                  adiabatic_rescale_factor, kind_set_external, &
      95              :                                  rho_atom_set_external, xc_section_external)
      96              : 
      97              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      98              :       LOGICAL, INTENT(IN)                                :: energy_only
      99              :       REAL(dp), INTENT(INOUT)                            :: exc1
     100              :       REAL(dp), INTENT(IN), OPTIONAL                     :: adiabatic_rescale_factor
     101              :       TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
     102              :          POINTER                                         :: kind_set_external
     103              :       TYPE(rho_atom_type), DIMENSION(:), OPTIONAL, &
     104              :          POINTER                                         :: rho_atom_set_external
     105              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: xc_section_external
     106              : 
     107              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_vxc_atom'
     108              : 
     109              :       INTEGER                                            :: bo(2), handle, iat, iatom, ikind, ir, &
     110              :                                                             myfun, na, natom, nr, nspins, num_pe
     111              :       INTEGER, DIMENSION(2, 3)                           :: bounds
     112        29294 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     113              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
     114              :                                                             paw_atom, tau_f
     115              :       REAL(dp)                                           :: agr, alpha, density_cut, exc_h, exc_s, &
     116              :                                                             gradient_cut, &
     117              :                                                             my_adiabatic_rescale_factor, tau_cut
     118              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
     119              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
     120        58588 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
     121        58588 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho_h, rho_s, tau_h, tau_s, vtau_h, &
     122        29294 :                                                             vtau_s, vxc_h, vxc_s
     123        58588 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho_h, drho_s, vxg_h, vxg_s
     124        29294 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     125              :       TYPE(dft_control_type), POINTER                    :: dft_control
     126              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
     127              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
     128              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
     129              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     130        29294 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: my_kind_set
     131        29294 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
     132        29294 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
     133        29294 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: my_rho_atom_set
     134              :       TYPE(rho_atom_type), POINTER                       :: rho_atom
     135              :       TYPE(section_vals_type), POINTER                   :: input, my_xc_section, xc_fun_section
     136        29294 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
     137              :       TYPE(xc_derivative_set_type)                       :: deriv_set
     138              :       TYPE(xc_rho_cflags_type)                           :: needs
     139              :       TYPE(xc_rho_set_type)                              :: rho_set_h, rho_set_s
     140              : 
     141              : ! -------------------------------------------------------------------------
     142              : 
     143        29294 :       CALL timeset(routineN, handle)
     144              : 
     145        29294 :       NULLIFY (atom_list)
     146        29294 :       NULLIFY (my_kind_set)
     147        29294 :       NULLIFY (atomic_kind_set)
     148        29294 :       NULLIFY (grid_atom)
     149        29294 :       NULLIFY (harmonics)
     150        29294 :       NULLIFY (input)
     151        29294 :       NULLIFY (para_env)
     152        29294 :       NULLIFY (rho_atom)
     153        29294 :       NULLIFY (my_rho_atom_set)
     154        29294 :       NULLIFY (rho_nlcc)
     155              : 
     156        29294 :       IF (PRESENT(adiabatic_rescale_factor)) THEN
     157           44 :          my_adiabatic_rescale_factor = adiabatic_rescale_factor
     158              :       ELSE
     159        29250 :          my_adiabatic_rescale_factor = 1.0_dp
     160              :       END IF
     161              : 
     162              :       CALL get_qs_env(qs_env=qs_env, &
     163              :                       dft_control=dft_control, &
     164              :                       para_env=para_env, &
     165              :                       atomic_kind_set=atomic_kind_set, &
     166              :                       qs_kind_set=my_kind_set, &
     167              :                       input=input, &
     168        29294 :                       rho_atom_set=my_rho_atom_set)
     169              : 
     170        29294 :       IF (PRESENT(kind_set_external)) my_kind_set => kind_set_external
     171        29294 :       IF (PRESENT(rho_atom_set_external)) my_rho_atom_set => rho_atom_set_external
     172              : 
     173        29294 :       nlcc = has_nlcc(my_kind_set)
     174        29294 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
     175              : 
     176        29294 :       my_xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     177              : 
     178        29294 :       IF (PRESENT(xc_section_external)) my_xc_section => xc_section_external
     179              : 
     180        29294 :       xc_fun_section => section_vals_get_subs_vals(my_xc_section, "XC_FUNCTIONAL")
     181              :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", &
     182        29294 :                                 i_val=myfun)
     183              : 
     184        29294 :       IF (myfun == xc_none) THEN
     185         4018 :          exc1 = 0.0_dp
     186        15686 :          my_rho_atom_set(:)%exc_h = 0.0_dp
     187        15686 :          my_rho_atom_set(:)%exc_s = 0.0_dp
     188              :       ELSE
     189              :          CALL section_vals_val_get(my_xc_section, "DENSITY_CUTOFF", &
     190        25276 :                                    r_val=density_cut)
     191              :          CALL section_vals_val_get(my_xc_section, "GRADIENT_CUTOFF", &
     192        25276 :                                    r_val=gradient_cut)
     193              :          CALL section_vals_val_get(my_xc_section, "TAU_CUTOFF", &
     194        25276 :                                    r_val=tau_cut)
     195              : 
     196        25276 :          lsd = dft_control%lsd
     197        25276 :          nspins = dft_control%nspins
     198              :          needs = xc_functionals_get_needs(xc_fun_section, &
     199              :                                           lsd=lsd, &
     200        25276 :                                           calc_potential=.TRUE.)
     201              : 
     202        25276 :          gradient_f = (needs%drho .OR. needs%drho_spin)
     203        25276 :          tau_f = (needs%tau .OR. needs%tau_spin)
     204              : 
     205              :          ! Initialize energy contribution from the one center XC terms to zero
     206        25276 :          exc1 = 0.0_dp
     207              : 
     208              :          ! Nullify some pointers for work-arrays
     209        25276 :          NULLIFY (rho_h, drho_h, rho_s, drho_s, weight_h, weight_s)
     210        25276 :          NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
     211        25276 :          NULLIFY (tau_h, tau_s)
     212        25276 :          NULLIFY (vtau_h, vtau_s)
     213              : 
     214              :          ! Here starts the loop over all the atoms
     215              : 
     216        75324 :          DO ikind = 1, SIZE(atomic_kind_set)
     217        50048 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     218              :             CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     219        50048 :                              harmonics=harmonics, grid_atom=grid_atom)
     220        50048 :             CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
     221              : 
     222        50048 :             IF (.NOT. paw_atom) CYCLE
     223              : 
     224        46036 :             nr = grid_atom%nr
     225        46036 :             na = grid_atom%ng_sphere
     226              : 
     227              :             ! Prepare the structures needed to calculate and store the xc derivatives
     228              : 
     229              :             ! Array dimension: here anly one dimensional arrays are used,
     230              :             ! i.e. only the first column of deriv_data is read.
     231              :             ! The other to dimensions  are set to size equal 1
     232       460360 :             bounds(1:2, 1:3) = 1
     233        46036 :             bounds(2, 1) = na
     234        46036 :             bounds(2, 2) = nr
     235              : 
     236              :             ! set integration weights
     237        46036 :             IF (accint) THEN
     238        13282 :                weight_h => grid_atom%weight
     239        13282 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
     240        13282 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     241        12814 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
     242              :                END IF
     243        13282 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     244         1872 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
     245        23868 :                   DO ir = 1, nr
     246        23400 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
     247      1193868 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
     248              :                   END DO
     249          468 :                   grid_atom%gapw_weight_alpha = alpha
     250              :                END IF
     251        13282 :                weight_s => grid_atom%gapw_weight_s
     252              :             ELSE
     253        32754 :                weight_h => grid_atom%weight
     254        32754 :                weight_s => grid_atom%weight
     255              :             END IF
     256              : 
     257              :             ! create a place where to put the derivatives
     258        46036 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
     259              :             ! create the place where to store the argument for the functionals
     260              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
     261        46036 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     262              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
     263        46036 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     264              : 
     265              :             ! allocate the required 3d arrays where to store rho and drho
     266        46036 :             CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
     267        46036 :             CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
     268              : 
     269        46036 :             CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
     270        46036 :             CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
     271        46036 :             CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
     272        46036 :             CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
     273              :             !
     274        46036 :             IF (gradient_f) THEN
     275        30016 :                CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
     276        30016 :                CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
     277        30016 :                CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
     278        30016 :                CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
     279              :             END IF
     280              : 
     281        46036 :             IF (tau_f) THEN
     282         1218 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
     283         1218 :                CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
     284         1218 :                CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
     285         1218 :                CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
     286         1218 :                CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
     287              :             END IF
     288              : 
     289              :             ! NLCC: prepare rho and drho of the core charge for this KIND
     290        46036 :             donlcc = .FALSE.
     291        46036 :             IF (nlcc) THEN
     292          458 :                NULLIFY (rho_nlcc)
     293          458 :                rho_nlcc => my_kind_set(ikind)%nlcc_pot
     294          458 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
     295              :             END IF
     296              : 
     297              :             ! Distribute the atoms of this kind
     298              : 
     299        46036 :             num_pe = para_env%num_pe
     300        46036 :             bo = get_limit(natom, para_env%num_pe, para_env%mepos)
     301              : 
     302        82285 :             DO iat = bo(1), bo(2)
     303        36249 :                iatom = atom_list(iat)
     304              : 
     305        36249 :                my_rho_atom_set(iatom)%exc_h = 0.0_dp
     306        36249 :                my_rho_atom_set(iatom)%exc_s = 0.0_dp
     307              : 
     308        36249 :                rho_atom => my_rho_atom_set(iatom)
     309    117689623 :                rho_h = 0.0_dp
     310    117689623 :                rho_s = 0.0_dp
     311        36249 :                IF (gradient_f) THEN
     312        22957 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
     313              :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
     314              :                                     rho_rad_s=r_s, drho_rad_h=dr_h, &
     315              :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
     316        22957 :                                     rho_rad_s_d=r_s_d)
     317    335985922 :                   drho_h = 0.0_dp
     318    335985922 :                   drho_s = 0.0_dp
     319              :                ELSE
     320        13292 :                   NULLIFY (r_h, r_s)
     321        13292 :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
     322        13292 :                   rho_d = 0.0_dp
     323              :                END IF
     324        36249 :                IF (tau_f) THEN
     325              :                   !compute tau on the grid all at once
     326          849 :                   CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
     327              :                ELSE
     328        35400 :                   tau_d = 0.0_dp
     329              :                END IF
     330              : 
     331      2019239 :                DO ir = 1, nr
     332              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
     333              :                                         ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
     334      1982990 :                                         r_h_d, r_s_d, drho_h, drho_s)
     335      2019239 :                   IF (donlcc) THEN
     336              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
     337         8650 :                                         ir, rho_nlcc(:, 1), rho_h, rho_s, rho_nlcc(:, 2), drho_h, drho_s)
     338              :                   END IF
     339              :                END DO
     340              : 
     341      2019239 :                DO ir = 1, nr
     342      2019239 :                   IF (tau_f) THEN
     343        43750 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
     344        43750 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
     345      1939240 :                   ELSE IF (gradient_f) THEN
     346      1121540 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
     347      1121540 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
     348              :                   ELSE
     349       817700 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
     350       817700 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
     351              :                   END IF
     352              :                END DO
     353              : 
     354              :                !-------------------!
     355              :                ! hard atom density !
     356              :                !-------------------!
     357        36249 :                CALL xc_dset_zero_all(deriv_set)
     358              :                CALL vxc_of_r_new(xc_fun_section, rho_set_h, deriv_set, 1, needs, weight_h, &
     359              :                                  lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h, energy_only=energy_only, &
     360        36249 :                                  adiabatic_rescale_factor=my_adiabatic_rescale_factor)
     361        36249 :                rho_atom%exc_h = rho_atom%exc_h + exc_h
     362              : 
     363              :                !-------------------!
     364              :                ! soft atom density !
     365              :                !-------------------!
     366        36249 :                CALL xc_dset_zero_all(deriv_set)
     367              :                CALL vxc_of_r_new(xc_fun_section, rho_set_s, deriv_set, 1, needs, weight_s, &
     368              :                                  lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s, energy_only=energy_only, &
     369        36249 :                                  adiabatic_rescale_factor=my_adiabatic_rescale_factor)
     370        36249 :                rho_atom%exc_s = rho_atom%exc_s + exc_s
     371              : 
     372              :                ! Add contributions to the exc energy
     373              : 
     374        36249 :                exc1 = exc1 + rho_atom%exc_h - rho_atom%exc_s
     375              : 
     376              :                ! Integration to get the matrix elements relative to the vxc_atom
     377              :                ! here the products with the primitives is done: gaVxcgb
     378              :                ! internal transformation to get the integral in cartesian Gaussians
     379              : 
     380        36249 :                IF (.NOT. energy_only) THEN
     381        34737 :                   NULLIFY (int_hh, int_ss)
     382        34737 :                   CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
     383        34737 :                   IF (gradient_f) THEN
     384              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
     385        21627 :                                      grid_atom, basis_1c, harmonics, nspins)
     386              :                   ELSE
     387              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
     388        13110 :                                        grid_atom, basis_1c, harmonics, nspins)
     389              :                   END IF
     390        34737 :                   IF (tau_f) THEN
     391              :                      CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
     392          849 :                                      tau_basis_cache, nspins)
     393              :                   END IF
     394              :                END IF ! energy_only
     395        82285 :                NULLIFY (r_h, r_s, dr_h, dr_s)
     396              :             END DO ! iat
     397              : 
     398        46036 :             IF (tau_f) CALL release_tau_basis_cache(tau_basis_cache)
     399              : 
     400              :             ! Release the xc structure used to store the xc derivatives
     401        46036 :             CALL xc_dset_release(deriv_set)
     402        46036 :             CALL xc_rho_set_release(rho_set_h)
     403       167396 :             CALL xc_rho_set_release(rho_set_s)
     404              :          END DO ! ikind
     405              : 
     406        25276 :          CALL para_env%sum(exc1)
     407              : 
     408        25276 :          IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
     409        25276 :          IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
     410        25276 :          IF (ASSOCIATED(vxc_h)) DEALLOCATE (vxc_h)
     411        25276 :          IF (ASSOCIATED(vxc_s)) DEALLOCATE (vxc_s)
     412              : 
     413        25276 :          IF (gradient_f) THEN
     414        16650 :             IF (ASSOCIATED(drho_h)) DEALLOCATE (drho_h)
     415        16650 :             IF (ASSOCIATED(drho_s)) DEALLOCATE (drho_s)
     416        16650 :             IF (ASSOCIATED(vxg_h)) DEALLOCATE (vxg_h)
     417        16650 :             IF (ASSOCIATED(vxg_s)) DEALLOCATE (vxg_s)
     418              :          END IF
     419              : 
     420        25276 :          IF (tau_f) THEN
     421          670 :             IF (ASSOCIATED(tau_h)) DEALLOCATE (tau_h)
     422          670 :             IF (ASSOCIATED(tau_s)) DEALLOCATE (tau_s)
     423          670 :             IF (ASSOCIATED(vtau_h)) DEALLOCATE (vtau_h)
     424          670 :             IF (ASSOCIATED(vtau_s)) DEALLOCATE (vtau_s)
     425              :          END IF
     426              : 
     427              :       END IF !xc_none
     428              : 
     429        29294 :       CALL timestop(handle)
     430              : 
     431      1113172 :    END SUBROUTINE calculate_vxc_atom
     432              : 
     433              : ! **************************************************************************************************
     434              : !> \brief ...
     435              : !> \param qs_env ...
     436              : !> \param exc1 the on-body ex energy contribution
     437              : !> \param gradient_atom_set ...
     438              : ! **************************************************************************************************
     439           10 :    SUBROUTINE calculate_vxc_atom_epr(qs_env, exc1, gradient_atom_set)
     440              : 
     441              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     442              :       REAL(dp), INTENT(INOUT)                            :: exc1
     443              :       TYPE(nablavks_atom_type), DIMENSION(:), POINTER    :: gradient_atom_set
     444              : 
     445              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_vxc_atom_epr'
     446              : 
     447              :       INTEGER                                            :: bo(2), handle, ia, iat, iatom, idir, &
     448              :                                                             ikind, ir, ispin, myfun, na, natom, &
     449              :                                                             nr, nspins, num_pe
     450              :       INTEGER, DIMENSION(2, 3)                           :: bounds
     451           10 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     452              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
     453              :                                                             paw_atom, tau_f
     454              :       REAL(dp)                                           :: agr, alpha, density_cut, exc_h, exc_s, &
     455              :                                                             gradient_cut, tau_cut
     456              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
     457              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
     458           20 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
     459           20 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho_h, rho_s, tau_h, tau_s, vtau_h, &
     460           10 :                                                             vtau_s, vxc_h, vxc_s
     461           20 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho_h, drho_s, vxg_h, vxg_s
     462           10 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     463              :       TYPE(dft_control_type), POINTER                    :: dft_control
     464              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
     465              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
     466              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
     467              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     468           10 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: my_kind_set
     469           10 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
     470           10 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
     471           10 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: my_rho_atom_set
     472              :       TYPE(rho_atom_type), POINTER                       :: rho_atom
     473              :       TYPE(section_vals_type), POINTER                   :: input, my_xc_section, xc_fun_section
     474           10 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
     475              :       TYPE(xc_derivative_set_type)                       :: deriv_set
     476              :       TYPE(xc_rho_cflags_type)                           :: needs
     477              :       TYPE(xc_rho_set_type)                              :: rho_set_h, rho_set_s
     478              : 
     479              : ! -------------------------------------------------------------------------
     480              : 
     481           10 :       CALL timeset(routineN, handle)
     482              : 
     483           10 :       NULLIFY (atom_list)
     484           10 :       NULLIFY (my_kind_set)
     485           10 :       NULLIFY (atomic_kind_set)
     486           10 :       NULLIFY (grid_atom)
     487           10 :       NULLIFY (harmonics)
     488           10 :       NULLIFY (input)
     489           10 :       NULLIFY (para_env)
     490           10 :       NULLIFY (rho_atom)
     491           10 :       NULLIFY (my_rho_atom_set)
     492           10 :       NULLIFY (rho_nlcc)
     493              : 
     494              :       CALL get_qs_env(qs_env=qs_env, &
     495              :                       dft_control=dft_control, &
     496              :                       para_env=para_env, &
     497              :                       atomic_kind_set=atomic_kind_set, &
     498              :                       qs_kind_set=my_kind_set, &
     499              :                       input=input, &
     500           10 :                       rho_atom_set=my_rho_atom_set)
     501              : 
     502           10 :       nlcc = has_nlcc(my_kind_set)
     503           10 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
     504              : 
     505              :       my_xc_section => section_vals_get_subs_vals(input, &
     506           10 :                                                   "PROPERTIES%LINRES%EPR%PRINT%G_TENSOR%XC")
     507           10 :       xc_fun_section => section_vals_get_subs_vals(my_xc_section, "XC_FUNCTIONAL")
     508              :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", &
     509           10 :                                 i_val=myfun)
     510              : 
     511           10 :       IF (myfun == xc_none) THEN
     512            0 :          exc1 = 0.0_dp
     513            0 :          my_rho_atom_set(:)%exc_h = 0.0_dp
     514            0 :          my_rho_atom_set(:)%exc_s = 0.0_dp
     515              :       ELSE
     516              :          CALL section_vals_val_get(my_xc_section, "DENSITY_CUTOFF", &
     517           10 :                                    r_val=density_cut)
     518              :          CALL section_vals_val_get(my_xc_section, "GRADIENT_CUTOFF", &
     519           10 :                                    r_val=gradient_cut)
     520              :          CALL section_vals_val_get(my_xc_section, "TAU_CUTOFF", &
     521           10 :                                    r_val=tau_cut)
     522              : 
     523           10 :          lsd = dft_control%lsd
     524           10 :          nspins = dft_control%nspins
     525              :          needs = xc_functionals_get_needs(xc_fun_section, &
     526              :                                           lsd=lsd, &
     527           10 :                                           calc_potential=.TRUE.)
     528              : 
     529              :          ! whatever the xc, if epr_xc, drho_spin is needed
     530           10 :          needs%drho_spin = .TRUE.
     531              : 
     532           10 :          gradient_f = (needs%drho .OR. needs%drho_spin)
     533           10 :          tau_f = (needs%tau .OR. needs%tau_spin)
     534              : 
     535              :          ! Initialize energy contribution from the one center XC terms to zero
     536           10 :          exc1 = 0.0_dp
     537              : 
     538              :          ! Nullify some pointers for work-arrays
     539           10 :          NULLIFY (rho_h, drho_h, rho_s, drho_s, weight_h, weight_s)
     540           10 :          NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
     541           10 :          NULLIFY (tau_h, tau_s)
     542           10 :          NULLIFY (vtau_h, vtau_s)
     543              : 
     544              :          ! Here starts the loop over all the atoms
     545              : 
     546           30 :          DO ikind = 1, SIZE(atomic_kind_set)
     547           20 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     548              :             CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     549           20 :                              harmonics=harmonics, grid_atom=grid_atom)
     550           20 :             CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
     551              : 
     552           20 :             IF (.NOT. paw_atom) CYCLE
     553              : 
     554           20 :             nr = grid_atom%nr
     555           20 :             na = grid_atom%ng_sphere
     556              : 
     557              :             ! Prepare the structures needed to calculate and store the xc derivatives
     558              : 
     559              :             ! Array dimension: here anly one dimensional arrays are used,
     560              :             ! i.e. only the first column of deriv_data is read.
     561              :             ! The other to dimensions  are set to size equal 1
     562          200 :             bounds(1:2, 1:3) = 1
     563           20 :             bounds(2, 1) = na
     564           20 :             bounds(2, 2) = nr
     565              : 
     566              :             ! set integration weights
     567           20 :             IF (accint) THEN
     568            0 :                weight_h => grid_atom%weight
     569            0 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
     570            0 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     571            0 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
     572              :                END IF
     573            0 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     574            0 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
     575            0 :                   DO ir = 1, nr
     576            0 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
     577            0 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
     578              :                   END DO
     579            0 :                   grid_atom%gapw_weight_alpha = alpha
     580              :                END IF
     581            0 :                weight_s => grid_atom%gapw_weight_s
     582              :             ELSE
     583           20 :                weight_h => grid_atom%weight
     584           20 :                weight_s => grid_atom%weight
     585              :             END IF
     586              : 
     587              :             ! create a place where to put the derivatives
     588           20 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
     589              :             ! create the place where to store the argument for the functionals
     590              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
     591           20 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     592              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
     593           20 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     594              : 
     595              :             ! allocate the required 3d arrays where to store rho and drho
     596           20 :             CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
     597           20 :             CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
     598              : 
     599           20 :             CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
     600           20 :             CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
     601           20 :             CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
     602           20 :             CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
     603              :             !
     604              :             IF (gradient_f) THEN
     605           20 :                CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
     606           20 :                CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
     607           20 :                CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
     608           20 :                CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
     609              :             END IF
     610              : 
     611           20 :             IF (tau_f) THEN
     612            0 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
     613            0 :                CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
     614            0 :                CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
     615            0 :                CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
     616            0 :                CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
     617              :             END IF
     618              : 
     619              :             ! NLCC: prepare rho and drho of the core charge for this KIND
     620           20 :             donlcc = .FALSE.
     621           20 :             IF (nlcc) THEN
     622            0 :                NULLIFY (rho_nlcc)
     623            0 :                rho_nlcc => my_kind_set(ikind)%nlcc_pot
     624            0 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
     625              :             END IF
     626              : 
     627              :             ! Distribute the atoms of this kind
     628              : 
     629           20 :             num_pe = para_env%num_pe
     630           20 :             bo = get_limit(natom, para_env%num_pe, para_env%mepos)
     631              : 
     632           35 :             DO iat = bo(1), bo(2)
     633           15 :                iatom = atom_list(iat)
     634              : 
     635           15 :                my_rho_atom_set(iatom)%exc_h = 0.0_dp
     636           15 :                my_rho_atom_set(iatom)%exc_s = 0.0_dp
     637              : 
     638           15 :                rho_atom => my_rho_atom_set(iatom)
     639        76545 :                rho_h = 0.0_dp
     640        76545 :                rho_s = 0.0_dp
     641              :                IF (gradient_f) THEN
     642           15 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
     643              :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
     644              :                                     rho_rad_s=r_s, drho_rad_h=dr_h, &
     645              :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
     646           15 :                                     rho_rad_s_d=r_s_d)
     647       376545 :                   drho_h = 0.0_dp
     648       376545 :                   drho_s = 0.0_dp
     649              :                ELSE
     650              :                   NULLIFY (r_h, r_s)
     651              :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
     652              :                   rho_d = 0.0_dp
     653              :                END IF
     654           15 :                IF (tau_f) THEN
     655              :                   !compute tau on the grid all at once
     656            0 :                   CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
     657              :                ELSE
     658           15 :                   tau_d = 0.0_dp
     659              :                END IF
     660              : 
     661          765 :                DO ir = 1, nr
     662              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
     663              :                                         ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
     664          750 :                                         r_h_d, r_s_d, drho_h, drho_s)
     665          765 :                   IF (donlcc) THEN
     666              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
     667            0 :                                         ir, rho_nlcc(:, 1), rho_h, rho_s, rho_nlcc(:, 2), drho_h, drho_s)
     668              :                   END IF
     669              :                END DO
     670          765 :                DO ir = 1, nr
     671          765 :                   IF (tau_f) THEN
     672            0 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
     673            0 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
     674              :                   ELSE IF (gradient_f) THEN
     675          750 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
     676          750 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
     677              :                   ELSE
     678              :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
     679              :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
     680              :                   END IF
     681              :                END DO
     682              : 
     683              :                !-------------------!
     684              :                ! hard atom density !
     685              :                !-------------------!
     686           15 :                CALL xc_dset_zero_all(deriv_set)
     687              :                CALL vxc_of_r_epr(xc_fun_section, rho_set_h, deriv_set, needs, weight_h, &
     688           15 :                                  lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h)
     689           15 :                rho_atom%exc_h = rho_atom%exc_h + exc_h
     690              : 
     691              :                !-------------------!
     692              :                ! soft atom density !
     693              :                !-------------------!
     694           15 :                CALL xc_dset_zero_all(deriv_set)
     695              :                CALL vxc_of_r_epr(xc_fun_section, rho_set_s, deriv_set, needs, weight_s, &
     696           15 :                                  lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s)
     697           15 :                rho_atom%exc_s = rho_atom%exc_s + exc_s
     698              : 
     699           45 :                DO ispin = 1, nspins
     700          135 :                   DO idir = 1, 3
     701         4620 :                      DO ir = 1, nr
     702       229590 :                         DO ia = 1, na
     703              :                            gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) = &
     704              :                               gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) &
     705       225000 :                               + vxg_h(idir, ia, ir, ispin)
     706              :                            gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) = &
     707              :                               gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) &
     708       229500 :                               + vxg_s(idir, ia, ir, ispin)
     709              :                         END DO ! ia
     710              :                      END DO ! ir
     711              :                   END DO ! idir
     712              :                END DO ! ispin
     713              : 
     714              :                ! Add contributions to the exc energy
     715              : 
     716           15 :                exc1 = exc1 + rho_atom%exc_h - rho_atom%exc_s
     717              : 
     718              :                ! Integration to get the matrix elements relative to the vxc_atom
     719              :                ! here the products with the primitives is done: gaVxcgb
     720              :                ! internal transformation to get the integral in cartesian Gaussians
     721              : 
     722           15 :                NULLIFY (int_hh, int_ss)
     723           15 :                CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
     724              :                IF (gradient_f) THEN
     725              :                   CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
     726           15 :                                   grid_atom, basis_1c, harmonics, nspins)
     727              :                ELSE
     728              :                   CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
     729              :                                     grid_atom, basis_1c, harmonics, nspins)
     730              :                END IF
     731           15 :                IF (tau_f) THEN
     732              :                   CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
     733            0 :                                   tau_basis_cache, nspins)
     734              :                END IF
     735           35 :                NULLIFY (r_h, r_s, dr_h, dr_s)
     736              :             END DO ! iat
     737              : 
     738           20 :             IF (tau_f) CALL release_tau_basis_cache(tau_basis_cache)
     739              : 
     740              :             ! Release the xc structure used to store the xc derivatives
     741           20 :             CALL xc_dset_release(deriv_set)
     742           20 :             CALL xc_rho_set_release(rho_set_h)
     743           70 :             CALL xc_rho_set_release(rho_set_s)
     744              :          END DO ! ikind
     745              : 
     746           10 :          CALL para_env%sum(exc1)
     747              : 
     748           10 :          IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
     749           10 :          IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
     750           10 :          IF (ASSOCIATED(vxc_h)) DEALLOCATE (vxc_h)
     751           10 :          IF (ASSOCIATED(vxc_s)) DEALLOCATE (vxc_s)
     752              : 
     753              :          IF (gradient_f) THEN
     754           10 :             IF (ASSOCIATED(drho_h)) DEALLOCATE (drho_h)
     755           10 :             IF (ASSOCIATED(drho_s)) DEALLOCATE (drho_s)
     756           10 :             IF (ASSOCIATED(vxg_h)) DEALLOCATE (vxg_h)
     757           10 :             IF (ASSOCIATED(vxg_s)) DEALLOCATE (vxg_s)
     758              :          END IF
     759              : 
     760           10 :          IF (tau_f) THEN
     761            0 :             IF (ASSOCIATED(tau_h)) DEALLOCATE (tau_h)
     762            0 :             IF (ASSOCIATED(tau_s)) DEALLOCATE (tau_s)
     763            0 :             IF (ASSOCIATED(vtau_h)) DEALLOCATE (vtau_h)
     764            0 :             IF (ASSOCIATED(vtau_s)) DEALLOCATE (vtau_s)
     765              :          END IF
     766              : 
     767              :       END IF !xc_none
     768              : 
     769           10 :       CALL timestop(handle)
     770              : 
     771          380 :    END SUBROUTINE calculate_vxc_atom_epr
     772              : 
     773              : ! **************************************************************************************************
     774              : !> \brief ...
     775              : !> \param rho_atom_set ...
     776              : !> \param rho1_atom_set ...
     777              : !> \param qs_env ...
     778              : !> \param xc_section ...
     779              : !> \param para_env ...
     780              : !> \param do_tddfpt2 New implementation of TDDFT.
     781              : !> \param do_triplet ...
     782              : !> \param do_sf ...
     783              : !> \param kind_set_external ...
     784              : ! **************************************************************************************************
     785         5860 :    SUBROUTINE calculate_xc_2nd_deriv_atom(rho_atom_set, rho1_atom_set, qs_env, xc_section, para_env, &
     786              :                                           do_tddfpt2, do_triplet, do_sf, kind_set_external)
     787              : 
     788              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho_atom_set, rho1_atom_set
     789              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     790              :       TYPE(section_vals_type), POINTER                   :: xc_section
     791              :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env
     792              :       LOGICAL, INTENT(IN), OPTIONAL                      :: do_tddfpt2, do_triplet, do_sf
     793              :       TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
     794              :          POINTER                                         :: kind_set_external
     795              : 
     796              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_xc_2nd_deriv_atom'
     797              : 
     798              :       INTEGER                                            :: atom, handle, iatom, ikind, ir, na, &
     799              :                                                             natom, nr, nspins
     800              :       INTEGER, DIMENSION(2)                              :: local_loop_limit
     801              :       INTEGER, DIMENSION(2, 3)                           :: bounds
     802         5860 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     803              :       LOGICAL                                            :: accint, gradient_functional, lsd, &
     804              :                                                             my_do_sf, paw_atom, scale_rho, tau_f
     805              :       REAL(KIND=dp)                                      :: agr, alpha, density_cut, gradient_cut, &
     806              :                                                             rtot, tau_cut
     807              :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), &
     808         5860 :          POINTER                                         :: vtau_h, vtau_s, vxc_h, vxc_s
     809              :       REAL(KIND=dp), DIMENSION(1, 1, 1)                  :: rtau
     810              :       REAL(KIND=dp), DIMENSION(1, 1, 1, 1)               :: rrho
     811         5860 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: weight_h, weight_s
     812        17580 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: rho1_h, rho1_s, rho_h, rho_s, tau1_h, &
     813         5860 :                                                             tau1_s, tau_h, tau_s
     814        11720 :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: drho1_h, drho1_s, drho_h, drho_s, vxg_h, &
     815         5860 :                                                             vxg_s
     816         5860 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     817              :       TYPE(dft_control_type), POINTER                    :: dft_control
     818              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
     819              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
     820              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
     821         5860 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: my_kind_set, qs_kind_set
     822         5860 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr1_h, dr1_s, dr_h, dr_s, int_hh, &
     823         5860 :                                                             int_ss, r1_h, r1_s, r_h, r_s
     824         5860 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r1_h_d, r1_s_d, r_h_d, r_s_d
     825              :       TYPE(rho_atom_type), POINTER                       :: rho1_atom, rho_atom
     826              :       TYPE(section_vals_type), POINTER                   :: input, xc_fun_section
     827         5860 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
     828              :       TYPE(xc_derivative_set_type)                       :: deriv_set
     829              :       TYPE(xc_rho_cflags_type)                           :: needs
     830              :       TYPE(xc_rho_set_type)                              :: rho1_set_h, rho1_set_s, rho_set_h, &
     831              :                                                             rho_set_s
     832              : 
     833              : ! -------------------------------------------------------------------------
     834              : 
     835         5860 :       CALL timeset(routineN, handle)
     836              : 
     837         5860 :       NULLIFY (qs_kind_set)
     838         5860 :       NULLIFY (rho_h, rho_s, drho_h, drho_s, weight_h, weight_s)
     839         5860 :       NULLIFY (rho1_h, rho1_s, drho1_h, drho1_s)
     840         5860 :       NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
     841         5860 :       NULLIFY (tau_h, tau_s, tau1_h, tau1_s, vtau_h, vtau_s)
     842              : 
     843              :       CALL get_qs_env(qs_env=qs_env, &
     844              :                       input=input, &
     845              :                       dft_control=dft_control, &
     846              :                       qs_kind_set=qs_kind_set, &
     847         5860 :                       atomic_kind_set=atomic_kind_set)
     848              : 
     849         5860 :       IF (PRESENT(kind_set_external)) THEN
     850          616 :          my_kind_set => kind_set_external
     851              :       ELSE
     852         5244 :          my_kind_set => qs_kind_set
     853              :       END IF
     854              : 
     855         5860 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
     856              : 
     857         5860 :       CALL section_vals_val_get(input, "DFT%LSD", l_val=lsd)
     858              :       CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", &
     859         5860 :                                 r_val=density_cut)
     860              :       CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", &
     861         5860 :                                 r_val=gradient_cut)
     862              :       CALL section_vals_val_get(xc_section, "TAU_CUTOFF", &
     863         5860 :                                 r_val=tau_cut)
     864              : 
     865         5860 :       my_do_sf = .FALSE.
     866         5860 :       IF (PRESENT(do_sf)) my_do_sf = do_sf
     867              : 
     868              :       xc_fun_section => section_vals_get_subs_vals(xc_section, &
     869         5860 :                                                    "XC_FUNCTIONAL")
     870         5860 :       IF (lsd) THEN
     871          134 :          nspins = 2
     872              :       ELSE
     873         5726 :          nspins = 1
     874              :       END IF
     875              : 
     876         5860 :       scale_rho = .FALSE.
     877         5860 :       IF (PRESENT(do_tddfpt2) .AND. PRESENT(do_triplet)) THEN
     878         2876 :          IF (nspins == 1 .AND. do_triplet) THEN
     879          310 :             lsd = .TRUE.
     880          310 :             scale_rho = .TRUE.
     881              :          END IF
     882         2984 :       ELSEIF (PRESENT(do_triplet)) THEN
     883         2686 :          IF (nspins == 1 .AND. do_triplet) lsd = .TRUE.
     884              :       END IF
     885              : 
     886              :       needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, &
     887         5860 :                                        calc_potential=.TRUE.)
     888         5860 :       gradient_functional = needs%drho .OR. needs%drho_spin
     889         5860 :       tau_f = (needs%tau .OR. needs%tau_spin)
     890         5860 :       IF (.NOT. tau_f) rtau = 0.0_dp
     891              : 
     892              :       !  Here starts the loop over all the atoms
     893        18638 :       DO ikind = 1, SIZE(atomic_kind_set)
     894              : 
     895        12778 :          NULLIFY (atom_list, harmonics, grid_atom)
     896        12778 :          CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     897              :          CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     898        12778 :                           harmonics=harmonics, grid_atom=grid_atom)
     899        12778 :          CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
     900        12778 :          IF (.NOT. paw_atom) CYCLE
     901              : 
     902        12070 :          nr = grid_atom%nr
     903        12070 :          na = grid_atom%ng_sphere
     904              : 
     905              :          ! set integration weights
     906        12070 :          IF (accint) THEN
     907         4772 :             weight_h => grid_atom%weight
     908         4772 :             alpha = dft_control%qs_control%gapw_control%aw(ikind)
     909         4772 :             IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     910         4768 :                IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
     911              :             END IF
     912         4772 :             IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     913           16 :                ALLOCATE (grid_atom%gapw_weight_s(na, nr))
     914          204 :                DO ir = 1, nr
     915          200 :                   agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
     916        10204 :                   grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
     917              :                END DO
     918            4 :                grid_atom%gapw_weight_alpha = alpha
     919              :             END IF
     920         4772 :             weight_s => grid_atom%gapw_weight_s
     921              :          ELSE
     922         7298 :             weight_h => grid_atom%weight
     923         7298 :             weight_s => grid_atom%weight
     924              :          END IF
     925              : 
     926              :          ! Array dimension: here anly one dimensional arrays are used,
     927              :          ! i.e. only the first column of deriv_data is read.
     928              :          ! The other to dimensions  are set to size equal 1.
     929       120700 :          bounds(1:2, 1:3) = 1
     930        12070 :          bounds(2, 1) = na
     931        12070 :          bounds(2, 2) = nr
     932              : 
     933        12070 :          CALL xc_dset_create(deriv_set, local_bounds=bounds)
     934              :          CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
     935        12070 :                                 drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     936              :          CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
     937        12070 :                                 drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     938              :          CALL xc_rho_set_create(rho1_set_h, bounds, rho_cutoff=density_cut, &
     939        12070 :                                 drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     940              :          CALL xc_rho_set_create(rho1_set_s, bounds, rho_cutoff=density_cut, &
     941        12070 :                                 drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     942              : 
     943              :          ! allocate the required 3d arrays where to store rho and drho
     944        12070 :          IF (nspins == 1 .AND. .NOT. lsd) THEN
     945        11292 :             CALL xc_rho_set_atom_update(rho_set_h, needs, 1, bounds)
     946        11292 :             CALL xc_rho_set_atom_update(rho1_set_h, needs, 1, bounds)
     947        11292 :             CALL xc_rho_set_atom_update(rho_set_s, needs, 1, bounds)
     948        11292 :             CALL xc_rho_set_atom_update(rho1_set_s, needs, 1, bounds)
     949              :          ELSE
     950          778 :             CALL xc_rho_set_atom_update(rho_set_h, needs, 2, bounds)
     951          778 :             CALL xc_rho_set_atom_update(rho1_set_h, needs, 2, bounds)
     952          778 :             CALL xc_rho_set_atom_update(rho_set_s, needs, 2, bounds)
     953          778 :             CALL xc_rho_set_atom_update(rho1_set_s, needs, 2, bounds)
     954              :          END IF
     955              : 
     956              :          ALLOCATE (rho_h(1:na, 1:nr, 1:nspins), rho1_h(1:na, 1:nr, 1:nspins), &
     957       168980 :                    rho_s(1:na, 1:nr, 1:nspins), rho1_s(1:na, 1:nr, 1:nspins))
     958              : 
     959        84490 :          ALLOCATE (vxc_h(1:na, 1:nr, 1:nspins), vxc_s(1:na, 1:nr, 1:nspins))
     960     31404676 :          vxc_h = 0.0_dp
     961     31404676 :          vxc_s = 0.0_dp
     962              : 
     963        12070 :          IF (tau_f) THEN
     964            0 :             CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
     965              :             ALLOCATE (tau_h(1:na, 1:nr, 1:nspins), tau1_h(1:na, 1:nr, 1:nspins), &
     966            0 :                       tau_s(1:na, 1:nr, 1:nspins), tau1_s(1:na, 1:nr, 1:nspins))
     967            0 :             ALLOCATE (vtau_h(1:na, 1:nr, 1:nspins), vtau_s(1:na, 1:nr, 1:nspins))
     968              :          END IF
     969              : 
     970        12070 :          IF (gradient_functional) THEN
     971              :             ALLOCATE (drho_h(1:4, 1:na, 1:nr, 1:nspins), drho1_h(1:4, 1:na, 1:nr, 1:nspins), &
     972       120904 :                       drho_s(1:4, 1:na, 1:nr, 1:nspins), drho1_s(1:4, 1:na, 1:nr, 1:nspins))
     973        69088 :             ALLOCATE (vxg_h(1:3, 1:na, 1:nr, 1:nspins), vxg_s(1:3, 1:na, 1:nr, 1:nspins))
     974              :          ELSE
     975              :             ALLOCATE (drho_h(1, 1, 1, 1), drho1_h(1, 1, 1, 1), &
     976         3434 :                       drho_s(1, 1, 1, 1), drho1_s(1, 1, 1, 1))
     977         3434 :             ALLOCATE (vxg_h(1, 1, 1, 1), vxg_s(1, 1, 1, 1))
     978         3434 :             rrho = 0.0_dp
     979              :          END IF
     980     88997258 :          vxg_h = 0.0_dp
     981     88997258 :          vxg_s = 0.0_dp
     982              : 
     983              :          ! parallelization
     984        12070 :          local_loop_limit = get_limit(natom, para_env%num_pe, para_env%mepos)
     985              : 
     986        20660 :          DO iatom = local_loop_limit(1), local_loop_limit(2) !1,natom
     987         8590 :             atom = atom_list(iatom)
     988              : 
     989         8590 :             rho_atom_set(atom)%exc_h = 0.0_dp
     990         8590 :             rho_atom_set(atom)%exc_s = 0.0_dp
     991         8590 :             rho1_atom_set(atom)%exc_h = 0.0_dp
     992         8590 :             rho1_atom_set(atom)%exc_s = 0.0_dp
     993              : 
     994         8590 :             rho_atom => rho_atom_set(atom)
     995         8590 :             rho1_atom => rho1_atom_set(atom)
     996         8590 :             NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
     997         8590 :             NULLIFY (r1_h, r1_s, dr1_h, dr1_s, r1_h_d, r1_s_d)
     998     22416574 :             rho_h = 0.0_dp
     999     22416574 :             rho_s = 0.0_dp
    1000     22416574 :             rho1_h = 0.0_dp
    1001     22416574 :             rho1_s = 0.0_dp
    1002         8590 :             IF (gradient_functional) THEN
    1003              :                CALL get_rho_atom(rho_atom=rho_atom, &
    1004              :                                  rho_rad_h=r_h, rho_rad_s=r_s, &
    1005              :                                  drho_rad_h=dr_h, drho_rad_s=dr_s, &
    1006         6178 :                                  rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    1007              :                CALL get_rho_atom(rho_atom=rho1_atom, &
    1008              :                                  rho_rad_h=r1_h, rho_rad_s=r1_s, &
    1009              :                                  drho_rad_h=dr1_h, drho_rad_s=dr1_s, &
    1010         6178 :                                  rho_rad_h_d=r1_h_d, rho_rad_s_d=r1_s_d)
    1011    159705102 :                drho_h = 0.0_dp; drho_s = 0.0_dp
    1012    159705102 :                drho1_h = 0.0_dp; drho1_s = 0.0_dp
    1013              :             ELSE
    1014              :                CALL get_rho_atom(rho_atom=rho_atom, &
    1015         2412 :                                  rho_rad_h=r_h, rho_rad_s=r_s)
    1016              :                CALL get_rho_atom(rho_atom=rho1_atom, &
    1017         2412 :                                  rho_rad_h=r1_h, rho_rad_s=r1_s)
    1018              :             END IF
    1019              : 
    1020         8590 :             rtot = 0.0_dp
    1021              : 
    1022       438090 :             DO ir = 1, nr
    1023              :                CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_functional, &
    1024              :                                      ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, r_h_d, r_s_d, &
    1025       429500 :                                      drho_h, drho_s)
    1026              :                CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_functional, &
    1027              :                                      ir, r1_h, r1_s, rho1_h, rho1_s, dr1_h, dr1_s, r1_h_d, r1_s_d, &
    1028       438090 :                                      drho1_h, drho1_s)
    1029              :             END DO
    1030         8590 :             IF (tau_f) THEN
    1031            0 :                CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
    1032            0 :                CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, tau_basis_cache, nspins)
    1033              :             END IF
    1034         8590 :             IF (scale_rho) THEN
    1035       926376 :                rho_h = 2.0_dp*rho_h
    1036       926376 :                rho_s = 2.0_dp*rho_s
    1037          363 :                IF (gradient_functional) THEN
    1038      3426696 :                   drho_h = 2.0_dp*drho_h
    1039      3426696 :                   drho_s = 2.0_dp*drho_s
    1040              :                END IF
    1041          363 :                IF (tau_f) THEN
    1042            0 :                   tau_h = 2.0_dp*tau_h
    1043            0 :                   tau_s = 2.0_dp*tau_s
    1044              :                END IF
    1045              :             END IF
    1046              : 
    1047       438090 :             DO ir = 1, nr
    1048       438090 :                IF (tau_f) THEN
    1049            0 :                   CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
    1050            0 :                   CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau1_h, na, ir)
    1051            0 :                   CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
    1052            0 :                   CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau1_s, na, ir)
    1053       429500 :                ELSE IF (gradient_functional) THEN
    1054       308900 :                   CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, rtau, na, ir)
    1055       308900 :                   CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, rtau, na, ir)
    1056       308900 :                   CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, rtau, na, ir)
    1057       308900 :                   CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, rtau, na, ir)
    1058              :                ELSE
    1059       120600 :                   CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rrho, rtau, na, ir)
    1060       120600 :                   CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, rrho, rtau, na, ir)
    1061       120600 :                   CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rrho, rtau, na, ir)
    1062       120600 :                   CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, rrho, rtau, na, ir)
    1063              :                END IF
    1064              :             END DO
    1065              : 
    1066              :             CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
    1067              :                                    rho_set=rho_set_h, rho1_set=rho1_set_h, &
    1068              :                                    deriv_set=deriv_set, &
    1069              :                                    w=weight_h, vxc=vxc_h, vxg=vxg_h, vtau=vtau_h, do_triplet=do_triplet, &
    1070         8590 :                                    do_sf=my_do_sf)
    1071              :             CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
    1072              :                                    rho_set=rho_set_s, rho1_set=rho1_set_s, &
    1073              :                                    deriv_set=deriv_set, &
    1074              :                                    w=weight_s, vxc=vxc_s, vxg=vxg_s, vtau=vtau_s, do_triplet=do_triplet, &
    1075         8590 :                                    do_sf=my_do_sf)
    1076              : 
    1077         8590 :             CALL get_rho_atom(rho_atom=rho1_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    1078         8590 :             IF (gradient_functional) THEN
    1079              :                CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    1080         6178 :                                grid_atom, basis_1c, harmonics, nspins)
    1081              :             ELSE
    1082              :                CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
    1083         2412 :                                  grid_atom, basis_1c, harmonics, nspins)
    1084              :             END IF
    1085         8590 :             IF (tau_f) THEN
    1086              :                CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
    1087            0 :                                tau_basis_cache, nspins)
    1088              :             END IF
    1089              : 
    1090        20660 :             NULLIFY (r_h, r_s, dr_h, dr_s)
    1091              : 
    1092              :          END DO
    1093              : 
    1094              :          ! some cleanup
    1095        12070 :          DEALLOCATE (rho_h, rho_s, rho1_h, rho1_s, vxc_h, vxc_s)
    1096        12070 :          DEALLOCATE (drho_h, drho_s, vxg_h, vxg_s)
    1097        12070 :          DEALLOCATE (drho1_h, drho1_s)
    1098        12070 :          IF (tau_f) THEN
    1099            0 :             DEALLOCATE (tau_h, tau_s, tau1_h, tau1_s)
    1100            0 :             DEALLOCATE (vtau_h, vtau_s)
    1101            0 :             CALL release_tau_basis_cache(tau_basis_cache)
    1102              :          END IF
    1103              : 
    1104        12070 :          CALL xc_dset_release(deriv_set)
    1105        12070 :          CALL xc_rho_set_release(rho_set_h)
    1106        12070 :          CALL xc_rho_set_release(rho1_set_h)
    1107        12070 :          CALL xc_rho_set_release(rho_set_s)
    1108        43486 :          CALL xc_rho_set_release(rho1_set_s)
    1109              :       END DO
    1110              : 
    1111         5860 :       CALL timestop(handle)
    1112              : 
    1113       433640 :    END SUBROUTINE calculate_xc_2nd_deriv_atom
    1114              : 
    1115              : ! **************************************************************************************************
    1116              : !> \brief ...
    1117              : !> \param qs_env ...
    1118              : !> \param rho0_atom_set ...
    1119              : !> \param rho1_atom_set ...
    1120              : !> \param rho2_atom_set ...
    1121              : !> \param kind_set ...
    1122              : !> \param xc_section ...
    1123              : !> \param is_triplet ...
    1124              : !> \param accuracy ...
    1125              : ! **************************************************************************************************
    1126            0 :    SUBROUTINE calculate_gfxc_atom(qs_env, rho0_atom_set, rho1_atom_set, rho2_atom_set, &
    1127              :                                   kind_set, xc_section, is_triplet, accuracy)
    1128              : 
    1129              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1130              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set, rho1_atom_set, &
    1131              :                                                             rho2_atom_set
    1132              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: kind_set
    1133              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: xc_section
    1134              :       LOGICAL, INTENT(IN)                                :: is_triplet
    1135              :       INTEGER, INTENT(IN)                                :: accuracy
    1136              : 
    1137              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_gfxc_atom'
    1138              :       REAL(KIND=dp), PARAMETER                           :: epsrho = 5.e-4_dp
    1139              : 
    1140              :       INTEGER                                            :: bo(2), handle, iat, iatom, ikind, ir, &
    1141              :                                                             istep, mspins, myfun, na, natom, nf, &
    1142              :                                                             nr, ns, nspins, nstep, num_pe
    1143              :       INTEGER, DIMENSION(2, 3)                           :: bounds
    1144            0 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
    1145              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
    1146              :                                                             paw_atom, tau_f
    1147              :       REAL(dp)                                           :: agr, alpha, beta, density_cut, exc_h, &
    1148              :                                                             exc_s, gradient_cut, oeps1, oeps2, &
    1149              :                                                             tau_cut
    1150              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
    1151              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
    1152            0 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
    1153            0 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho0_h, rho0_s, rho1_h, rho1_s, rho_h, &
    1154            0 :                                                             rho_s, tau0_h, tau0_s, tau1_h, tau1_s, &
    1155            0 :                                                             tau_h, tau_s, vtau_h, vtau_s, vxc_h, &
    1156            0 :                                                             vxc_s
    1157            0 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho0_h, drho0_s, drho1_h, drho1_s, &
    1158            0 :                                                             drho_h, drho_s, vxg_h, vxg_s
    1159              :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak, bl
    1160            0 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1161              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1162              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    1163              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    1164              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    1165              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1166            0 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, fint_hh, fint_ss, int_hh, &
    1167            0 :                                                             int_ss, r_h, r_s
    1168            0 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    1169              :       TYPE(rho_atom_type), POINTER                       :: rho0_atom, rho1_atom, rho2_atom
    1170              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
    1171            0 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
    1172              :       TYPE(xc_derivative_set_type)                       :: deriv_set
    1173              :       TYPE(xc_rho_cflags_type)                           :: needs
    1174              :       TYPE(xc_rho_set_type)                              :: rho_set_h, rho_set_s
    1175              : 
    1176            0 :       CALL timeset(routineN, handle)
    1177              : 
    1178            0 :       NULLIFY (vtau_h, vtau_s)
    1179              : 
    1180            0 :       ak = 0.0_dp
    1181            0 :       bl = 0.0_dp
    1182            0 :       SELECT CASE (accuracy)
    1183              :       CASE (:4)
    1184            0 :          nstep = 2
    1185            0 :          ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
    1186            0 :          bl(-2:2) = [-1.0_dp, 16.0_dp, -30.0_dp, 16.0_dp, -1.0_dp]/12.0_dp
    1187              :       CASE (5:7)
    1188            0 :          nstep = 3
    1189            0 :          ak(-3:3) = [-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp]/60.0_dp
    1190            0 :          bl(-3:3) = [2.0_dp, -27.0_dp, 270.0_dp, -490.0_dp, 270.0_dp, -27.0_dp, 2.0_dp]/180.0_dp
    1191              :       CASE (8:)
    1192            0 :          nstep = 4
    1193              :          ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
    1194            0 :                      224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
    1195              :          bl(-4:4) = [-1.0_dp, 128.0_dp/9.0_dp, -112.0_dp, 896.0_dp, -14350.0_dp/9.0_dp, &
    1196            0 :                      896.0_dp, -112.0_dp, 128.0_dp/9.0_dp, -1.0_dp]/560.0_dp
    1197              :       END SELECT
    1198            0 :       oeps1 = 1.0_dp/epsrho
    1199            0 :       oeps2 = 1.0_dp/(epsrho**2)
    1200              : 
    1201              :       CALL get_qs_env(qs_env=qs_env, &
    1202              :                       dft_control=dft_control, &
    1203              :                       para_env=para_env, &
    1204            0 :                       atomic_kind_set=atomic_kind_set)
    1205              : 
    1206            0 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
    1207            0 :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", i_val=myfun)
    1208              : 
    1209            0 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
    1210              : 
    1211            0 :       IF (myfun == xc_none) THEN
    1212              :          ! no action needed?
    1213              :       ELSE
    1214            0 :          CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", r_val=density_cut)
    1215            0 :          CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", r_val=gradient_cut)
    1216            0 :          CALL section_vals_val_get(xc_section, "TAU_CUTOFF", r_val=tau_cut)
    1217              : 
    1218            0 :          nlcc = has_nlcc(kind_set)
    1219            0 :          lsd = dft_control%lsd
    1220            0 :          nspins = dft_control%nspins
    1221            0 :          mspins = nspins
    1222            0 :          IF (is_triplet) THEN
    1223            0 :             CPASSERT(nspins == 1)
    1224            0 :             lsd = .TRUE.
    1225            0 :             mspins = 2
    1226              :          END IF
    1227            0 :          needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, calc_potential=.TRUE.)
    1228            0 :          gradient_f = (needs%drho .OR. needs%drho_spin)
    1229            0 :          tau_f = (needs%tau .OR. needs%tau_spin)
    1230              : 
    1231              :          ! Here starts the loop over all the atoms
    1232            0 :          DO ikind = 1, SIZE(atomic_kind_set)
    1233            0 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    1234              :             CALL get_qs_kind(kind_set(ikind), paw_atom=paw_atom, &
    1235            0 :                              harmonics=harmonics, grid_atom=grid_atom)
    1236            0 :             CALL get_qs_kind(kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    1237              : 
    1238            0 :             IF (.NOT. paw_atom) CYCLE
    1239              : 
    1240            0 :             nr = grid_atom%nr
    1241            0 :             na = grid_atom%ng_sphere
    1242              : 
    1243              :             ! set integration weights
    1244            0 :             IF (accint) THEN
    1245            0 :                weight_h => grid_atom%weight
    1246            0 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
    1247            0 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    1248            0 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
    1249              :                END IF
    1250            0 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    1251            0 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
    1252            0 :                   DO ir = 1, nr
    1253            0 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
    1254            0 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
    1255              :                   END DO
    1256            0 :                   grid_atom%gapw_weight_alpha = alpha
    1257              :                END IF
    1258            0 :                weight_s => grid_atom%gapw_weight_s
    1259              :             ELSE
    1260            0 :                weight_h => grid_atom%weight
    1261            0 :                weight_s => grid_atom%weight
    1262              :             END IF
    1263              : 
    1264              :             ! Prepare the structures needed to calculate and store the xc derivatives
    1265              : 
    1266              :             ! Array dimension: here anly one dimensional arrays are used,
    1267              :             ! i.e. only the first column of deriv_data is read.
    1268              :             ! The other to dimensions  are set to size equal 1
    1269            0 :             bounds(1:2, 1:3) = 1
    1270            0 :             bounds(2, 1) = na
    1271            0 :             bounds(2, 2) = nr
    1272              : 
    1273              :             ! create a place where to put the derivatives
    1274            0 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
    1275              :             ! create the place where to store the argument for the functionals
    1276              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
    1277            0 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    1278              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
    1279            0 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    1280              : 
    1281              :             ! allocate the required 3d arrays where to store rho and drho
    1282            0 :             CALL xc_rho_set_atom_update(rho_set_h, needs, mspins, bounds)
    1283            0 :             CALL xc_rho_set_atom_update(rho_set_s, needs, mspins, bounds)
    1284              : 
    1285              :             ALLOCATE (rho_h(na, nr, mspins), rho_s(na, nr, mspins), &
    1286              :                       rho0_h(na, nr, nspins), rho0_s(na, nr, nspins), &
    1287            0 :                       rho1_h(na, nr, nspins), rho1_s(na, nr, nspins))
    1288            0 :             ALLOCATE (vxc_h(na, nr, mspins), vxc_s(na, nr, mspins))
    1289            0 :             IF (gradient_f) THEN
    1290              :                ALLOCATE (drho_h(4, na, nr, mspins), drho_s(4, na, nr, mspins), &
    1291              :                          drho0_h(4, na, nr, nspins), drho0_s(4, na, nr, nspins), &
    1292            0 :                          drho1_h(4, na, nr, nspins), drho1_s(4, na, nr, nspins))
    1293            0 :                ALLOCATE (vxg_h(3, na, nr, mspins), vxg_s(3, na, nr, mspins))
    1294              :             END IF
    1295            0 :             IF (tau_f) THEN
    1296            0 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    1297              :                ALLOCATE (tau_h(na, nr, mspins), tau_s(na, nr, mspins), &
    1298              :                          tau0_h(na, nr, nspins), tau0_s(na, nr, nspins), &
    1299            0 :                          tau1_h(na, nr, nspins), tau1_s(na, nr, nspins))
    1300            0 :                ALLOCATE (vtau_h(na, nr, mspins), vtau_s(na, nr, mspins))
    1301              :             END IF
    1302              :             !
    1303              :             ! NLCC: prepare rho and drho of the core charge for this KIND
    1304            0 :             donlcc = .FALSE.
    1305            0 :             IF (nlcc) THEN
    1306            0 :                NULLIFY (rho_nlcc)
    1307            0 :                rho_nlcc => kind_set(ikind)%nlcc_pot
    1308            0 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
    1309              :             END IF
    1310              : 
    1311              :             ! Distribute the atoms of this kind
    1312            0 :             num_pe = para_env%num_pe
    1313            0 :             bo = get_limit(natom, num_pe, para_env%mepos)
    1314              : 
    1315            0 :             DO iat = bo(1), bo(2)
    1316            0 :                iatom = atom_list(iat)
    1317              :                !
    1318            0 :                NULLIFY (int_hh, int_ss)
    1319            0 :                rho0_atom => rho0_atom_set(iatom)
    1320            0 :                CALL get_rho_atom(rho_atom=rho0_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    1321            0 :                ALLOCATE (fint_ss(nspins), fint_hh(nspins))
    1322            0 :                DO ns = 1, nspins
    1323            0 :                   nf = SIZE(int_ss(ns)%r_coef, 1)
    1324            0 :                   ALLOCATE (fint_ss(ns)%r_coef(nf, nf))
    1325            0 :                   nf = SIZE(int_hh(ns)%r_coef, 1)
    1326            0 :                   ALLOCATE (fint_hh(ns)%r_coef(nf, nf))
    1327              :                END DO
    1328              : 
    1329              :                ! RHO0
    1330            0 :                rho0_h = 0.0_dp
    1331            0 :                rho0_s = 0.0_dp
    1332            0 :                rho0_atom => rho0_atom_set(iatom)
    1333            0 :                IF (gradient_f) THEN
    1334            0 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    1335              :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    1336            0 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    1337            0 :                   drho0_h = 0.0_dp
    1338            0 :                   drho0_s = 0.0_dp
    1339              :                ELSE
    1340            0 :                   NULLIFY (r_h, r_s)
    1341            0 :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    1342            0 :                   rho_d = 0.0_dp
    1343              :                END IF
    1344            0 :                DO ir = 1, nr
    1345              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    1346              :                                         ir, r_h, r_s, rho0_h, rho0_s, dr_h, dr_s, &
    1347            0 :                                         r_h_d, r_s_d, drho0_h, drho0_s)
    1348            0 :                   IF (donlcc) THEN
    1349              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
    1350            0 :                                         ir, rho_nlcc(:, 1), rho0_h, rho0_s, rho_nlcc(:, 2), drho0_h, drho0_s)
    1351              :                   END IF
    1352              :                END DO
    1353            0 :                IF (tau_f) THEN
    1354              :                   !compute tau on the grid all at once
    1355            0 :                   CALL calc_tau_atom(tau0_h, tau0_s, rho0_atom, tau_basis_cache, nspins)
    1356              :                ELSE
    1357            0 :                   tau_d = 0.0_dp
    1358              :                END IF
    1359              :                ! RHO1
    1360            0 :                rho1_h = 0.0_dp
    1361            0 :                rho1_s = 0.0_dp
    1362            0 :                rho1_atom => rho1_atom_set(iatom)
    1363            0 :                IF (gradient_f) THEN
    1364            0 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    1365              :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    1366            0 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    1367            0 :                   drho1_h = 0.0_dp
    1368            0 :                   drho1_s = 0.0_dp
    1369              :                ELSE
    1370            0 :                   NULLIFY (r_h, r_s)
    1371            0 :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    1372              :                END IF
    1373            0 :                DO ir = 1, nr
    1374              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    1375              :                                         ir, r_h, r_s, rho1_h, rho1_s, dr_h, dr_s, &
    1376            0 :                                         r_h_d, r_s_d, drho1_h, drho1_s)
    1377              :                END DO
    1378            0 :                IF (tau_f) THEN
    1379              :                   !compute tau on the grid all at once
    1380            0 :                   CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, tau_basis_cache, nspins)
    1381              :                END IF
    1382              :                ! RHO2
    1383            0 :                rho2_atom => rho2_atom_set(iatom)
    1384              : 
    1385            0 :                DO istep = -nstep, nstep
    1386              : 
    1387            0 :                   beta = REAL(istep, KIND=dp)*epsrho
    1388              : 
    1389            0 :                   IF (is_triplet) THEN
    1390            0 :                      rho_h(:, :, 1) = rho0_h(:, :, 1) + beta*rho1_h(:, :, 1)
    1391            0 :                      rho_h(:, :, 2) = rho0_h(:, :, 1)
    1392            0 :                      rho_h = 0.5_dp*rho_h
    1393            0 :                      rho_s(:, :, 1) = rho0_s(:, :, 1) + beta*rho1_s(:, :, 1)
    1394            0 :                      rho_s(:, :, 2) = rho0_s(:, :, 1)
    1395            0 :                      rho_s = 0.5_dp*rho_s
    1396            0 :                      IF (gradient_f) THEN
    1397            0 :                         drho_h(:, :, :, 1) = drho0_h(:, :, :, 1) + beta*drho1_h(:, :, :, 1)
    1398            0 :                         drho_h(:, :, :, 2) = drho0_h(:, :, :, 1)
    1399            0 :                         drho_h = 0.5_dp*drho_h
    1400            0 :                         drho_s(:, :, :, 1) = drho0_s(:, :, :, 1) + beta*drho1_s(:, :, :, 1)
    1401            0 :                         drho_s(:, :, :, 2) = drho0_s(:, :, :, 1)
    1402            0 :                         drho_s = 0.5_dp*drho_s
    1403              :                      END IF
    1404            0 :                      IF (tau_f) THEN
    1405            0 :                         tau_h(:, :, 1) = tau0_h(:, :, 1) + beta*tau1_h(:, :, 1)
    1406            0 :                         tau_h(:, :, 2) = tau0_h(:, :, 1)
    1407            0 :                         tau_h = 0.5_dp*tau0_h
    1408            0 :                         tau_s(:, :, 1) = tau0_s(:, :, 1) + beta*tau1_s(:, :, 1)
    1409            0 :                         tau_s(:, :, 2) = tau0_s(:, :, 1)
    1410            0 :                         tau_s = 0.5_dp*tau0_s
    1411              :                      END IF
    1412              :                   ELSE
    1413            0 :                      rho_h = rho0_h + beta*rho1_h
    1414            0 :                      rho_s = rho0_s + beta*rho1_s
    1415            0 :                      IF (gradient_f) THEN
    1416            0 :                         drho_h = drho0_h + beta*drho1_h
    1417            0 :                         drho_s = drho0_s + beta*drho1_s
    1418              :                      END IF
    1419            0 :                      IF (tau_f) THEN
    1420            0 :                         tau_h = tau0_h + beta*tau1_h
    1421            0 :                         tau_s = tau0_s + beta*tau1_s
    1422              :                      END IF
    1423              :                   END IF
    1424              :                   !
    1425            0 :                   IF (gradient_f) THEN
    1426              :                      drho_h(4, :, :, :) = SQRT( &
    1427              :                                           drho_h(1, :, :, :)*drho_h(1, :, :, :) + &
    1428              :                                           drho_h(2, :, :, :)*drho_h(2, :, :, :) + &
    1429            0 :                                           drho_h(3, :, :, :)*drho_h(3, :, :, :))
    1430              : 
    1431              :                      drho_s(4, :, :, :) = SQRT( &
    1432              :                                           drho_s(1, :, :, :)*drho_s(1, :, :, :) + &
    1433              :                                           drho_s(2, :, :, :)*drho_s(2, :, :, :) + &
    1434            0 :                                           drho_s(3, :, :, :)*drho_s(3, :, :, :))
    1435              :                   END IF
    1436              : 
    1437            0 :                   DO ir = 1, nr
    1438            0 :                      IF (tau_f) THEN
    1439            0 :                         CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, drho_h, tau_h, na, ir)
    1440            0 :                         CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, drho_s, tau_s, na, ir)
    1441            0 :                      ELSE IF (gradient_f) THEN
    1442            0 :                         CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, drho_h, tau_d, na, ir)
    1443            0 :                         CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, drho_s, tau_d, na, ir)
    1444              :                      ELSE
    1445            0 :                         CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, rho_d, tau_d, na, ir)
    1446            0 :                         CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, rho_d, tau_d, na, ir)
    1447              :                      END IF
    1448              :                   END DO
    1449              : 
    1450              :                   ! hard atom density !
    1451            0 :                   CALL xc_dset_zero_all(deriv_set)
    1452              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_h, deriv_set, 1, needs, weight_h, &
    1453            0 :                                     lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h)
    1454            0 :                   IF (is_triplet) THEN
    1455            0 :                      vxc_h(:, :, 1) = vxc_h(:, :, 1) - vxc_h(:, :, 2)
    1456            0 :                      IF (gradient_f) THEN
    1457            0 :                         vxg_h(:, :, :, 1) = vxg_h(:, :, :, 1) - vxg_h(:, :, :, 2)
    1458              :                      END IF
    1459            0 :                      IF (tau_f) THEN
    1460            0 :                         vtau_h(:, :, 1) = vtau_h(:, :, 1) - vtau_h(:, :, 2)
    1461              :                      END IF
    1462              :                   END IF
    1463              :                   ! soft atom density !
    1464            0 :                   CALL xc_dset_zero_all(deriv_set)
    1465              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_s, deriv_set, 1, needs, weight_s, &
    1466            0 :                                     lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s)
    1467            0 :                   IF (is_triplet) THEN
    1468            0 :                      vxc_s(:, :, 1) = vxc_s(:, :, 1) - vxc_s(:, :, 2)
    1469            0 :                      IF (gradient_f) THEN
    1470            0 :                         vxg_s(:, :, :, 1) = vxg_s(:, :, :, 1) - vxg_s(:, :, :, 2)
    1471              :                      END IF
    1472            0 :                      IF (tau_f) THEN
    1473            0 :                         vtau_s(:, :, 1) = vtau_s(:, :, 1) - vtau_s(:, :, 2)
    1474              :                      END IF
    1475              :                   END IF
    1476              :                   ! potentials
    1477            0 :                   DO ns = 1, nspins
    1478            0 :                      fint_hh(ns)%r_coef(:, :) = 0.0_dp
    1479            0 :                      fint_ss(ns)%r_coef(:, :) = 0.0_dp
    1480              :                   END DO
    1481            0 :                   IF (gradient_f) THEN
    1482              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, fint_hh, fint_ss, &
    1483            0 :                                      grid_atom, basis_1c, harmonics, nspins)
    1484              :                   ELSE
    1485              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, fint_hh, fint_ss, &
    1486            0 :                                        grid_atom, basis_1c, harmonics, nspins)
    1487              :                   END IF
    1488            0 :                   IF (tau_f) THEN
    1489              :                      CALL dgaVtaudgb(vtau_h, vtau_s, fint_hh, fint_ss, &
    1490            0 :                                      tau_basis_cache, nspins)
    1491              :                   END IF
    1492              :                   ! first derivative fxc
    1493            0 :                   NULLIFY (int_hh, int_ss)
    1494            0 :                   CALL get_rho_atom(rho_atom=rho1_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    1495            0 :                   DO ns = 1, nspins
    1496            0 :                      int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_ss(ns)%r_coef(:, :)
    1497            0 :                      int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_hh(ns)%r_coef(:, :)
    1498              :                   END DO
    1499              :                   ! second derivative gxc
    1500            0 :                   NULLIFY (int_hh, int_ss)
    1501            0 :                   CALL get_rho_atom(rho_atom=rho2_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    1502            0 :                   DO ns = 1, nspins
    1503            0 :                      int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps2*bl(istep)*fint_ss(ns)%r_coef(:, :)
    1504            0 :                      int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps2*bl(istep)*fint_hh(ns)%r_coef(:, :)
    1505              :                   END DO
    1506              :                END DO
    1507              :                !
    1508            0 :                DO ns = 1, nspins
    1509            0 :                   DEALLOCATE (fint_ss(ns)%r_coef)
    1510            0 :                   DEALLOCATE (fint_hh(ns)%r_coef)
    1511              :                END DO
    1512            0 :                DEALLOCATE (fint_ss, fint_hh)
    1513              : 
    1514              :             END DO ! iat
    1515              : 
    1516              :             ! Release the xc structure used to store the xc derivatives
    1517            0 :             CALL xc_dset_release(deriv_set)
    1518            0 :             CALL xc_rho_set_release(rho_set_h)
    1519            0 :             CALL xc_rho_set_release(rho_set_s)
    1520              : 
    1521            0 :             DEALLOCATE (rho_h, rho_s, rho0_h, rho0_s, rho1_h, rho1_s)
    1522            0 :             DEALLOCATE (vxc_h, vxc_s)
    1523            0 :             IF (gradient_f) THEN
    1524            0 :                DEALLOCATE (drho_h, drho_s, drho0_h, drho0_s, drho1_h, drho1_s)
    1525            0 :                DEALLOCATE (vxg_h, vxg_s)
    1526              :             END IF
    1527            0 :             IF (tau_f) THEN
    1528            0 :                DEALLOCATE (tau_h, tau_s, tau0_h, tau0_s, tau1_h, tau1_s)
    1529            0 :                DEALLOCATE (vtau_h, vtau_s)
    1530            0 :                CALL release_tau_basis_cache(tau_basis_cache)
    1531              :             END IF
    1532              :          END DO ! ikind
    1533              : 
    1534              :       END IF !xc_none
    1535              : 
    1536            0 :       CALL timestop(handle)
    1537              : 
    1538            0 :    END SUBROUTINE calculate_gfxc_atom
    1539              : 
    1540              : ! **************************************************************************************************
    1541              : !> \brief ...
    1542              : !> \param qs_env ...
    1543              : !> \param rho0_atom_set ...
    1544              : !> \param rho1_atom_set ...
    1545              : !> \param rho2_atom_set ...
    1546              : !> \param kind_set ...
    1547              : !> \param xc_section ...
    1548              : !> \param is_triplet ...
    1549              : !> \param accuracy ...
    1550              : !> \param epsrho ...
    1551              : ! **************************************************************************************************
    1552          114 :    SUBROUTINE gfxc_atom_diff(qs_env, rho0_atom_set, rho1_atom_set, rho2_atom_set, &
    1553              :                              kind_set, xc_section, is_triplet, accuracy, epsrho)
    1554              : 
    1555              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1556              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set, rho1_atom_set, &
    1557              :                                                             rho2_atom_set
    1558              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: kind_set
    1559              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: xc_section
    1560              :       LOGICAL, INTENT(IN)                                :: is_triplet
    1561              :       INTEGER, INTENT(IN)                                :: accuracy
    1562              :       REAL(KIND=dp), INTENT(IN)                          :: epsrho
    1563              : 
    1564              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'gfxc_atom_diff'
    1565              : 
    1566              :       INTEGER                                            :: bo(2), handle, iat, iatom, ikind, ir, &
    1567              :                                                             istep, mspins, myfun, na, natom, nf, &
    1568              :                                                             nr, ns, nspins, nstep, num_pe
    1569              :       INTEGER, DIMENSION(2, 3)                           :: bounds
    1570          114 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
    1571              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
    1572              :                                                             paw_atom, tau_f
    1573              :       REAL(dp)                                           :: agr, alpha, beta, density_cut, &
    1574              :                                                             gradient_cut, oeps1, tau_cut
    1575          114 :       REAL(dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER  :: vtau_h, vtau_s, vxc_h, vxc_s
    1576              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
    1577              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
    1578          228 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
    1579          228 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho0_h, rho0_s, rho1_h, rho1_s, rho_h, &
    1580          228 :                                                             rho_s, tau0_h, tau0_s, tau1_h, tau1_s, &
    1581          114 :                                                             tau_h, tau_s
    1582          114 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho0_h, drho0_s, drho1_h, drho1_s, &
    1583          228 :                                                             drho_h, drho_s, vxg_h, vxg_s
    1584              :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak
    1585          114 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1586              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1587              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    1588              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    1589              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    1590              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1591          114 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, fint_hh, fint_ss, int_hh, &
    1592          114 :                                                             int_ss, r_h, r_s
    1593          114 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    1594              :       TYPE(rho_atom_type), POINTER                       :: rho0_atom, rho1_atom, rho2_atom
    1595              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
    1596          114 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
    1597              :       TYPE(xc_derivative_set_type)                       :: deriv_set
    1598              :       TYPE(xc_rho_cflags_type)                           :: needs
    1599              :       TYPE(xc_rho_set_type)                              :: rho1_set_h, rho1_set_s, rho_set_h, &
    1600              :                                                             rho_set_s
    1601              : 
    1602          114 :       CALL timeset(routineN, handle)
    1603              : 
    1604          114 :       NULLIFY (vtau_h, vtau_s)
    1605              : 
    1606          114 :       ak = 0.0_dp
    1607          114 :       SELECT CASE (accuracy)
    1608              :       CASE (:4)
    1609            0 :          nstep = 2
    1610            0 :          ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
    1611              :       CASE (5:7)
    1612          912 :          nstep = 3
    1613          912 :          ak(-3:3) = [-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp]/60.0_dp
    1614              :       CASE (8:)
    1615            0 :          nstep = 4
    1616              :          ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
    1617          114 :                      224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
    1618              :       END SELECT
    1619          114 :       oeps1 = 1.0_dp/epsrho
    1620              : 
    1621              :       CALL get_qs_env(qs_env=qs_env, &
    1622              :                       dft_control=dft_control, &
    1623              :                       para_env=para_env, &
    1624          114 :                       atomic_kind_set=atomic_kind_set)
    1625              : 
    1626          114 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
    1627          114 :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", i_val=myfun)
    1628              : 
    1629          114 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
    1630              : 
    1631          114 :       IF (myfun == xc_none) THEN
    1632              :          ! no action needed?
    1633              :       ELSE
    1634              :          ! calculate fxc
    1635              :          CALL calculate_xc_2nd_deriv_atom(rho0_atom_set, rho1_atom_set, qs_env, xc_section, para_env, &
    1636          114 :                                           do_triplet=is_triplet, kind_set_external=kind_set)
    1637              : 
    1638          114 :          CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", r_val=density_cut)
    1639          114 :          CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", r_val=gradient_cut)
    1640          114 :          CALL section_vals_val_get(xc_section, "TAU_CUTOFF", r_val=tau_cut)
    1641              : 
    1642          114 :          nlcc = has_nlcc(kind_set)
    1643          114 :          lsd = dft_control%lsd
    1644          114 :          nspins = dft_control%nspins
    1645          114 :          mspins = nspins
    1646          114 :          IF (is_triplet) THEN
    1647           12 :             CPASSERT(nspins == 1)
    1648           12 :             lsd = .TRUE.
    1649           12 :             mspins = 2
    1650              :          END IF
    1651          114 :          needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, calc_potential=.TRUE.)
    1652          114 :          gradient_f = (needs%drho .OR. needs%drho_spin)
    1653          114 :          tau_f = (needs%tau .OR. needs%tau_spin)
    1654              : 
    1655              :          ! Here starts the loop over all the atoms
    1656          386 :          DO ikind = 1, SIZE(atomic_kind_set)
    1657          272 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    1658              :             CALL get_qs_kind(kind_set(ikind), paw_atom=paw_atom, &
    1659          272 :                              harmonics=harmonics, grid_atom=grid_atom)
    1660          272 :             CALL get_qs_kind(kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    1661              : 
    1662          272 :             IF (.NOT. paw_atom) CYCLE
    1663              : 
    1664          258 :             nr = grid_atom%nr
    1665          258 :             na = grid_atom%ng_sphere
    1666              : 
    1667              :             ! set integration weights
    1668          258 :             IF (accint) THEN
    1669          138 :                weight_h => grid_atom%weight
    1670          138 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
    1671          138 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    1672          138 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
    1673              :                END IF
    1674          138 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    1675            0 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
    1676            0 :                   DO ir = 1, nr
    1677            0 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
    1678            0 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
    1679              :                   END DO
    1680            0 :                   grid_atom%gapw_weight_alpha = alpha
    1681              :                END IF
    1682          138 :                weight_s => grid_atom%gapw_weight_s
    1683              :             ELSE
    1684          120 :                weight_h => grid_atom%weight
    1685          120 :                weight_s => grid_atom%weight
    1686              :             END IF
    1687              : 
    1688              :             ! Prepare the structures needed to calculate and store the xc derivatives
    1689              : 
    1690              :             ! Array dimension: here anly one dimensional arrays are used,
    1691              :             ! i.e. only the first column of deriv_data is read.
    1692              :             ! The other to dimensions  are set to size equal 1
    1693         2580 :             bounds(1:2, 1:3) = 1
    1694          258 :             bounds(2, 1) = na
    1695          258 :             bounds(2, 2) = nr
    1696              : 
    1697              :             ! create a place where to put the derivatives
    1698          258 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
    1699              :             ! create the place where to store the argument for the functionals
    1700              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
    1701          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    1702              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
    1703          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    1704              :             CALL xc_rho_set_create(rho1_set_h, bounds, rho_cutoff=density_cut, &
    1705          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    1706              :             CALL xc_rho_set_create(rho1_set_s, bounds, rho_cutoff=density_cut, &
    1707          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    1708              : 
    1709              :             ! allocate the required 3d arrays where to store rho and drho
    1710          258 :             CALL xc_rho_set_atom_update(rho_set_h, needs, mspins, bounds)
    1711          258 :             CALL xc_rho_set_atom_update(rho_set_s, needs, mspins, bounds)
    1712          258 :             CALL xc_rho_set_atom_update(rho1_set_h, needs, mspins, bounds)
    1713          258 :             CALL xc_rho_set_atom_update(rho1_set_s, needs, mspins, bounds)
    1714              : 
    1715              :             ALLOCATE (rho_h(na, nr, nspins), rho_s(na, nr, nspins), &
    1716              :                       rho0_h(na, nr, nspins), rho0_s(na, nr, nspins), &
    1717         5160 :                       rho1_h(na, nr, nspins), rho1_s(na, nr, nspins))
    1718         1806 :             ALLOCATE (vxc_h(na, nr, nspins), vxc_s(na, nr, nspins))
    1719          258 :             IF (gradient_f) THEN
    1720              :                ALLOCATE (drho_h(4, na, nr, nspins), drho_s(4, na, nr, nspins), &
    1721              :                          drho0_h(4, na, nr, nspins), drho0_s(4, na, nr, nspins), &
    1722         3520 :                          drho1_h(4, na, nr, nspins), drho1_s(4, na, nr, nspins))
    1723         1408 :                ALLOCATE (vxg_h(3, na, nr, nspins), vxg_s(3, na, nr, nspins))
    1724              :             END IF
    1725          258 :             IF (tau_f) THEN
    1726            0 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    1727              :                ALLOCATE (tau_h(na, nr, nspins), tau_s(na, nr, nspins), &
    1728              :                          tau0_h(na, nr, nspins), tau0_s(na, nr, nspins), &
    1729            0 :                          tau1_h(na, nr, nspins), tau1_s(na, nr, nspins))
    1730            0 :                ALLOCATE (vtau_h(na, nr, nspins), vtau_s(na, nr, nspins))
    1731              :             END IF
    1732              :             !
    1733              :             ! NLCC: prepare rho and drho of the core charge for this KIND
    1734          258 :             donlcc = .FALSE.
    1735          258 :             IF (nlcc) THEN
    1736            0 :                NULLIFY (rho_nlcc)
    1737            0 :                rho_nlcc => kind_set(ikind)%nlcc_pot
    1738            0 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
    1739              :             END IF
    1740              : 
    1741              :             ! Distribute the atoms of this kind
    1742          258 :             num_pe = para_env%num_pe
    1743          258 :             bo = get_limit(natom, num_pe, para_env%mepos)
    1744              : 
    1745          441 :             DO iat = bo(1), bo(2)
    1746          183 :                iatom = atom_list(iat)
    1747              :                !
    1748          183 :                NULLIFY (int_hh, int_ss)
    1749          183 :                rho0_atom => rho0_atom_set(iatom)
    1750          183 :                CALL get_rho_atom(rho_atom=rho0_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    1751         1098 :                ALLOCATE (fint_ss(nspins), fint_hh(nspins))
    1752          366 :                DO ns = 1, nspins
    1753          183 :                   nf = SIZE(int_ss(ns)%r_coef, 1)
    1754          732 :                   ALLOCATE (fint_ss(ns)%r_coef(nf, nf))
    1755          183 :                   nf = SIZE(int_hh(ns)%r_coef, 1)
    1756          915 :                   ALLOCATE (fint_hh(ns)%r_coef(nf, nf))
    1757              :                END DO
    1758              : 
    1759              :                ! RHO0
    1760       467016 :                rho0_h = 0.0_dp
    1761       467016 :                rho0_s = 0.0_dp
    1762          183 :                rho0_atom => rho0_atom_set(iatom)
    1763          183 :                IF (gradient_f) THEN
    1764          126 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    1765              :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    1766          126 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    1767      1581552 :                   drho0_h = 0.0_dp
    1768      1581552 :                   drho0_s = 0.0_dp
    1769              :                ELSE
    1770           57 :                   NULLIFY (r_h, r_s)
    1771           57 :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    1772           57 :                   rho_d = 0.0_dp
    1773              :                END IF
    1774         9333 :                DO ir = 1, nr
    1775              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    1776              :                                         ir, r_h, r_s, rho0_h, rho0_s, dr_h, dr_s, &
    1777         9150 :                                         r_h_d, r_s_d, drho0_h, drho0_s)
    1778         9333 :                   IF (donlcc) THEN
    1779              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
    1780            0 :                                         ir, rho_nlcc(:, 1), rho0_h, rho0_s, rho_nlcc(:, 2), drho0_h, drho0_s)
    1781              :                   END IF
    1782              :                END DO
    1783          183 :                IF (tau_f) THEN
    1784              :                   !compute tau on the grid all at once
    1785            0 :                   CALL calc_tau_atom(tau0_h, tau0_s, rho0_atom, tau_basis_cache, nspins)
    1786              :                ELSE
    1787          183 :                   tau_d = 0.0_dp
    1788              :                END IF
    1789              :                ! RHO1
    1790       467016 :                rho1_h = 0.0_dp
    1791       467016 :                rho1_s = 0.0_dp
    1792          183 :                rho1_atom => rho1_atom_set(iatom)
    1793          183 :                IF (gradient_f) THEN
    1794          126 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    1795              :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    1796          126 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    1797      1581552 :                   drho1_h = 0.0_dp
    1798      1581552 :                   drho1_s = 0.0_dp
    1799              :                ELSE
    1800           57 :                   NULLIFY (r_h, r_s)
    1801           57 :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    1802              :                END IF
    1803         9333 :                DO ir = 1, nr
    1804              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    1805              :                                         ir, r_h, r_s, rho1_h, rho1_s, dr_h, dr_s, &
    1806         9333 :                                         r_h_d, r_s_d, drho1_h, drho1_s)
    1807              :                END DO
    1808          183 :                IF (tau_f) THEN
    1809              :                   !compute tau on the grid all at once
    1810            0 :                   CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, tau_basis_cache, nspins)
    1811              :                END IF
    1812              : 
    1813         9333 :                DO ir = 1, nr
    1814         9333 :                   IF (tau_f) THEN
    1815            0 :                      CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau1_h, na, ir)
    1816            0 :                      CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau1_s, na, ir)
    1817         9150 :                   ELSE IF (gradient_f) THEN
    1818         6300 :                      CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau_d, na, ir)
    1819         6300 :                      CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau_d, na, ir)
    1820              :                   ELSE
    1821         2850 :                      CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, rho_d, tau_d, na, ir)
    1822         2850 :                      CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, rho_d, tau_d, na, ir)
    1823              :                   END IF
    1824              :                END DO
    1825              : 
    1826              :                ! RHO2
    1827          183 :                rho2_atom => rho2_atom_set(iatom)
    1828              : 
    1829         1464 :                DO istep = -nstep, nstep
    1830              : 
    1831         1281 :                   beta = REAL(istep, KIND=dp)*epsrho
    1832              : 
    1833      6536943 :                   rho_h = rho0_h + beta*rho1_h
    1834      6536943 :                   rho_s = rho0_s + beta*rho1_s
    1835         1281 :                   IF (gradient_f) THEN
    1836     22140846 :                      drho_h = drho0_h + beta*drho1_h
    1837     22140846 :                      drho_s = drho0_s + beta*drho1_s
    1838              :                   END IF
    1839         1281 :                   IF (tau_f) THEN
    1840            0 :                      tau_h = tau0_h + beta*tau1_h
    1841            0 :                      tau_s = tau0_s + beta*tau1_s
    1842              :                   END IF
    1843              :                   !
    1844         1281 :                   IF (gradient_f) THEN
    1845              :                      drho_h(4, :, :, :) = SQRT( &
    1846              :                                           drho_h(1, :, :, :)*drho_h(1, :, :, :) + &
    1847              :                                           drho_h(2, :, :, :)*drho_h(2, :, :, :) + &
    1848      2250864 :                                           drho_h(3, :, :, :)*drho_h(3, :, :, :))
    1849              : 
    1850              :                      drho_s(4, :, :, :) = SQRT( &
    1851              :                                           drho_s(1, :, :, :)*drho_s(1, :, :, :) + &
    1852              :                                           drho_s(2, :, :, :)*drho_s(2, :, :, :) + &
    1853      2250864 :                                           drho_s(3, :, :, :)*drho_s(3, :, :, :))
    1854              :                   END IF
    1855              : 
    1856        65331 :                   DO ir = 1, nr
    1857        65331 :                      IF (tau_f) THEN
    1858            0 :                         CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
    1859            0 :                         CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
    1860        64050 :                      ELSE IF (gradient_f) THEN
    1861        44100 :                         CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
    1862        44100 :                         CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
    1863              :                      ELSE
    1864        19950 :                         CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
    1865        19950 :                         CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
    1866              :                      END IF
    1867              :                   END DO
    1868              : 
    1869              :                   ! hard atom density !
    1870         1281 :                   CALL xc_dset_zero_all(deriv_set)
    1871              :                   CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
    1872              :                                          rho_set=rho_set_h, rho1_set=rho1_set_h, &
    1873              :                                          deriv_set=deriv_set, &
    1874              :                                          w=weight_h, vxc=vxc_h, vxg=vxg_h, vtau=vtau_h, &
    1875         1281 :                                          do_triplet=is_triplet)
    1876              :                   ! soft atom density !
    1877         1281 :                   CALL xc_dset_zero_all(deriv_set)
    1878              :                   CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
    1879              :                                          rho_set=rho_set_s, rho1_set=rho1_set_s, &
    1880              :                                          deriv_set=deriv_set, &
    1881              :                                          w=weight_s, vxc=vxc_s, vxg=vxg_s, vtau=vtau_s, &
    1882         1281 :                                          do_triplet=is_triplet)
    1883              :                   ! potentials
    1884         2562 :                   DO ns = 1, nspins
    1885      2410793 :                      fint_hh(ns)%r_coef(:, :) = 0.0_dp
    1886      2412074 :                      fint_ss(ns)%r_coef(:, :) = 0.0_dp
    1887              :                   END DO
    1888         1281 :                   IF (gradient_f) THEN
    1889              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, fint_hh, fint_ss, &
    1890          882 :                                      grid_atom, basis_1c, harmonics, nspins)
    1891              :                   ELSE
    1892              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, fint_hh, fint_ss, &
    1893          399 :                                        grid_atom, basis_1c, harmonics, nspins)
    1894              :                   END IF
    1895         1281 :                   IF (tau_f) THEN
    1896              :                      CALL dgaVtaudgb(vtau_h, vtau_s, fint_hh, fint_ss, &
    1897            0 :                                      tau_basis_cache, nspins)
    1898              :                   END IF
    1899              :                   ! second derivative gxc
    1900         1281 :                   NULLIFY (int_hh, int_ss)
    1901         1281 :                   CALL get_rho_atom(rho_atom=rho2_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    1902         2745 :                   DO ns = 1, nspins
    1903      4820305 :                      int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_ss(ns)%r_coef(:, :)
    1904      4821586 :                      int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_hh(ns)%r_coef(:, :)
    1905              :                   END DO
    1906              :                END DO
    1907              :                !
    1908          366 :                DO ns = 1, nspins
    1909          183 :                   DEALLOCATE (fint_ss(ns)%r_coef)
    1910          366 :                   DEALLOCATE (fint_hh(ns)%r_coef)
    1911              :                END DO
    1912          441 :                DEALLOCATE (fint_ss, fint_hh)
    1913              : 
    1914              :             END DO ! iat
    1915              : 
    1916              :             ! Release the xc structure used to store the xc derivatives
    1917          258 :             CALL xc_dset_release(deriv_set)
    1918          258 :             CALL xc_rho_set_release(rho_set_h)
    1919          258 :             CALL xc_rho_set_release(rho_set_s)
    1920          258 :             CALL xc_rho_set_release(rho1_set_h)
    1921          258 :             CALL xc_rho_set_release(rho1_set_s)
    1922              : 
    1923          258 :             DEALLOCATE (rho_h, rho_s, rho0_h, rho0_s, rho1_h, rho1_s)
    1924          258 :             DEALLOCATE (vxc_h, vxc_s)
    1925          258 :             IF (gradient_f) THEN
    1926          176 :                DEALLOCATE (drho_h, drho_s, drho0_h, drho0_s, drho1_h, drho1_s)
    1927          176 :                DEALLOCATE (vxg_h, vxg_s)
    1928              :             END IF
    1929          902 :             IF (tau_f) THEN
    1930            0 :                DEALLOCATE (tau_h, tau_s, tau0_h, tau0_s, tau1_h, tau1_s)
    1931            0 :                DEALLOCATE (vtau_h, vtau_s)
    1932            0 :                CALL release_tau_basis_cache(tau_basis_cache)
    1933              :             END IF
    1934              :          END DO ! ikind
    1935              : 
    1936              :       END IF !xc_none
    1937              : 
    1938          114 :       CALL timestop(handle)
    1939              : 
    1940         8436 :    END SUBROUTINE gfxc_atom_diff
    1941              : 
    1942              : ! **************************************************************************************************
    1943              : !> \brief ...
    1944              : !> \param grid_atom ...
    1945              : !> \param harmonics ...
    1946              : !> \param nspins ...
    1947              : !> \param grad_func ...
    1948              : !> \param ir ...
    1949              : !> \param r_h ...
    1950              : !> \param r_s ...
    1951              : !> \param rho_h ...
    1952              : !> \param rho_s ...
    1953              : !> \param dr_h ...
    1954              : !> \param dr_s ...
    1955              : !> \param r_h_d ...
    1956              : !> \param r_s_d ...
    1957              : !> \param drho_h ...
    1958              : !> \param drho_s ...
    1959              : ! **************************************************************************************************
    1960      2861040 :    SUBROUTINE calc_rho_angular(grid_atom, harmonics, nspins, grad_func, &
    1961              :                                ir, r_h, r_s, rho_h, rho_s, &
    1962              :                                dr_h, dr_s, r_h_d, r_s_d, drho_h, drho_s)
    1963              : 
    1964              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    1965              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    1966              :       INTEGER, INTENT(IN)                                :: nspins
    1967              :       LOGICAL, INTENT(IN)                                :: grad_func
    1968              :       INTEGER, INTENT(IN)                                :: ir
    1969              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: r_h, r_s
    1970              :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: rho_h, rho_s
    1971              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s
    1972              :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    1973              :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: drho_h, drho_s
    1974              : 
    1975              :       INTEGER                                            :: ia, iso, ispin, na
    1976              :       REAL(KIND=dp)                                      :: rad, urad
    1977              : 
    1978      2861040 :       CPASSERT(ASSOCIATED(r_h))
    1979      2861040 :       CPASSERT(ASSOCIATED(r_s))
    1980      2861040 :       CPASSERT(ASSOCIATED(rho_h))
    1981      2861040 :       CPASSERT(ASSOCIATED(rho_s))
    1982      2861040 :       IF (grad_func) THEN
    1983      1796440 :          CPASSERT(ASSOCIATED(dr_h))
    1984      1796440 :          CPASSERT(ASSOCIATED(dr_s))
    1985      1796440 :          CPASSERT(ASSOCIATED(r_h_d))
    1986      1796440 :          CPASSERT(ASSOCIATED(r_s_d))
    1987      1796440 :          CPASSERT(ASSOCIATED(drho_h))
    1988      1796440 :          CPASSERT(ASSOCIATED(drho_s))
    1989              :       END IF
    1990              : 
    1991      2861040 :       na = grid_atom%ng_sphere
    1992      2861040 :       rad = grid_atom%rad(ir)
    1993      2861040 :       urad = grid_atom%oorad2l(ir, 1)
    1994      6063820 :       DO ispin = 1, nspins
    1995     49154440 :          DO iso = 1, harmonics%max_iso_not0
    1996   2202365920 :             DO ia = 1, na
    1997              :                rho_h(ia, ir, ispin) = rho_h(ia, ir, ispin) + &
    1998   2156072520 :                                       r_h(ispin)%r_coef(ir, iso)*harmonics%slm(ia, iso)
    1999              :                rho_s(ia, ir, ispin) = rho_s(ia, ir, ispin) + &
    2000   2199163140 :                                       r_s(ispin)%r_coef(ir, iso)*harmonics%slm(ia, iso)
    2001              :             END DO ! ia
    2002              :          END DO ! iso
    2003              :       END DO ! ispin
    2004              : 
    2005      2861040 :       IF (grad_func) THEN
    2006      3783570 :          DO ispin = 1, nspins
    2007     29585300 :             DO iso = 1, harmonics%max_iso_not0
    2008   1411035320 :                DO ia = 1, na
    2009              : 
    2010              :                   ! components of the gradient of rho1 hard
    2011              :                   drho_h(1, ia, ir, ispin) = drho_h(1, ia, ir, ispin) + &
    2012              :                                              dr_h(ispin)%r_coef(ir, iso)* &
    2013              :                                              harmonics%a(1, ia)*harmonics%slm(ia, iso) + &
    2014              :                                              r_h_d(1, ispin)%r_coef(ir, iso)* &
    2015   1381450020 :                                              harmonics%slm(ia, iso)
    2016              : 
    2017              :                   drho_h(2, ia, ir, ispin) = drho_h(2, ia, ir, ispin) + &
    2018              :                                              dr_h(ispin)%r_coef(ir, iso)* &
    2019              :                                              harmonics%a(2, ia)*harmonics%slm(ia, iso) + &
    2020              :                                              r_h_d(2, ispin)%r_coef(ir, iso)* &
    2021   1381450020 :                                              harmonics%slm(ia, iso)
    2022              : 
    2023              :                   drho_h(3, ia, ir, ispin) = drho_h(3, ia, ir, ispin) + &
    2024              :                                              dr_h(ispin)%r_coef(ir, iso)* &
    2025              :                                              harmonics%a(3, ia)*harmonics%slm(ia, iso) + &
    2026              :                                              r_h_d(3, ispin)%r_coef(ir, iso)* &
    2027   1381450020 :                                              harmonics%slm(ia, iso)
    2028              : 
    2029              :                   ! components of the gradient of rho1 soft
    2030              :                   drho_s(1, ia, ir, ispin) = drho_s(1, ia, ir, ispin) + &
    2031              :                                              dr_s(ispin)%r_coef(ir, iso)* &
    2032              :                                              harmonics%a(1, ia)*harmonics%slm(ia, iso) + &
    2033              :                                              r_s_d(1, ispin)%r_coef(ir, iso)* &
    2034   1381450020 :                                              harmonics%slm(ia, iso)
    2035              : 
    2036              :                   drho_s(2, ia, ir, ispin) = drho_s(2, ia, ir, ispin) + &
    2037              :                                              dr_s(ispin)%r_coef(ir, iso)* &
    2038              :                                              harmonics%a(2, ia)*harmonics%slm(ia, iso) + &
    2039              :                                              r_s_d(2, ispin)%r_coef(ir, iso)* &
    2040   1381450020 :                                              harmonics%slm(ia, iso)
    2041              : 
    2042              :                   drho_s(3, ia, ir, ispin) = drho_s(3, ia, ir, ispin) + &
    2043              :                                              dr_s(ispin)%r_coef(ir, iso)* &
    2044              :                                              harmonics%a(3, ia)*harmonics%slm(ia, iso) + &
    2045              :                                              r_s_d(3, ispin)%r_coef(ir, iso)* &
    2046   1409048190 :                                              harmonics%slm(ia, iso)
    2047              : 
    2048              :                END DO ! ia
    2049              :             END DO ! iso
    2050    103218550 :             DO ia = 1, na
    2051              :                drho_h(4, ia, ir, ispin) = SQRT( &
    2052              :                                           drho_h(1, ia, ir, ispin)*drho_h(1, ia, ir, ispin) + &
    2053              :                                           drho_h(2, ia, ir, ispin)*drho_h(2, ia, ir, ispin) + &
    2054     99434980 :                                           drho_h(3, ia, ir, ispin)*drho_h(3, ia, ir, ispin))
    2055              : 
    2056              :                drho_s(4, ia, ir, ispin) = SQRT( &
    2057              :                                           drho_s(1, ia, ir, ispin)*drho_s(1, ia, ir, ispin) + &
    2058              :                                           drho_s(2, ia, ir, ispin)*drho_s(2, ia, ir, ispin) + &
    2059    101422110 :                                           drho_s(3, ia, ir, ispin)*drho_s(3, ia, ir, ispin))
    2060              :             END DO ! ia
    2061              :          END DO ! ispin
    2062              :       END IF
    2063              : 
    2064      2861040 :    END SUBROUTINE calc_rho_angular
    2065              : 
    2066              : ! **************************************************************************************************
    2067              : !> \brief Precompute radial and angular factors for GAPW meta-GGA tau contractions
    2068              : !> \param tau_cache precomputed compact one-center gradient basis
    2069              : !> \param grid_atom atom-centered integration grid
    2070              : !> \param basis_1c GAPW one-center basis
    2071              : !> \param harmonics spherical harmonics on the atom-centered grid
    2072              : ! **************************************************************************************************
    2073         1218 :    SUBROUTINE create_tau_basis_cache(tau_cache, grid_atom, basis_1c, harmonics)
    2074              : 
    2075              :       TYPE(tau_basis_cache_type), INTENT(INOUT)          :: tau_cache
    2076              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    2077              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    2078              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    2079              : 
    2080              :       INTEGER                                            :: dir, ia, igrid, ip, ipgf, ir, iset, iso, &
    2081              :                                                             l, starti
    2082         1218 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: a1, a2, gexp, r1, r2
    2083         1218 :       REAL(dp), DIMENSION(:, :), POINTER                 :: slm
    2084         1218 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: dslm_dxyz
    2085              : 
    2086         1218 :       NULLIFY (slm, dslm_dxyz)
    2087              : 
    2088         1218 :       CALL release_tau_basis_cache(tau_cache)
    2089              : 
    2090              :       CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=tau_cache%lmax, &
    2091              :                              lmin=tau_cache%lmin, maxso=tau_cache%maxso, &
    2092              :                              npgf=tau_cache%npgf, nset=tau_cache%nset, &
    2093         1218 :                              zet=tau_cache%zet)
    2094              :       CALL get_paw_basis_info(basis_1c, o2nindex=tau_cache%o2nindex, &
    2095              :                               n2oindex=tau_cache%n2oindex, &
    2096         1218 :                               nsatbas=tau_cache%nsatbas)
    2097              : 
    2098         1218 :       tau_cache%nr = grid_atom%nr
    2099         1218 :       tau_cache%na = grid_atom%ng_sphere
    2100         1218 :       slm => harmonics%slm
    2101         1218 :       dslm_dxyz => harmonics%dslm_dxyz
    2102              : 
    2103         6090 :       ALLOCATE (tau_cache%grad(tau_cache%na*tau_cache%nr, tau_cache%nsatbas, 3))
    2104              :       ALLOCATE (a1(tau_cache%na), a2(tau_cache%na), gexp(tau_cache%nr), &
    2105         9744 :                 r1(tau_cache%nr), r2(tau_cache%nr))
    2106    283015104 :       tau_cache%grad = 0.0_dp
    2107              : 
    2108         5092 :       DO iset = 1, tau_cache%nset
    2109        16818 :          DO ipgf = 1, tau_cache%npgf(iset)
    2110              :             starti = (iset - 1)*tau_cache%maxso + &
    2111        11726 :                      (ipgf - 1)*nsoset(tau_cache%lmax(iset))
    2112              :             gexp(1:tau_cache%nr) = EXP(-tau_cache%zet(ipgf, iset)* &
    2113       611026 :                                        grid_atom%rad2(1:tau_cache%nr))
    2114        51544 :             DO iso = nsoset(tau_cache%lmin(iset) - 1) + 1, nsoset(tau_cache%lmax(iset))
    2115        35944 :                ip = tau_cache%o2nindex(starti + iso)
    2116        35944 :                IF (ip == 0) CYCLE
    2117        35944 :                l = indso(1, iso)
    2118              : 
    2119      1869544 :                r1(1:tau_cache%nr) = grid_atom%rad(1:tau_cache%nr)**(l - 1)*gexp(1:tau_cache%nr)
    2120              :                r2(1:tau_cache%nr) = -2.0_dp*tau_cache%zet(ipgf, iset)* &
    2121      1869544 :                                     grid_atom%rad2(1:tau_cache%nr)*r1(1:tau_cache%nr)
    2122              : 
    2123       155502 :                DO dir = 1, 3
    2124      5578056 :                   a1(1:tau_cache%na) = dslm_dxyz(dir, 1:tau_cache%na, iso)
    2125      5578056 :                   a2(1:tau_cache%na) = harmonics%a(dir, 1:tau_cache%na)*slm(1:tau_cache%na, iso)
    2126      5644576 :                   DO ir = 1, tau_cache%nr
    2127    288511032 :                      DO ia = 1, tau_cache%na
    2128    282902400 :                         igrid = ia + (ir - 1)*tau_cache%na
    2129    288403200 :                         tau_cache%grad(igrid, ip, dir) = r1(ir)*a1(ia) + r2(ir)*a2(ia)
    2130              :                      END DO
    2131              :                   END DO
    2132              :                END DO
    2133              :             END DO
    2134              :          END DO
    2135              :       END DO
    2136              : 
    2137         1218 :       DEALLOCATE (a1, a2, gexp, r1, r2)
    2138              : 
    2139         1218 :    END SUBROUTINE create_tau_basis_cache
    2140              : 
    2141              : ! **************************************************************************************************
    2142              : !> \brief Release precomputed GAPW meta-GGA tau factors
    2143              : !> \param tau_cache precomputed compact one-center gradient basis
    2144              : ! **************************************************************************************************
    2145         2436 :    SUBROUTINE release_tau_basis_cache(tau_cache)
    2146              : 
    2147              :       TYPE(tau_basis_cache_type), INTENT(INOUT)          :: tau_cache
    2148              : 
    2149         2436 :       IF (ALLOCATED(tau_cache%grad)) DEALLOCATE (tau_cache%grad)
    2150         2436 :       IF (ASSOCIATED(tau_cache%n2oindex)) DEALLOCATE (tau_cache%n2oindex)
    2151         2436 :       IF (ASSOCIATED(tau_cache%o2nindex)) DEALLOCATE (tau_cache%o2nindex)
    2152         2436 :       NULLIFY (tau_cache%lmax, tau_cache%lmin, tau_cache%n2oindex, tau_cache%npgf, &
    2153         2436 :                tau_cache%zet, tau_cache%o2nindex)
    2154         2436 :       tau_cache%maxso = 0
    2155         2436 :       tau_cache%na = 0
    2156         2436 :       tau_cache%nr = 0
    2157         2436 :       tau_cache%nsatbas = 0
    2158         2436 :       tau_cache%nset = 0
    2159              : 
    2160         2436 :    END SUBROUTINE release_tau_basis_cache
    2161              : 
    2162              : ! **************************************************************************************************
    2163              : !> \brief Computes tau hard and soft on the atomic grids for meta-GGA calculations
    2164              : !> \param tau_h the hard part of tau
    2165              : !> \param tau_s the soft part of tau
    2166              : !> \param rho_atom atom-centered density matrices
    2167              : !> \param tau_cache precomputed compact one-center gradient basis
    2168              : !> \param nspins number of spin channels
    2169              : !> \note This is a rewrite to correct a meta-GGA GAPW bug. This is more brute force than the original,
    2170              : !>       which was done along in qs_rho_atom_methods.F, but makes sure that no corner is cut in
    2171              : !>       terms of accuracy (A. Bussy)
    2172              : ! **************************************************************************************************
    2173          849 :    SUBROUTINE calc_tau_atom(tau_h, tau_s, rho_atom, tau_cache, nspins)
    2174              : 
    2175              :       REAL(dp), DIMENSION(:, :, :), INTENT(INOUT)        :: tau_h, tau_s
    2176              :       TYPE(rho_atom_type), POINTER                       :: rho_atom
    2177              :       TYPE(tau_basis_cache_type), INTENT(IN)             :: tau_cache
    2178              :       INTEGER, INTENT(IN)                                :: nspins
    2179              : 
    2180              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'calc_tau_atom'
    2181              : 
    2182              :       INTEGER                                            :: dir, handle, ia, ibas, igrid, ir, ispin, &
    2183              :                                                             na, nbas, ngrid, nr
    2184          849 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: work
    2185              : 
    2186          849 :       CALL timeset(routineN, handle)
    2187              : 
    2188          849 :       CPASSERT(ALLOCATED(tau_cache%grad))
    2189              : 
    2190              :       !zeroing tau, assuming it is already allocated
    2191      2346956 :       tau_h = 0.0_dp
    2192      2346956 :       tau_s = 0.0_dp
    2193              : 
    2194          849 :       nr = tau_cache%nr
    2195          849 :       na = tau_cache%na
    2196          849 :       nbas = tau_cache%nsatbas
    2197          849 :       ngrid = na*nr
    2198         3396 :       ALLOCATE (work(ngrid, nbas))
    2199              : 
    2200         1706 :       DO ispin = 1, nspins
    2201         4277 :          DO dir = 1, 3
    2202              :             CALL dgemm('N', 'T', ngrid, nbas, nbas, 0.5_dp, tau_cache%grad(:, :, dir), &
    2203         2571 :                        ngrid, rho_atom%cpc_h(ispin)%r_coef, nbas, 0.0_dp, work, ngrid)
    2204        72576 :             DO ibas = 1, nbas
    2205      3627426 :                DO ir = 1, nr
    2206    185298555 :                   DO ia = 1, na
    2207    181673700 :                      igrid = ia + (ir - 1)*na
    2208              :                      tau_h(ia, ir, ispin) = tau_h(ia, ir, ispin) + &
    2209    185228550 :                                             tau_cache%grad(igrid, ibas, dir)*work(igrid, ibas)
    2210              :                   END DO
    2211              :                END DO
    2212              :             END DO
    2213              : 
    2214              :             CALL dgemm('N', 'T', ngrid, nbas, nbas, 0.5_dp, tau_cache%grad(:, :, dir), &
    2215         2571 :                        ngrid, rho_atom%cpc_s(ispin)%r_coef, nbas, 0.0_dp, work, ngrid)
    2216        73433 :             DO ibas = 1, nbas
    2217      3627426 :                DO ir = 1, nr
    2218    185298555 :                   DO ia = 1, na
    2219    181673700 :                      igrid = ia + (ir - 1)*na
    2220              :                      tau_s(ia, ir, ispin) = tau_s(ia, ir, ispin) + &
    2221    185228550 :                                             tau_cache%grad(igrid, ibas, dir)*work(igrid, ibas)
    2222              :                   END DO
    2223              :                END DO
    2224              :             END DO
    2225              :          END DO
    2226              :       END DO
    2227              : 
    2228          849 :       DEALLOCATE (work)
    2229              : 
    2230          849 :       CALL timestop(handle)
    2231              : 
    2232          849 :    END SUBROUTINE calc_tau_atom
    2233              : 
    2234              : ! **************************************************************************************************
    2235              : !> \brief ...
    2236              : !> \param grid_atom ...
    2237              : !> \param nspins ...
    2238              : !> \param grad_func ...
    2239              : !> \param ir ...
    2240              : !> \param rho_nlcc ...
    2241              : !> \param rho_h ...
    2242              : !> \param rho_s ...
    2243              : !> \param drho_nlcc ...
    2244              : !> \param drho_h ...
    2245              : !> \param drho_s ...
    2246              : ! **************************************************************************************************
    2247         8650 :    SUBROUTINE calc_rho_nlcc(grid_atom, nspins, grad_func, &
    2248         8650 :                             ir, rho_nlcc, rho_h, rho_s, drho_nlcc, drho_h, drho_s)
    2249              : 
    2250              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    2251              :       INTEGER, INTENT(IN)                                :: nspins
    2252              :       LOGICAL, INTENT(IN)                                :: grad_func
    2253              :       INTEGER, INTENT(IN)                                :: ir
    2254              :       REAL(KIND=dp), DIMENSION(:)                        :: rho_nlcc
    2255              :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: rho_h, rho_s
    2256              :       REAL(KIND=dp), DIMENSION(:)                        :: drho_nlcc
    2257              :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: drho_h, drho_s
    2258              : 
    2259              :       INTEGER                                            :: ia, ispin, na
    2260              :       REAL(KIND=dp)                                      :: drho, dx, dy, dz, rad, rho, urad, xsp
    2261              : 
    2262         8650 :       CPASSERT(ASSOCIATED(rho_h))
    2263         8650 :       CPASSERT(ASSOCIATED(rho_s))
    2264         8650 :       IF (grad_func) THEN
    2265         8650 :          CPASSERT(ASSOCIATED(drho_h))
    2266         8650 :          CPASSERT(ASSOCIATED(drho_s))
    2267              :       END IF
    2268              : 
    2269         8650 :       na = grid_atom%ng_sphere
    2270         8650 :       rad = grid_atom%rad(ir)
    2271         8650 :       urad = grid_atom%oorad2l(ir, 1)
    2272              : 
    2273         8650 :       xsp = REAL(nspins, KIND=dp)
    2274         8650 :       rho = rho_nlcc(ir)/xsp
    2275        17300 :       DO ispin = 1, nspins
    2276       441150 :          rho_h(1:na, ir, ispin) = rho_h(1:na, ir, ispin) + rho
    2277       449800 :          rho_s(1:na, ir, ispin) = rho_s(1:na, ir, ispin) + rho
    2278              :       END DO ! ispin
    2279              : 
    2280         8650 :       IF (grad_func) THEN
    2281         8650 :          drho = drho_nlcc(ir)/xsp
    2282        17300 :          DO ispin = 1, nspins
    2283       449800 :             DO ia = 1, na
    2284       432500 :                IF (grid_atom%azi(ia) == 0.0_dp) THEN
    2285              :                   dx = 0.0_dp
    2286              :                   dy = 0.0_dp
    2287              :                ELSE
    2288       389250 :                   dx = grid_atom%sin_pol(ia)*grid_atom%sin_azi(ia)
    2289       389250 :                   dy = grid_atom%sin_pol(ia)*grid_atom%cos_azi(ia)
    2290              :                END IF
    2291       432500 :                dz = grid_atom%cos_pol(ia)
    2292              :                ! components of the gradient of rho1 hard
    2293       432500 :                drho_h(1, ia, ir, ispin) = drho_h(1, ia, ir, ispin) + drho*dx
    2294       432500 :                drho_h(2, ia, ir, ispin) = drho_h(2, ia, ir, ispin) + drho*dy
    2295       432500 :                drho_h(3, ia, ir, ispin) = drho_h(3, ia, ir, ispin) + drho*dz
    2296              :                ! components of the gradient of rho1 soft
    2297       432500 :                drho_s(1, ia, ir, ispin) = drho_s(1, ia, ir, ispin) + drho*dx
    2298       432500 :                drho_s(2, ia, ir, ispin) = drho_s(2, ia, ir, ispin) + drho*dy
    2299       432500 :                drho_s(3, ia, ir, ispin) = drho_s(3, ia, ir, ispin) + drho*dz
    2300              :                ! norm of gradient
    2301              :                drho_h(4, ia, ir, ispin) = SQRT( &
    2302              :                                           drho_h(1, ia, ir, ispin)*drho_h(1, ia, ir, ispin) + &
    2303              :                                           drho_h(2, ia, ir, ispin)*drho_h(2, ia, ir, ispin) + &
    2304       432500 :                                           drho_h(3, ia, ir, ispin)*drho_h(3, ia, ir, ispin))
    2305              : 
    2306              :                drho_s(4, ia, ir, ispin) = SQRT( &
    2307              :                                           drho_s(1, ia, ir, ispin)*drho_s(1, ia, ir, ispin) + &
    2308              :                                           drho_s(2, ia, ir, ispin)*drho_s(2, ia, ir, ispin) + &
    2309       441150 :                                           drho_s(3, ia, ir, ispin)*drho_s(3, ia, ir, ispin))
    2310              :             END DO ! ia
    2311              :          END DO ! ispin
    2312              :       END IF
    2313              : 
    2314         8650 :    END SUBROUTINE calc_rho_nlcc
    2315              : 
    2316              : ! **************************************************************************************************
    2317              : !> \brief ...
    2318              : !> \param vxc_h ...
    2319              : !> \param vxc_s ...
    2320              : !> \param int_hh ...
    2321              : !> \param int_ss ...
    2322              : !> \param grid_atom ...
    2323              : !> \param basis_1c ...
    2324              : !> \param harmonics ...
    2325              : !> \param nspins ...
    2326              : ! **************************************************************************************************
    2327        15921 :    SUBROUTINE gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, grid_atom, basis_1c, harmonics, nspins)
    2328              : 
    2329              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vxc_h, vxc_s
    2330              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: int_hh, int_ss
    2331              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    2332              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    2333              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    2334              :       INTEGER, INTENT(IN)                                :: nspins
    2335              : 
    2336              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'gaVxcgb_noGC'
    2337              : 
    2338              :       INTEGER :: handle, ia, ic, icg, ipgf1, ipgf2, ir, iset1, iset2, iso, iso1, iso2, ispin, l, &
    2339              :          ld, lmax12, lmax_expansion, lmin12, m1, m2, max_iso_not0, max_iso_not0_local, max_s_harm, &
    2340              :          maxl, maxso, n1, n2, na, ngau1, ngau2, nngau1, nr, nset, size1
    2341              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: cg_n_list
    2342              :       INTEGER, ALLOCATABLE, DIMENSION(:, :, :)           :: cg_list
    2343        15921 :       INTEGER, DIMENSION(:), POINTER                     :: lmax, lmin, npgf
    2344        15921 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: g1, g2
    2345        15921 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: gg, gVg_h, gVg_s, matso_h, matso_s, vx
    2346        15921 :       REAL(dp), DIMENSION(:, :), POINTER                 :: zet
    2347              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: my_CG
    2348              : 
    2349        15921 :       CALL timeset(routineN, handle)
    2350              : 
    2351        15921 :       NULLIFY (lmin, lmax, npgf, zet, my_CG)
    2352              : 
    2353              :       CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=lmax, lmin=lmin, &
    2354              :                              maxso=maxso, maxl=maxl, npgf=npgf, &
    2355        15921 :                              nset=nset, zet=zet)
    2356              : 
    2357        15921 :       nr = grid_atom%nr
    2358        15921 :       na = grid_atom%ng_sphere
    2359        15921 :       my_CG => harmonics%my_CG
    2360        15921 :       max_iso_not0 = harmonics%max_iso_not0
    2361        15921 :       lmax_expansion = indso(1, max_iso_not0)
    2362        15921 :       max_s_harm = harmonics%max_s_harm
    2363              : 
    2364       111447 :       ALLOCATE (g1(nr), g2(nr), gg(nr, 0:2*maxl))
    2365        95526 :       ALLOCATE (gVg_h(na, 0:2*maxl), gVg_s(na, 0:2*maxl))
    2366              :       ALLOCATE (matso_h(nsoset(maxl), nsoset(maxl)), &
    2367        95526 :                 matso_s(nsoset(maxl), nsoset(maxl)))
    2368        63684 :       ALLOCATE (vx(na, nr))
    2369        95526 :       ALLOCATE (cg_list(2, nsoset(maxl)**2, max_s_harm), cg_n_list(max_s_harm))
    2370              : 
    2371       958271 :       g1 = 0.0_dp
    2372       958271 :       g2 = 0.0_dp
    2373        15921 :       m1 = 0
    2374        54528 :       DO iset1 = 1, nset
    2375        38607 :          n1 = nsoset(lmax(iset1))
    2376        38607 :          m2 = 0
    2377       160646 :          DO iset2 = 1, nset
    2378              :             CALL get_none0_cg_list(my_CG, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
    2379       122039 :                                    max_s_harm, lmax_expansion, cg_list, cg_n_list, max_iso_not0_local)
    2380       122039 :             CPASSERT(max_iso_not0_local <= max_iso_not0)
    2381              : 
    2382       122039 :             n2 = nsoset(lmax(iset2))
    2383       447916 :             DO ipgf1 = 1, npgf(iset1)
    2384       325877 :                ngau1 = n1*(ipgf1 - 1) + m1
    2385       325877 :                size1 = nsoset(lmax(iset1)) - nsoset(lmin(iset1) - 1)
    2386       325877 :                nngau1 = nsoset(lmin(iset1) - 1) + ngau1
    2387              : 
    2388     18743727 :                g1(1:nr) = EXP(-zet(ipgf1, iset1)*grid_atom%rad2(1:nr))
    2389      1514144 :                DO ipgf2 = 1, npgf(iset2)
    2390      1066228 :                   ngau2 = n2*(ipgf2 - 1) + m2
    2391              : 
    2392     60868328 :                   g2(1:nr) = EXP(-zet(ipgf2, iset2)*grid_atom%rad2(1:nr))
    2393      1066228 :                   lmin12 = lmin(iset1) + lmin(iset2)
    2394      1066228 :                   lmax12 = lmax(iset1) + lmax(iset2)
    2395              : 
    2396              :                   ! reduce expansion local densities
    2397      1392105 :                   IF (lmin12 <= lmax_expansion) THEN
    2398              : 
    2399    262621710 :                      gg = 0.0_dp
    2400      1065283 :                      IF (lmin12 == 0) THEN
    2401     33750591 :                         gg(1:nr, lmin12) = g1(1:nr)*g2(1:nr)
    2402              :                      ELSE
    2403     27069542 :                         gg(1:nr, lmin12) = grid_atom%rad2l(1:nr, lmin12)*g1(1:nr)*g2(1:nr)
    2404              :                      END IF
    2405              : 
    2406              :                      ! limit the expansion of the local densities to a max L
    2407      1065283 :                      IF (lmax12 > lmax_expansion) lmax12 = lmax_expansion
    2408              : 
    2409      1562895 :                      DO l = lmin12 + 1, lmax12
    2410     30944295 :                         gg(1:nr, l) = grid_atom%rad(1:nr)*gg(:, l - 1)
    2411              :                      END DO
    2412              : 
    2413      2300622 :                      DO ispin = 1, nspins
    2414      1235339 :                         ld = lmax12 + 1
    2415     74505289 :                         DO ir = 1, nr
    2416   3738002789 :                            vx(1:na, ir) = vxc_h(1:na, ir, ispin)
    2417              :                         END DO
    2418              :                         CALL dgemm('N', 'N', na, ld, nr, 1.0_dp, vx(1:na, 1:nr), na, &
    2419      1235339 :                                    gg(1:nr, 0:lmax12), nr, 0.0_dp, gVg_h(1:na, 0:lmax12), na)
    2420     74505289 :                         DO ir = 1, nr
    2421   3738002789 :                            vx(1:na, ir) = vxc_s(1:na, ir, ispin)
    2422              :                         END DO
    2423              :                         CALL dgemm('N', 'N', na, ld, nr, 1.0_dp, vx(1:na, 1:nr), na, &
    2424      1235339 :                                    gg(1:nr, 0:lmax12), nr, 0.0_dp, gVg_s(1:na, 0:lmax12), na)
    2425              : 
    2426    103955651 :                         matso_h = 0.0_dp
    2427    103955651 :                         matso_s = 0.0_dp
    2428      9730568 :                         DO iso = 1, max_iso_not0_local
    2429     26894967 :                            DO icg = 1, cg_n_list(iso)
    2430     17164399 :                               iso1 = cg_list(1, icg, iso)
    2431     17164399 :                               iso2 = cg_list(2, icg, iso)
    2432     17164399 :                               l = indso(1, iso1) + indso(1, iso2)
    2433              : 
    2434     17164399 :                               CPASSERT(l <= lmax_expansion)
    2435    883879578 :                               DO ia = 1, na
    2436              :                                  matso_h(iso1, iso2) = matso_h(iso1, iso2) + &
    2437              :                                                        gVg_h(ia, l)* &
    2438              :                                                        my_CG(iso1, iso2, iso)* &
    2439    858219950 :                                                        harmonics%slm(ia, iso)
    2440              :                                  matso_s(iso1, iso2) = matso_s(iso1, iso2) + &
    2441              :                                                        gVg_s(ia, l)* &
    2442              :                                                        my_CG(iso1, iso2, iso)* &
    2443    875384349 :                                                        harmonics%slm(ia, iso)
    2444              :                               END DO
    2445              :                            END DO
    2446              :                         END DO
    2447              : 
    2448              :                         ! Write in the global matrix
    2449      5550889 :                         DO ic = nsoset(lmin(iset2) - 1) + 1, nsoset(lmax(iset2))
    2450      3250267 :                            iso1 = nsoset(lmin(iset1) - 1) + 1
    2451      3250267 :                            iso2 = ngau2 + ic
    2452              :                            CALL daxpy(size1, 1.0_dp, matso_h(iso1, ic), 1, &
    2453      3250267 :                                       int_hh(ispin)%r_coef(nngau1 + 1, iso2), 1)
    2454              :                            CALL daxpy(size1, 1.0_dp, matso_s(iso1, ic), 1, &
    2455      4485606 :                                       int_ss(ispin)%r_coef(nngau1 + 1, iso2), 1)
    2456              :                         END DO
    2457              : 
    2458              :                      END DO ! ispin
    2459              : 
    2460              :                   END IF ! lmax_expansion
    2461              : 
    2462              :                END DO ! ipfg2
    2463              :             END DO ! ipfg1
    2464       282685 :             m2 = m2 + maxso
    2465              :          END DO ! iset2
    2466        54528 :          m1 = m1 + maxso
    2467              :       END DO ! iset1
    2468              : 
    2469        15921 :       DEALLOCATE (g1, g2, gg, matso_h, matso_s, gVg_s, gVg_h, vx)
    2470              : 
    2471        15921 :       DEALLOCATE (cg_list, cg_n_list)
    2472              : 
    2473        15921 :       CALL timestop(handle)
    2474              : 
    2475        15921 :    END SUBROUTINE gaVxcgb_noGC
    2476              : 
    2477              : ! **************************************************************************************************
    2478              : !> \brief ...
    2479              : !> \param vxc_h ...
    2480              : !> \param vxc_s ...
    2481              : !> \param vxg_h ...
    2482              : !> \param vxg_s ...
    2483              : !> \param int_hh ...
    2484              : !> \param int_ss ...
    2485              : !> \param grid_atom ...
    2486              : !> \param basis_1c ...
    2487              : !> \param harmonics ...
    2488              : !> \param nspins ...
    2489              : ! **************************************************************************************************
    2490        28702 :    SUBROUTINE gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    2491              :                          grid_atom, basis_1c, harmonics, nspins)
    2492              : 
    2493              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vxc_h, vxc_s
    2494              :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: vxg_h, vxg_s
    2495              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: int_hh, int_ss
    2496              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    2497              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    2498              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    2499              :       INTEGER, INTENT(IN)                                :: nspins
    2500              : 
    2501              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'gaVxcgb_GC'
    2502              : 
    2503              :       INTEGER :: dmax_iso_not0_local, handle, ia, ic, icg, ipgf1, ipgf2, ir, iset1, iset2, iso, &
    2504              :          iso1, iso2, ispin, l, lmax12, lmax_expansion, lmin12, m1, m2, max_iso_not0, &
    2505              :          max_iso_not0_local, max_s_harm, maxl, maxso, n1, n2, na, ngau1, ngau2, nngau1, nr, nset, &
    2506              :          size1
    2507              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: cg_n_list, dcg_n_list
    2508              :       INTEGER, ALLOCATABLE, DIMENSION(:, :, :)           :: cg_list, dcg_list
    2509        28702 :       INTEGER, DIMENSION(:), POINTER                     :: lmax, lmin, npgf
    2510              :       REAL(dp)                                           :: urad
    2511        28702 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: g1, g2
    2512        28702 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: dgg, gg, gVXCg_h, gVXCg_s, matso_h, &
    2513        28702 :                                                             matso_s
    2514        28702 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: gVXGg_h, gVXGg_s
    2515        28702 :       REAL(dp), DIMENSION(:, :), POINTER                 :: zet
    2516              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: my_CG
    2517              :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: my_CG_dxyz
    2518              : 
    2519        28702 :       CALL timeset(routineN, handle)
    2520              : 
    2521        28702 :       NULLIFY (lmin, lmax, npgf, zet, my_CG, my_CG_dxyz)
    2522              : 
    2523              :       CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=lmax, lmin=lmin, &
    2524              :                              maxso=maxso, maxl=maxl, npgf=npgf, &
    2525        28702 :                              nset=nset, zet=zet)
    2526              : 
    2527        28702 :       nr = grid_atom%nr
    2528        28702 :       na = grid_atom%ng_sphere
    2529        28702 :       my_CG => harmonics%my_CG
    2530        28702 :       my_CG_dxyz => harmonics%my_CG_dxyz
    2531        28702 :       max_iso_not0 = harmonics%max_iso_not0
    2532        28702 :       lmax_expansion = indso(1, max_iso_not0)
    2533        28702 :       max_s_harm = harmonics%max_s_harm
    2534              : 
    2535       258318 :       ALLOCATE (g1(nr), g2(nr), gg(nr, 0:2*maxl), dgg(nr, 0:2*maxl))
    2536       172212 :       ALLOCATE (gVXCg_h(na, 0:2*maxl), gVXCg_s(na, 0:2*maxl))
    2537       172212 :       ALLOCATE (gVXGg_h(3, na, 0:2*maxl), gVXGg_s(3, na, 0:2*maxl))
    2538              :       ALLOCATE (cg_list(2, nsoset(maxl)**2, max_s_harm), cg_n_list(max_s_harm), &
    2539       258318 :                 dcg_list(2, nsoset(maxl)**2, max_s_harm), dcg_n_list(max_s_harm))
    2540              : 
    2541              :       ALLOCATE (matso_h(nsoset(maxl), nsoset(maxl)), &
    2542       172212 :                 matso_s(nsoset(maxl), nsoset(maxl)))
    2543              : 
    2544        60426 :       DO ispin = 1, nspins
    2545              : 
    2546      1643004 :          g1 = 0.0_dp
    2547      1643004 :          g2 = 0.0_dp
    2548        31724 :          m1 = 0
    2549       141607 :          DO iset1 = 1, nset
    2550        81181 :             n1 = nsoset(lmax(iset1))
    2551        81181 :             m2 = 0
    2552       354926 :             DO iset2 = 1, nset
    2553              :                CALL get_none0_cg_list(my_CG, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
    2554       273745 :                                       max_s_harm, lmax_expansion, cg_list, cg_n_list, max_iso_not0_local)
    2555       273745 :                CPASSERT(max_iso_not0_local <= max_iso_not0)
    2556              :                CALL get_none0_cg_list(my_CG_dxyz, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
    2557       273745 :                                       max_s_harm, lmax_expansion, dcg_list, dcg_n_list, dmax_iso_not0_local)
    2558              : 
    2559       273745 :                n2 = nsoset(lmax(iset2))
    2560       888315 :                DO ipgf1 = 1, npgf(iset1)
    2561       614570 :                   ngau1 = n1*(ipgf1 - 1) + m1
    2562       614570 :                   size1 = nsoset(lmax(iset1)) - nsoset(lmin(iset1) - 1)
    2563       614570 :                   nngau1 = nsoset(lmin(iset1) - 1) + ngau1
    2564              : 
    2565     32064150 :                   g1(1:nr) = EXP(-zet(ipgf1, iset1)*grid_atom%rad2(1:nr))
    2566      2432713 :                   DO ipgf2 = 1, npgf(iset2)
    2567      1544398 :                      ngau2 = n2*(ipgf2 - 1) + m2
    2568              : 
    2569     80790978 :                      g2(1:nr) = EXP(-zet(ipgf2, iset2)*grid_atom%rad2(1:nr))
    2570      1544398 :                      lmin12 = lmin(iset1) + lmin(iset2)
    2571      1544398 :                      lmax12 = lmax(iset1) + lmax(iset2)
    2572              : 
    2573              :                      !test reduce expansion local densities
    2574      1544398 :                      IF (lmin12 <= lmax_expansion) THEN
    2575              : 
    2576    338286432 :                         gg = 0.0_dp
    2577    338286432 :                         dgg = 0.0_dp
    2578              : 
    2579      1543798 :                         IF (lmin12 == 0) THEN
    2580     48750516 :                            gg(1:nr, lmin12) = g1(1:nr)*g2(1:nr)
    2581              :                         ELSE
    2582     32009862 :                            gg(1:nr, lmin12) = grid_atom%rad2l(1:nr, lmin12)*g1(1:nr)*g2(1:nr)
    2583              :                         END IF
    2584              : 
    2585              :                         !test reduce expansion local densities
    2586      1543798 :                         IF (lmax12 > lmax_expansion) lmax12 = lmax_expansion
    2587              : 
    2588      2375378 :                         DO l = lmin12 + 1, lmax12
    2589     43869380 :                            gg(1:nr, l) = grid_atom%rad(1:nr)*gg(:, l - 1)
    2590              :                            dgg(1:nr, l - 1) = dgg(1:nr, l - 1) - 2.0_dp*(zet(ipgf1, iset1) + &
    2591     45413178 :                                                                          zet(ipgf2, iset2))*gg(1:nr, l)
    2592              :                         END DO
    2593              :                         dgg(1:nr, lmax12) = dgg(1:nr, lmax12) - 2.0_dp*(zet(ipgf1, iset1) + &
    2594              :                                                                         zet(ipgf2, iset2))*grid_atom%rad(1:nr)* &
    2595     80760378 :                                             gg(1:nr, lmax12)
    2596              : 
    2597    328522708 :                         gVXCg_h = 0.0_dp
    2598    328522708 :                         gVXCg_s = 0.0_dp
    2599   1290216616 :                         gVXGg_h = 0.0_dp
    2600   1290216616 :                         gVXGg_s = 0.0_dp
    2601              : 
    2602              :                         ! Cross Term
    2603      3919176 :                         DO l = lmin12, lmax12
    2604    122639308 :                            DO ia = 1, na
    2605   6237356910 :                               DO ir = 1, nr
    2606              :                                  gVXCg_h(ia, l) = gVXCg_h(ia, l) + &
    2607              :                                                   gg(ir, l)*vxc_h(ia, ir, ispin) + &
    2608              :                                                   dgg(ir, l)* &
    2609              :                                                   (vxg_h(1, ia, ir, ispin)*harmonics%a(1, ia) + &
    2610              :                                                    vxg_h(2, ia, ir, ispin)*harmonics%a(2, ia) + &
    2611   6116261400 :                                                    vxg_h(3, ia, ir, ispin)*harmonics%a(3, ia))
    2612              : 
    2613              :                                  gVXCg_s(ia, l) = gVXCg_s(ia, l) + &
    2614              :                                                   gg(ir, l)*vxc_s(ia, ir, ispin) + &
    2615              :                                                   dgg(ir, l)* &
    2616              :                                                   (vxg_s(1, ia, ir, ispin)*harmonics%a(1, ia) + &
    2617              :                                                    vxg_s(2, ia, ir, ispin)*harmonics%a(2, ia) + &
    2618   6116261400 :                                                    vxg_s(3, ia, ir, ispin)*harmonics%a(3, ia))
    2619              : 
    2620   6116261400 :                                  urad = grid_atom%oorad2l(ir, 1)
    2621              : 
    2622              :                                  gVXGg_h(1, ia, l) = gVXGg_h(1, ia, l) + &
    2623              :                                                      vxg_h(1, ia, ir, ispin)* &
    2624   6116261400 :                                                      gg(ir, l)*urad
    2625              : 
    2626              :                                  gVXGg_h(2, ia, l) = gVXGg_h(2, ia, l) + &
    2627              :                                                      vxg_h(2, ia, ir, ispin)* &
    2628   6116261400 :                                                      gg(ir, l)*urad
    2629              : 
    2630              :                                  gVXGg_h(3, ia, l) = gVXGg_h(3, ia, l) + &
    2631              :                                                      vxg_h(3, ia, ir, ispin)* &
    2632   6116261400 :                                                      gg(ir, l)*urad
    2633              : 
    2634              :                                  gVXGg_s(1, ia, l) = gVXGg_s(1, ia, l) + &
    2635              :                                                      vxg_s(1, ia, ir, ispin)* &
    2636   6116261400 :                                                      gg(ir, l)*urad
    2637              : 
    2638              :                                  gVXGg_s(2, ia, l) = gVXGg_s(2, ia, l) + &
    2639              :                                                      vxg_s(2, ia, ir, ispin)* &
    2640   6116261400 :                                                      gg(ir, l)*urad
    2641              : 
    2642              :                                  gVXGg_s(3, ia, l) = gVXGg_s(3, ia, l) + &
    2643              :                                                      vxg_s(3, ia, ir, ispin)* &
    2644   6234981532 :                                                      gg(ir, l)*urad
    2645              : 
    2646              :                               END DO ! ir
    2647              :                            END DO ! ia
    2648              :                         END DO ! l
    2649              : 
    2650    112813382 :                         matso_h = 0.0_dp
    2651    112813382 :                         matso_s = 0.0_dp
    2652     11129206 :                         DO iso = 1, max_iso_not0_local
    2653     31436911 :                            DO icg = 1, cg_n_list(iso)
    2654     20307705 :                               iso1 = cg_list(1, icg, iso)
    2655     20307705 :                               iso2 = cg_list(2, icg, iso)
    2656              : 
    2657     20307705 :                               l = indso(1, iso1) + indso(1, iso2)
    2658              : 
    2659              :                               !test reduce expansion local densities
    2660     20307705 :                               CPASSERT(l <= lmax_expansion)
    2661   1045030023 :                               DO ia = 1, na
    2662              :                                  matso_h(iso1, iso2) = matso_h(iso1, iso2) + &
    2663              :                                                        gVXCg_h(ia, l)* &
    2664              :                                                        harmonics%slm(ia, iso)* &
    2665   1015136910 :                                                        my_CG(iso1, iso2, iso)
    2666              :                                  matso_s(iso1, iso2) = matso_s(iso1, iso2) + &
    2667              :                                                        gVXCg_s(ia, l)* &
    2668              :                                                        harmonics%slm(ia, iso)* &
    2669   1035444615 :                                                        my_CG(iso1, iso2, iso)
    2670              :                               END DO ! ia
    2671              : 
    2672              :                               !test reduce expansion local densities
    2673              : 
    2674              :                            END DO
    2675              : 
    2676              :                         END DO ! iso
    2677              : 
    2678      5936116 :                         DO iso = 1, dmax_iso_not0_local
    2679     39057859 :                            DO icg = 1, dcg_n_list(iso)
    2680     33121743 :                               iso1 = dcg_list(1, icg, iso)
    2681     33121743 :                               iso2 = dcg_list(2, icg, iso)
    2682              : 
    2683     33121743 :                               l = indso(1, iso1) + indso(1, iso2)
    2684              :                               !test reduce expansion local densities
    2685     33121743 :                               CPASSERT(l <= lmax_expansion)
    2686   1692861879 :                               DO ia = 1, na
    2687              :                                  matso_h(iso1, iso2) = matso_h(iso1, iso2) + &
    2688              :                                                        (gVXGg_h(1, ia, l)*my_CG_dxyz(1, iso1, iso2, iso) + &
    2689              :                                                         gVXGg_h(2, ia, l)*my_CG_dxyz(2, iso1, iso2, iso) + &
    2690              :                                                         gVXGg_h(3, ia, l)*my_CG_dxyz(3, iso1, iso2, iso))* &
    2691   1655347818 :                                                        harmonics%slm(ia, iso)
    2692              : 
    2693              :                                  matso_s(iso1, iso2) = matso_s(iso1, iso2) + &
    2694              :                                                        (gVXGg_s(1, ia, l)*my_CG_dxyz(1, iso1, iso2, iso) + &
    2695              :                                                         gVXGg_s(2, ia, l)*my_CG_dxyz(2, iso1, iso2, iso) + &
    2696              :                                                         gVXGg_s(3, ia, l)*my_CG_dxyz(3, iso1, iso2, iso))* &
    2697   1688469561 :                                                        harmonics%slm(ia, iso)
    2698              : 
    2699              :                               END DO ! ia
    2700              : 
    2701              :                               !test reduce expansion local densities
    2702              : 
    2703              :                            END DO ! icg
    2704              :                         END DO ! iso
    2705              :                         !test reduce expansion local densities
    2706              :                      END IF ! lmax_expansion
    2707              : 
    2708              :                      !  Write in the global matrix
    2709      6090568 :                      DO ic = nsoset(lmin(iset2) - 1) + 1, nsoset(lmax(iset2))
    2710      3931600 :                         iso1 = nsoset(lmin(iset1) - 1) + 1
    2711      3931600 :                         iso2 = ngau2 + ic
    2712              :                         CALL daxpy(size1, 1.0_dp, matso_h(iso1, ic), 1, &
    2713      3931600 :                                    int_hh(ispin)%r_coef(nngau1 + 1, iso2), 1)
    2714              :                         CALL daxpy(size1, 1.0_dp, matso_s(iso1, ic), 1, &
    2715      5475998 :                                    int_ss(ispin)%r_coef(nngau1 + 1, iso2), 1)
    2716              :                      END DO
    2717              : 
    2718              :                   END DO ! ipfg2
    2719              :                END DO ! ipfg1
    2720       902416 :                m2 = m2 + maxso
    2721              :             END DO ! iset2
    2722       112905 :             m1 = m1 + maxso
    2723              :          END DO ! iset1
    2724              :       END DO ! ispin
    2725              : 
    2726        28702 :       DEALLOCATE (g1, g2, gg, dgg, matso_h, matso_s, gVXCg_h, gVXCg_s, gVXGg_h, gVXGg_s)
    2727        28702 :       DEALLOCATE (cg_list, cg_n_list, dcg_list, dcg_n_list)
    2728              : 
    2729        28702 :       CALL timestop(handle)
    2730              : 
    2731        28702 :    END SUBROUTINE gaVxcgb_GC
    2732              : 
    2733              : ! **************************************************************************************************
    2734              : !> \brief Integrates 0.5 * grad_ga .dot. (V_tau * grad_gb) on the atomic grid for meta-GGA
    2735              : !> \param vtau_h the hard tau potential
    2736              : !> \param vtau_s the soft tau potential
    2737              : !> \param int_hh hard one-center matrix contribution
    2738              : !> \param int_ss soft one-center matrix contribution
    2739              : !> \param tau_cache precomputed compact one-center gradient basis
    2740              : !> \param nspins number of spin channels
    2741              : !> \note This is a rewrite to correct meta-GGA GAPW bug. This is more brute force than the original
    2742              : !>       but makes sure that no corner is cut in terms of accuracy (A. Bussy)
    2743              : ! **************************************************************************************************
    2744          849 :    SUBROUTINE dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
    2745              :                          tau_cache, nspins)
    2746              : 
    2747              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vtau_h, vtau_s
    2748              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: int_hh, int_ss
    2749              :       TYPE(tau_basis_cache_type), INTENT(IN)             :: tau_cache
    2750              :       INTEGER, INTENT(IN)                                :: nspins
    2751              : 
    2752              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'dgaVtaudgb'
    2753              : 
    2754              :       INTEGER                                            :: dir, handle, ia, ibas, igrid, iold, ir, &
    2755              :                                                             ispin, jbas, jold, max_old_basis, na, &
    2756              :                                                             nbas, ngrid, nr
    2757          849 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: int_h, int_s, weighted_grad
    2758              : 
    2759          849 :       CALL timeset(routineN, handle)
    2760              : 
    2761          849 :       CPASSERT(ALLOCATED(tau_cache%grad))
    2762          849 :       CPASSERT(ASSOCIATED(tau_cache%n2oindex))
    2763              : 
    2764          849 :       nr = tau_cache%nr
    2765          849 :       na = tau_cache%na
    2766          849 :       nbas = tau_cache%nsatbas
    2767          849 :       ngrid = na*nr
    2768        66894 :       max_old_basis = MAXVAL(tau_cache%n2oindex)
    2769         7641 :       ALLOCATE (int_h(nbas, nbas), int_s(nbas, nbas), weighted_grad(ngrid, nbas))
    2770              : 
    2771         1706 :       DO ispin = 1, nspins
    2772          857 :          CPASSERT(SIZE(int_hh(ispin)%r_coef, 1) >= max_old_basis)
    2773          857 :          CPASSERT(SIZE(int_hh(ispin)%r_coef, 2) >= max_old_basis)
    2774          857 :          CPASSERT(SIZE(int_ss(ispin)%r_coef, 1) >= max_old_basis)
    2775          857 :          CPASSERT(SIZE(int_ss(ispin)%r_coef, 2) >= max_old_basis)
    2776       951505 :          int_h = 0.0_dp
    2777       951505 :          int_s = 0.0_dp
    2778         3428 :          DO dir = 1, 3
    2779        72576 :             DO ibas = 1, nbas
    2780      3627426 :                DO ir = 1, nr
    2781    185298555 :                   DO ia = 1, na
    2782    181673700 :                      igrid = ia + (ir - 1)*na
    2783              :                      weighted_grad(igrid, ibas) = vtau_h(ia, ir, ispin)* &
    2784    185228550 :                                                   tau_cache%grad(igrid, ibas, dir)
    2785              :                   END DO
    2786              :                END DO
    2787              :             END DO
    2788              :             CALL dgemm('T', 'N', nbas, nbas, ngrid, 0.5_dp, tau_cache%grad(:, :, dir), &
    2789         2571 :                        ngrid, weighted_grad, ngrid, 1.0_dp, int_h, nbas)
    2790              : 
    2791        72576 :             DO ibas = 1, nbas
    2792      3627426 :                DO ir = 1, nr
    2793    185298555 :                   DO ia = 1, na
    2794    181673700 :                      igrid = ia + (ir - 1)*na
    2795              :                      weighted_grad(igrid, ibas) = vtau_s(ia, ir, ispin)* &
    2796    185228550 :                                                   tau_cache%grad(igrid, ibas, dir)
    2797              :                   END DO
    2798              :                END DO
    2799              :             END DO
    2800              :             CALL dgemm('T', 'N', nbas, nbas, ngrid, 0.5_dp, tau_cache%grad(:, :, dir), &
    2801         3428 :                        ngrid, weighted_grad, ngrid, 1.0_dp, int_s, nbas)
    2802              :          END DO
    2803              : 
    2804        25041 :          DO jbas = 1, nbas
    2805        23335 :             jold = tau_cache%n2oindex(jbas)
    2806       951505 :             DO ibas = 1, nbas
    2807       927313 :                iold = tau_cache%n2oindex(ibas)
    2808              :                int_hh(ispin)%r_coef(iold, jold) = int_hh(ispin)%r_coef(iold, jold) + &
    2809       927313 :                                                   int_h(ibas, jbas)
    2810              :                int_ss(ispin)%r_coef(iold, jold) = int_ss(ispin)%r_coef(iold, jold) + &
    2811       950648 :                                                   int_s(ibas, jbas)
    2812              :             END DO
    2813              :          END DO
    2814              :       END DO
    2815              : 
    2816          849 :       DEALLOCATE (int_h, int_s, weighted_grad)
    2817              : 
    2818          849 :       CALL timestop(handle)
    2819              : 
    2820          849 :    END SUBROUTINE dgaVtaudgb
    2821              : 
    2822            0 : END MODULE qs_vxc_atom
        

Generated by: LCOV version 2.0-1