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

Generated by: LCOV version 2.0-1