LCOV - code coverage report
Current view: top level - src - qs_vxc_atom.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:21ef868) Lines: 77.9 % 2359 1837
Test Date: 2026-08-14 07:04:57 Functions: 81.5 % 27 22

            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 cell_types,                      ONLY: cell_type,&
      18              :                                               pbc
      19              :    USE cp_array_utils,                  ONLY: cp_3d_r_cp_type
      20              :    USE cp_control_types,                ONLY: dft_control_type
      21              :    USE cp_log_handling,                 ONLY: cp_logger_get_default_io_unit
      22              :    USE external_potential_types,        ONLY: get_potential,&
      23              :                                               gth_potential_type,&
      24              :                                               sgp_potential_type
      25              :    USE input_constants,                 ONLY: cdft_alpha_constraint,&
      26              :                                               cdft_beta_constraint,&
      27              :                                               cdft_charge_constraint,&
      28              :                                               cdft_magnetization_constraint,&
      29              :                                               xc_none
      30              :    USE input_section_types,             ONLY: section_get_rval,&
      31              :                                               section_vals_get_subs_vals,&
      32              :                                               section_vals_type,&
      33              :                                               section_vals_val_get
      34              :    USE kinds,                           ONLY: dp,&
      35              :                                               int_8
      36              :    USE memory_utilities,                ONLY: reallocate
      37              :    USE message_passing,                 ONLY: mp_para_env_type
      38              :    USE orbital_pointers,                ONLY: indso,&
      39              :                                               nsoset
      40              :    USE particle_types,                  ONLY: particle_type
      41              :    USE paw_basis_types,                 ONLY: get_paw_basis_info
      42              :    USE pw_env_types,                    ONLY: pw_env_get,&
      43              :                                               pw_env_type
      44              :    USE pw_grid_types,                   ONLY: pw_grid_type
      45              :    USE pw_methods,                      ONLY: pw_axpy
      46              :    USE pw_pool_types,                   ONLY: pw_pool_type
      47              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      48              :                                               pw_r3d_rs_type
      49              :    USE qs_cdft_grid,                    ONLY: cdft_point_context_create,&
      50              :                                               cdft_point_context_release,&
      51              :                                               cdft_point_context_type,&
      52              :                                               cdft_point_weights
      53              :    USE qs_cdft_types,                   ONLY: cdft_control_type
      54              :    USE qs_environment_types,            ONLY: get_qs_env,&
      55              :                                               qs_environment_type
      56              :    USE qs_force_types,                  ONLY: qs_force_type
      57              :    USE qs_grid_atom,                    ONLY: grid_atom_type
      58              :    USE qs_harmonics_atom,               ONLY: get_none0_cg_list,&
      59              :                                               harmonics_atom_type
      60              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      61              :                                               has_nlcc,&
      62              :                                               qs_kind_type
      63              :    USE qs_linres_types,                 ONLY: nablavks_atom_type
      64              :    USE qs_rho_atom_methods,             ONLY: replicate_rho_atom_radial
      65              :    USE qs_rho_atom_types,               ONLY: get_rho_atom,&
      66              :                                               rho_atom_coeff,&
      67              :                                               rho_atom_type
      68              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      69              :                                               qs_rho_type
      70              :    USE skala_gpw_features,              ONLY: skala_gpw_smooth_partition_derivatives,&
      71              :                                               smooth_atom_partition
      72              :    USE skala_gpw_functional,            ONLY: &
      73              :         build_vxc_from_feature_grads, get_gauxc_section, native_skala_gapw_density_partition, &
      74              :         skala_gapw_atom_composite_energy, skala_gapw_atom_vxc_of_r, &
      75              :         skala_gapw_density_partition_hard_minus_soft, skala_gapw_density_partition_hard_only, &
      76              :         skala_gapw_density_partition_none, skala_gapw_density_partition_soft_only, &
      77              :         xc_section_uses_gauxc_model, xc_section_uses_native_skala_evaluator
      78              :    USE spherical_harmonics,             ONLY: y_lm
      79              :    USE util,                            ONLY: get_limit
      80              :    USE virial_types,                    ONLY: virial_type
      81              :    USE xc_atom,                         ONLY: fill_rho_set,&
      82              :                                               vxc_of_r_epr,&
      83              :                                               vxc_of_r_new,&
      84              :                                               xc_2nd_deriv_of_r,&
      85              :                                               xc_rho_set_atom_update
      86              :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
      87              :                                               xc_dset_create,&
      88              :                                               xc_dset_release,&
      89              :                                               xc_dset_zero_all
      90              :    USE xc_derivatives,                  ONLY: xc_functionals_get_needs
      91              :    USE xc_input_constants,              ONLY: skala_gapw_cp2k_default,&
      92              :                                               skala_gapw_paw_one_center,&
      93              :                                               skala_gapw_paw_one_center_split
      94              :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      95              :    USE xc_rho_set_types,                ONLY: xc_rho_set_create,&
      96              :                                               xc_rho_set_get,&
      97              :                                               xc_rho_set_release,&
      98              :                                               xc_rho_set_type,&
      99              :                                               xc_rho_set_update
     100              : #include "./base/base_uses.f90"
     101              : 
     102              :    IMPLICIT NONE
     103              : 
     104              :    PRIVATE
     105              : 
     106              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_vxc_atom'
     107              : 
     108              :    INTEGER, PARAMETER, PRIVATE :: native_grid_interp_offset_min = -3, &
     109              :                                   native_grid_interp_offset_max = 4, &
     110              :                                   native_grid_interp_npts = &
     111              :                                   native_grid_interp_offset_max - &
     112              :                                   native_grid_interp_offset_min + 1
     113              : 
     114              :    TYPE tau_basis_cache_type
     115              :       INTEGER                                            :: maxso = 0, na = 0, nr = 0, nsatbas = 0, &
     116              :                                                             nset = 0
     117              :       INTEGER, DIMENSION(:), POINTER                     :: lmax => NULL(), lmin => NULL(), &
     118              :                                                             n2oindex => NULL(), npgf => NULL(), &
     119              :                                                             o2nindex => NULL()
     120              :       REAL(dp), DIMENSION(:, :), POINTER                 :: zet => NULL()
     121              :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: grad
     122              :    END TYPE tau_basis_cache_type
     123              : 
     124              :    PUBLIC :: calculate_vxc_atom, &
     125              :              calculate_vxc_atom_epr, &
     126              :              calculate_xc_2nd_deriv_atom, &
     127              :              calc_rho_angular, &
     128              :              calculate_gfxc_atom, &
     129              :              gapw_cdft_one_center, &
     130              :              gfxc_atom_diff, &
     131              :              gaVxcgb_noGC
     132              : 
     133              : CONTAINS
     134              : 
     135              : ! **************************************************************************************************
     136              : !> \brief Evaluate an NLCC density and its first two Cartesian derivatives.
     137              : !> \param point evaluation point
     138              : !> \param center pseudopotential center
     139              : !> \param gth_potential optional GTH potential
     140              : !> \param sgp_potential optional separable Gaussian potential
     141              : !> \param rho core density
     142              : !> \param gradient Cartesian density gradient
     143              : !> \param hessian Cartesian density Hessian
     144              : ! **************************************************************************************************
     145        30000 :    SUBROUTINE evaluate_nlcc_primitive_fields(point, center, gth_potential, sgp_potential, &
     146              :                                              rho, gradient, hessian)
     147              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: point, center
     148              :       TYPE(gth_potential_type), INTENT(IN), POINTER      :: gth_potential
     149              :       TYPE(sgp_potential_type), INTENT(IN), POINTER      :: sgp_potential
     150              :       REAL(dp), INTENT(OUT)                              :: rho
     151              :       REAL(dp), DIMENSION(3), INTENT(OUT)                :: gradient
     152              :       REAL(dp), DIMENSION(3, 3), INTENT(OUT)             :: hessian
     153              : 
     154              :       INTEGER                                            :: ic, idir, iexp, jdir, n_nlcc, nexp_nlcc, &
     155              :                                                             power
     156        30000 :       INTEGER, DIMENSION(:), POINTER                     :: nct_nlcc
     157              :       LOGICAL                                            :: has_sgp_nlcc, nlcc_present
     158              :       REAL(dp)                                           :: alpha, beta, d2poly, dpoly, exponential, &
     159              :                                                             poly, r2, rho_x, rho_xx, scaled_r2
     160              :       REAL(dp), DIMENSION(3)                             :: displacement
     161        30000 :       REAL(dp), DIMENSION(:), POINTER                    :: a_nlcc, alpha_nlcc, c_nlcc
     162        30000 :       REAL(dp), DIMENSION(:, :), POINTER                 :: cval_nlcc
     163              : 
     164        30000 :       NULLIFY (a_nlcc, alpha_nlcc, c_nlcc, cval_nlcc, nct_nlcc)
     165        30000 :       rho = 0.0_dp
     166        30000 :       rho_x = 0.0_dp
     167        30000 :       rho_xx = 0.0_dp
     168       120000 :       displacement = point - center
     169       120000 :       r2 = DOT_PRODUCT(displacement, displacement)
     170              : 
     171        30000 :       IF (ASSOCIATED(gth_potential)) THEN
     172              :          CALL get_potential(gth_potential, nlcc_present=nlcc_present, &
     173              :                             nexp_nlcc=nexp_nlcc, alpha_nlcc=alpha_nlcc, &
     174        30000 :                             nct_nlcc=nct_nlcc, cval_nlcc=cval_nlcc)
     175        30000 :          IF (nlcc_present) THEN
     176        30000 :             DO iexp = 1, nexp_nlcc
     177        15000 :                alpha = alpha_nlcc(iexp)
     178        15000 :                beta = 0.5_dp/(alpha*alpha)
     179        15000 :                scaled_r2 = r2/(alpha*alpha)
     180        15000 :                exponential = EXP(-0.5_dp*scaled_r2)
     181        45000 :                DO ic = 1, nct_nlcc(iexp)
     182        15000 :                   power = ic - 1
     183        15000 :                   poly = cval_nlcc(ic, iexp)*scaled_r2**power
     184        15000 :                   dpoly = 0.0_dp
     185        15000 :                   IF (power > 0) THEN
     186              :                      dpoly = cval_nlcc(ic, iexp)*REAL(power, dp)* &
     187            0 :                              scaled_r2**(power - 1)/(alpha*alpha)
     188              :                   END IF
     189            0 :                   d2poly = 0.0_dp
     190            0 :                   IF (power > 1) THEN
     191              :                      d2poly = cval_nlcc(ic, iexp)*REAL(power*(power - 1), dp)* &
     192            0 :                               scaled_r2**(power - 2)/(alpha**4)
     193              :                   END IF
     194        15000 :                   rho = rho + exponential*poly
     195        15000 :                   rho_x = rho_x + exponential*(dpoly - beta*poly)
     196        30000 :                   rho_xx = rho_xx + exponential*(d2poly - 2.0_dp*beta*dpoly + beta*beta*poly)
     197              :                END DO
     198              :             END DO
     199              :          END IF
     200            0 :       ELSE IF (ASSOCIATED(sgp_potential)) THEN
     201              :          CALL get_potential(sgp_potential, has_nlcc=has_sgp_nlcc, n_nlcc=n_nlcc, &
     202            0 :                             a_nlcc=a_nlcc, c_nlcc=c_nlcc)
     203            0 :          IF (has_sgp_nlcc) THEN
     204            0 :             DO iexp = 1, n_nlcc
     205            0 :                exponential = EXP(-a_nlcc(iexp)*r2)
     206            0 :                rho = rho + c_nlcc(iexp)*exponential
     207            0 :                rho_x = rho_x - a_nlcc(iexp)*c_nlcc(iexp)*exponential
     208            0 :                rho_xx = rho_xx + a_nlcc(iexp)**2*c_nlcc(iexp)*exponential
     209              :             END DO
     210              :          END IF
     211              :       END IF
     212              : 
     213       120000 :       gradient = 2.0_dp*rho_x*displacement
     214       120000 :       DO idir = 1, 3
     215       360000 :          DO jdir = 1, 3
     216       360000 :             hessian(idir, jdir) = 4.0_dp*rho_xx*displacement(idir)*displacement(jdir)
     217              :          END DO
     218       120000 :          hessian(idir, idir) = hessian(idir, idir) + 2.0_dp*rho_x
     219              :       END DO
     220        30000 :    END SUBROUTINE evaluate_nlcc_primitive_fields
     221              : 
     222              : ! **************************************************************************************************
     223              : !> \brief ...
     224              : !> \param qs_env ...
     225              : !> \param energy_only ...
     226              : !> \param exc1 the on-body ex energy contribution
     227              : !> \param adiabatic_rescale_factor ...
     228              : !> \param kind_set_external provides a non-default kind_set to use
     229              : !> \param rho_atom_set_external provides a non-default atomic density set to use
     230              : !> \param xc_section_external provides an external non-default XC
     231              : !> \param calculate_forces ...
     232              : !> \param composite_vxc_rho ...
     233              : !> \param composite_vxc_tau ...
     234              : !> \param composite_reference_active ...
     235              : ! **************************************************************************************************
     236        32056 :    SUBROUTINE calculate_vxc_atom(qs_env, energy_only, exc1, &
     237              :                                  adiabatic_rescale_factor, kind_set_external, &
     238              :                                  rho_atom_set_external, xc_section_external, calculate_forces, &
     239              :                                  composite_vxc_rho, composite_vxc_tau, composite_reference_active)
     240              : 
     241              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     242              :       LOGICAL, INTENT(IN)                                :: energy_only
     243              :       REAL(dp), INTENT(INOUT)                            :: exc1
     244              :       REAL(dp), INTENT(IN), OPTIONAL                     :: adiabatic_rescale_factor
     245              :       TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
     246              :          POINTER                                         :: kind_set_external
     247              :       TYPE(rho_atom_type), DIMENSION(:), OPTIONAL, &
     248              :          POINTER                                         :: rho_atom_set_external
     249              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: xc_section_external
     250              :       LOGICAL, INTENT(IN), OPTIONAL                      :: calculate_forces
     251              :       TYPE(pw_r3d_rs_type), DIMENSION(:), OPTIONAL, &
     252              :          POINTER                                         :: composite_vxc_rho, composite_vxc_tau
     253              :       LOGICAL, INTENT(OUT), OPTIONAL                     :: composite_reference_active
     254              : 
     255              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_vxc_atom'
     256              : 
     257              :       INTEGER :: atom_composite_components, bo(2), composite_local_atom, composite_local_natom, &
     258              :          composite_nflat, composite_pw_nflat, composite_row, cross_last_ir, &
     259              :          gapw_density_partition, gapw_representation, handle, ia, iat, iatom, icomponent, idir, &
     260              :          ikind, ir, ispin, iw, jdir, myfun, na, natom, nr, nspins, num_pe, source_atom, &
     261              :          target_atom, xc_deriv_method_id, xc_rho_smooth_id, zatom
     262        32056 :       INTEGER(KIND=int_8), ALLOCATABLE, DIMENSION(:)     :: composite_atomic_grid_sizes, &
     263        32056 :                                                             composite_local_grid_sizes
     264        32056 :       INTEGER, ALLOCATABLE, DIMENSION(:) :: composite_atom_end, composite_atom_kind, &
     265        32056 :          composite_atom_kind_index, composite_atom_start, composite_local_atoms
     266              :       INTEGER, DIMENSION(2, 3)                           :: bounds
     267        32056 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     268              :       LOGICAL :: accint, atom_composite_active, atom_composite_diagnostic, &
     269              :          atom_composite_reference, donlcc, evaluate_hard, evaluate_soft, force_paw_representation, &
     270              :          gradient_f, lsd, my_calculate_forces, native_grid_diagnostics, nlcc, paw_atom, &
     271              :          paw_pseudopotentials, rho_g_valid, skala_atom_grid, tau_f, tau_r_valid, use_virial
     272        32056 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: composite_partition_included
     273              :       REAL(dp) :: agr, alpha, atom_composite_exc, atom_composite_nelec, composite_density_max, &
     274              :          composite_density_min, composite_grad_max, composite_kin_max, composite_kin_min, &
     275              :          composite_tau_integral, cross_amplitude, cross_cutoff, density_cut, exc_h, exc_s, &
     276              :          feature_vxc_analytic, feature_vxc_fd, feature_vxc_minus, feature_vxc_plus, &
     277              :          feature_vxc_step, gradient_cut, my_adiabatic_rescale_factor, nlcc_density, &
     278              :          nlcc_spin_factor, one_center_density_field_contraction, &
     279              :          one_center_density_matrix_contraction, one_center_field_contraction, &
     280              :          one_center_gradient_field_contraction
     281              :       REAL(dp) :: one_center_gradient_matrix_contraction, one_center_matrix_contraction, &
     282              :          one_center_rho_grad_field_contraction, one_center_rho_grad_matrix_contraction, &
     283              :          one_center_tau_field_contraction, one_center_tau_matrix_contraction, &
     284              :          one_center_tensor_contraction, smooth_grid_contraction, smooth_input_contraction, &
     285              :          tau_cut, zeff
     286        32056 :       REAL(dp), ALLOCATABLE, DIMENSION(:) :: composite_atomic_grid_weight_grad, &
     287        32056 :          composite_atomic_grid_weights, composite_distances, composite_grid_weight_grad, &
     288        32056 :          composite_grid_weights, composite_partition_weights
     289        32056 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: composite_atom_coord_grad, composite_atom_coords, &
     290        32056 :          composite_cross_density, composite_cross_kin, composite_density, composite_density_grad, &
     291        32056 :          composite_explicit_force, composite_grid_coord_force, composite_grid_coord_grad, &
     292        32056 :          composite_grid_coords, composite_kin, composite_kin_grad, composite_local_atom_coords, &
     293        32056 :          composite_model_atom_force, composite_moving_smooth_force, composite_nlcc_center_force, &
     294        64112 :          composite_partition_atom_coords, composite_partition_force, smooth_density_adjoint, &
     295        32056 :          smooth_kin_adjoint
     296        32056 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :) :: composite_cross_grad, composite_grad, &
     297        32056 :          composite_grad_grad, composite_int_h, composite_int_s, composite_partition_datom, &
     298        64112 :          composite_partition_dstrain, cross_tau_coeff, cross_tau_h, cross_tau_s, &
     299        32056 :          smooth_grad_adjoint
     300              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
     301              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
     302              :       REAL(dp), DIMENSION(2)                             :: cross_density, cross_kin
     303              :       REAL(dp), DIMENSION(3) :: composite_point, nlcc_gradient, nlcc_spatial_derivative, &
     304              :          skala_atom_force_h, skala_atom_force_s, spatial_derivative
     305              :       REAL(dp), DIMENSION(3, 2)                          :: cross_grad
     306              :       REAL(dp), DIMENSION(3, 3)                          :: composite_explicit_virial, nlcc_hessian, &
     307              :                                                             skala_atom_virial, &
     308              :                                                             skala_atom_virial_h, &
     309              :                                                             skala_atom_virial_s
     310              :       REAL(dp), DIMENSION(4)                             :: feature_component_analytic, &
     311              :                                                             feature_component_fd
     312        64112 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
     313        32056 :       REAL(dp), DIMENSION(:, :, :), POINTER :: composite_smooth_rho, composite_smooth_rhoa, &
     314        32056 :          composite_smooth_rhob, composite_smooth_tau, composite_smooth_tau_a, &
     315        96168 :          composite_smooth_tau_b, rho_h, rho_s, smooth_rho, smooth_rhoa, smooth_rhob, smooth_tau, &
     316        32056 :          smooth_tau_a, smooth_tau_b, tau_h, tau_s, vtau_h, vtau_s, vxc_h, vxc_s
     317        64112 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho_h, drho_s, vxg_h, vxg_s
     318        32056 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     319              :       TYPE(cell_type), POINTER                           :: cell
     320       224392 :       TYPE(cp_3d_r_cp_type), DIMENSION(3) :: composite_smooth_drho, composite_smooth_drhoa, &
     321       448784 :          composite_smooth_drhob, smooth_drho, smooth_drhoa, smooth_drhob
     322              :       TYPE(dft_control_type), POINTER                    :: dft_control
     323              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
     324              :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     325              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
     326              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
     327              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     328        32056 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     329        32056 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: smooth_rho_g
     330              :       TYPE(pw_env_type), POINTER                         :: pw_env
     331              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     332        64112 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: smooth_rho_r, smooth_tau_r, &
     333        32056 :                                                             smooth_vxc_rho, smooth_vxc_tau
     334        32056 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     335        32056 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: my_kind_set
     336              :       TYPE(qs_rho_type), POINTER                         :: rho_struct
     337        32056 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: cpc_h, cpc_s, dr_h, dr_s, int_hh, &
     338        32056 :                                                             int_ss, r_h, r_s
     339        32056 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
     340        32056 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: my_rho_atom_set
     341              :       TYPE(rho_atom_type), POINTER                       :: rho_atom
     342              :       TYPE(section_vals_type), POINTER                   :: gauxc_section, input, my_xc_section, &
     343              :                                                             xc_fun_section
     344              :       TYPE(sgp_potential_type), POINTER                  :: sgp_potential
     345        32056 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
     346              :       TYPE(virial_type), POINTER                         :: virial
     347              :       TYPE(xc_derivative_set_type)                       :: deriv_set
     348              :       TYPE(xc_rho_cflags_type)                           :: needs
     349              :       TYPE(xc_rho_set_type)                              :: rho_set_h, rho_set_s, smooth_rho_set
     350              : 
     351              : ! -------------------------------------------------------------------------
     352              : 
     353        32056 :       CALL timeset(routineN, handle)
     354              : 
     355        32056 :       NULLIFY (atom_list)
     356        32056 :       NULLIFY (auxbas_pw_pool)
     357        32056 :       NULLIFY (my_kind_set)
     358        32056 :       NULLIFY (atomic_kind_set)
     359        32056 :       NULLIFY (cell)
     360        32056 :       NULLIFY (grid_atom)
     361        32056 :       NULLIFY (gth_potential)
     362        32056 :       NULLIFY (force)
     363        32056 :       NULLIFY (harmonics)
     364        32056 :       NULLIFY (input)
     365        32056 :       NULLIFY (para_env)
     366        32056 :       NULLIFY (particle_set)
     367        32056 :       NULLIFY (pw_env)
     368        32056 :       NULLIFY (rho_atom)
     369        32056 :       NULLIFY (rho_struct)
     370        32056 :       NULLIFY (my_rho_atom_set)
     371        32056 :       NULLIFY (rho_nlcc)
     372        32056 :       NULLIFY (smooth_rho, smooth_rhoa, smooth_rhob, smooth_tau, smooth_tau_a, smooth_tau_b)
     373        32056 :       NULLIFY (composite_smooth_rho, composite_smooth_rhoa, composite_smooth_rhob, &
     374        32056 :                composite_smooth_tau, composite_smooth_tau_a, composite_smooth_tau_b)
     375        32056 :       NULLIFY (smooth_rho_g, smooth_rho_r, smooth_tau_r)
     376        32056 :       NULLIFY (smooth_vxc_rho, smooth_vxc_tau)
     377       128224 :       DO idir = 1, 3
     378        96168 :          NULLIFY (smooth_drho(idir)%array, smooth_drhoa(idir)%array, smooth_drhob(idir)%array)
     379              :          NULLIFY (composite_smooth_drho(idir)%array, &
     380        96168 :                   composite_smooth_drhoa(idir)%array, &
     381       128224 :                   composite_smooth_drhob(idir)%array)
     382              :       END DO
     383        32056 :       NULLIFY (sgp_potential)
     384        32056 :       NULLIFY (virial)
     385        32056 :       my_calculate_forces = .FALSE.
     386        32056 :       IF (PRESENT(calculate_forces)) my_calculate_forces = calculate_forces
     387        32056 :       IF (PRESENT(composite_reference_active)) composite_reference_active = .FALSE.
     388              : 
     389        32056 :       IF (PRESENT(adiabatic_rescale_factor)) THEN
     390           44 :          my_adiabatic_rescale_factor = adiabatic_rescale_factor
     391              :       ELSE
     392        32012 :          my_adiabatic_rescale_factor = 1.0_dp
     393              :       END IF
     394              : 
     395              :       CALL get_qs_env(qs_env=qs_env, &
     396              :                       dft_control=dft_control, &
     397              :                       cell=cell, &
     398              :                       para_env=para_env, &
     399              :                       atomic_kind_set=atomic_kind_set, &
     400              :                       qs_kind_set=my_kind_set, &
     401              :                       input=input, &
     402              :                       particle_set=particle_set, &
     403              :                       pw_env=pw_env, &
     404              :                       rho=rho_struct, &
     405              :                       virial=virial, &
     406              :                       rho_atom_set=my_rho_atom_set, &
     407        32056 :                       force=force)
     408              : 
     409        32056 :       IF (PRESENT(kind_set_external)) my_kind_set => kind_set_external
     410        32056 :       IF (PRESENT(rho_atom_set_external)) my_rho_atom_set => rho_atom_set_external
     411              : 
     412        32056 :       nlcc = has_nlcc(my_kind_set)
     413        32056 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
     414              : 
     415        32056 :       my_xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     416              : 
     417        32056 :       IF (PRESENT(xc_section_external)) my_xc_section => xc_section_external
     418              : 
     419        32056 :       xc_fun_section => section_vals_get_subs_vals(my_xc_section, "XC_FUNCTIONAL")
     420              :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", &
     421        32056 :                                 i_val=myfun)
     422        32056 :       skala_atom_grid = xc_section_uses_gauxc_model(my_xc_section)
     423        32056 :       gapw_representation = skala_gapw_cp2k_default
     424        32056 :       atom_composite_diagnostic = .FALSE.
     425        32056 :       atom_composite_reference = .FALSE.
     426        32056 :       paw_pseudopotentials = .FALSE.
     427        32056 :       native_grid_diagnostics = .FALSE.
     428        32056 :       atom_composite_components = 1
     429        32056 :       feature_vxc_step = 3.0E-3_dp
     430        32056 :       IF (skala_atom_grid) THEN
     431           82 :          gauxc_section => get_gauxc_section(my_xc_section)
     432           82 :          CPASSERT(ASSOCIATED(gauxc_section))
     433              :          CALL section_vals_val_get(gauxc_section, "PSEUDOPOTENTIAL_GAPW_REPRESENTATION", &
     434           82 :                                    i_val=gapw_representation)
     435              :          CALL section_vals_val_get(gauxc_section, "NATIVE_GRID_DIAGNOSTICS", &
     436           82 :                                    l_val=native_grid_diagnostics)
     437              :       END IF
     438              :       force_paw_representation = gapw_representation == skala_gapw_paw_one_center .OR. &
     439        32056 :                                  gapw_representation == skala_gapw_paw_one_center_split
     440        32056 :       IF (skala_atom_grid) THEN
     441          172 :          DO ikind = 1, SIZE(my_kind_set)
     442           90 :             NULLIFY (gth_potential, sgp_potential)
     443              :             CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     444           90 :                              gth_potential=gth_potential, sgp_potential=sgp_potential)
     445              :             paw_pseudopotentials = paw_pseudopotentials .OR. &
     446              :                                    (paw_atom .AND. (ASSOCIATED(gth_potential) .OR. &
     447          212 :                                                     ASSOCIATED(sgp_potential)))
     448              :          END DO
     449              :       END IF
     450           82 :       IF (skala_atom_grid .AND. xc_section_uses_native_skala_evaluator(my_xc_section)) THEN
     451              :          CALL section_vals_val_get(gauxc_section, &
     452              :                                    "NATIVE_GRID_GAPW_ATOM_COMPOSITE_DIAGNOSTIC", &
     453           80 :                                    l_val=atom_composite_diagnostic)
     454              :          CALL section_vals_val_get(gauxc_section, &
     455              :                                    "NATIVE_GRID_GAPW_ATOM_COMPOSITE_REFERENCE", &
     456           80 :                                    l_val=atom_composite_reference)
     457              :          CALL section_vals_val_get(gauxc_section, &
     458              :                                    "NATIVE_GRID_GAPW_ATOM_COMPOSITE_COMPONENTS", &
     459           80 :                                    i_val=atom_composite_components)
     460              :          CALL section_vals_val_get(gauxc_section, &
     461              :                                    "NATIVE_GRID_GAPW_ATOM_COMPOSITE_FD_STEP", &
     462           80 :                                    r_val=feature_vxc_step)
     463              :       END IF
     464              :       atom_composite_reference = atom_composite_reference .OR. &
     465              :                                  (gapw_representation == skala_gapw_paw_one_center .AND. &
     466        32056 :                                   paw_pseudopotentials)
     467        32056 :       atom_composite_active = atom_composite_diagnostic .OR. atom_composite_reference
     468        32056 :       IF (PRESENT(composite_reference_active)) composite_reference_active = atom_composite_reference
     469        32056 :       gapw_density_partition = skala_gapw_density_partition_hard_minus_soft
     470        32056 :       IF (skala_atom_grid) THEN
     471           82 :          gapw_density_partition = native_skala_gapw_density_partition(my_xc_section)
     472              :       END IF
     473        32056 :       use_virial = ASSOCIATED(virial)
     474        32056 :       IF (use_virial) use_virial = my_calculate_forces .AND. &
     475        32056 :                                    virial%pv_calculate .AND. (.NOT. virial%pv_numer)
     476              : 
     477        32056 :       IF (myfun == xc_none) THEN
     478         4186 :          exc1 = 0.0_dp
     479        16378 :          my_rho_atom_set(:)%exc_h = 0.0_dp
     480        16378 :          my_rho_atom_set(:)%exc_s = 0.0_dp
     481              :       ELSE
     482              :          CALL section_vals_val_get(my_xc_section, "DENSITY_CUTOFF", &
     483        27870 :                                    r_val=density_cut)
     484              :          CALL section_vals_val_get(my_xc_section, "GRADIENT_CUTOFF", &
     485        27870 :                                    r_val=gradient_cut)
     486              :          CALL section_vals_val_get(my_xc_section, "TAU_CUTOFF", &
     487        27870 :                                    r_val=tau_cut)
     488              : 
     489        27870 :          lsd = dft_control%lsd
     490        27870 :          nspins = dft_control%nspins
     491              :          needs = xc_functionals_get_needs(xc_fun_section, &
     492              :                                           lsd=lsd, &
     493        27870 :                                           calc_potential=.TRUE.)
     494              : 
     495        27870 :          gradient_f = (needs%drho .OR. needs%drho_spin) .OR. skala_atom_grid
     496        27870 :          tau_f = (needs%tau .OR. needs%tau_spin) .OR. skala_atom_grid
     497              : 
     498        27870 :          IF (atom_composite_active) THEN
     499           28 :             IF (lsd) THEN
     500            0 :                needs%rho_spin = .TRUE.
     501            0 :                needs%drho_spin = .TRUE.
     502            0 :                needs%tau_spin = .TRUE.
     503              :             ELSE
     504           28 :                needs%rho = .TRUE.
     505           28 :                needs%drho = .TRUE.
     506           28 :                needs%tau = .TRUE.
     507              :             END IF
     508              : 
     509              :             ALLOCATE (composite_atomic_grid_sizes(SIZE(particle_set)), &
     510              :                       composite_atom_kind(SIZE(particle_set)), &
     511              :                       composite_atom_kind_index(SIZE(particle_set)), &
     512              :                       composite_atom_start(SIZE(particle_set)), &
     513              :                       composite_atom_end(SIZE(particle_set)), &
     514              :                       composite_atom_coords(3, SIZE(particle_set)), &
     515              :                       composite_partition_weights(SIZE(particle_set)), &
     516              :                       composite_partition_atom_coords(3, SIZE(particle_set)), &
     517          364 :                       composite_distances(SIZE(particle_set)))
     518           28 :             composite_atomic_grid_sizes = 0_int_8
     519           28 :             composite_atom_kind = 0
     520           28 :             composite_atom_kind_index = 0
     521           28 :             composite_atom_start = 0
     522           28 :             composite_atom_end = 0
     523           84 :             DO iatom = 1, SIZE(particle_set)
     524          252 :                composite_atom_coords(:, iatom) = particle_set(iatom)%r
     525              :             END DO
     526           60 :             DO ikind = 1, SIZE(atomic_kind_set)
     527           32 :                CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     528           32 :                NULLIFY (gth_potential, sgp_potential)
     529              :                CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     530              :                                 gth_potential=gth_potential, grid_atom=grid_atom, &
     531           32 :                                 sgp_potential=sgp_potential, zatom=zatom, zeff=zeff)
     532           32 :                IF (.NOT. paw_atom) CYCLE
     533              :                IF (.NOT. force_paw_representation .AND. &
     534           32 :                    (ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential)) .AND. &
     535              :                    ABS(zeff - REAL(zatom, dp)) <= 1.0E-10_dp) CYCLE
     536          148 :                DO iat = 1, natom
     537           56 :                   iatom = atom_list(iat)
     538           56 :                   composite_atomic_grid_sizes(iatom) = INT(grid_atom%nr*grid_atom%ng_sphere, KIND=int_8)
     539           56 :                   composite_atom_kind(iatom) = ikind
     540           88 :                   composite_atom_kind_index(iatom) = iat
     541              :                END DO
     542              :             END DO
     543           84 :             IF (ANY(composite_atomic_grid_sizes <= 0_int_8)) THEN
     544              :                CALL cp_abort(__LOCATION__, &
     545            0 :                              "The atom-composite diagnostic requires a GAPW one-center grid for every atom.")
     546              :             END IF
     547              : 
     548           28 :             composite_local_natom = 0
     549           60 :             DO ikind = 1, SIZE(atomic_kind_set)
     550           32 :                CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     551           32 :                NULLIFY (gth_potential, sgp_potential)
     552              :                CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     553              :                                 gth_potential=gth_potential, sgp_potential=sgp_potential, &
     554           32 :                                 zatom=zatom, zeff=zeff)
     555           32 :                IF (.NOT. paw_atom) CYCLE
     556              :                IF (.NOT. force_paw_representation .AND. &
     557           32 :                    (ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential)) .AND. &
     558              :                    ABS(zeff - REAL(zatom, dp)) <= 1.0E-10_dp) CYCLE
     559           32 :                bo = get_limit(natom, para_env%num_pe, para_env%mepos)
     560           92 :                composite_local_natom = composite_local_natom + MAX(0, bo(2) - bo(1) + 1)
     561              :             END DO
     562              :             ALLOCATE (composite_local_atoms(composite_local_natom), &
     563              :                       composite_local_grid_sizes(composite_local_natom), &
     564          190 :                       composite_local_atom_coords(3, composite_local_natom))
     565           28 :             composite_local_atom = 0
     566           28 :             composite_nflat = 0
     567           60 :             DO ikind = 1, SIZE(atomic_kind_set)
     568           32 :                CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     569           32 :                NULLIFY (gth_potential, sgp_potential)
     570              :                CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     571              :                                 gth_potential=gth_potential, sgp_potential=sgp_potential, &
     572           32 :                                 zatom=zatom, zeff=zeff)
     573           32 :                IF (.NOT. paw_atom) CYCLE
     574              :                IF (.NOT. force_paw_representation .AND. &
     575           32 :                    (ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential)) .AND. &
     576              :                    ABS(zeff - REAL(zatom, dp)) <= 1.0E-10_dp) CYCLE
     577           32 :                bo = get_limit(natom, para_env%num_pe, para_env%mepos)
     578          120 :                DO iat = bo(1), bo(2)
     579           28 :                   iatom = atom_list(iat)
     580           28 :                   composite_local_atom = composite_local_atom + 1
     581           28 :                   composite_local_atoms(composite_local_atom) = iatom
     582              :                   composite_local_grid_sizes(composite_local_atom) = &
     583           28 :                      composite_atomic_grid_sizes(iatom)
     584              :                   composite_local_atom_coords(:, composite_local_atom) = &
     585          112 :                      composite_atom_coords(:, iatom)
     586           28 :                   composite_atom_start(iatom) = composite_nflat + 1
     587           28 :                   composite_nflat = composite_nflat + INT(composite_atomic_grid_sizes(iatom))
     588           60 :                   composite_atom_end(iatom) = composite_nflat
     589              :                END DO
     590              :             END DO
     591           28 :             CPASSERT(composite_local_atom == composite_local_natom)
     592              :             ALLOCATE (composite_density(composite_nflat, 2), &
     593              :                       composite_grad(composite_nflat, 3, 2), &
     594              :                       composite_kin(composite_nflat, 2), &
     595              :                       composite_grid_coords(3, composite_nflat), &
     596              :                       composite_grid_weights(composite_nflat), &
     597          324 :                       composite_atomic_grid_weights(composite_nflat))
     598           28 :             composite_density = 0.0_dp
     599           28 :             composite_grad = 0.0_dp
     600           28 :             composite_kin = 0.0_dp
     601           28 :             composite_grid_coords = 0.0_dp
     602           28 :             composite_grid_weights = 0.0_dp
     603           28 :             composite_atomic_grid_weights = 0.0_dp
     604              : 
     605              :             CALL qs_rho_get(rho_struct, rho_r=smooth_rho_r, rho_g=smooth_rho_g, &
     606              :                             tau_r=smooth_tau_r, rho_g_valid=rho_g_valid, &
     607           28 :                             tau_r_valid=tau_r_valid)
     608           28 :             CPASSERT(rho_g_valid)
     609           28 :             CPASSERT(tau_r_valid)
     610           28 :             CPASSERT(ASSOCIATED(smooth_rho_r))
     611           28 :             CPASSERT(ASSOCIATED(smooth_rho_g))
     612           28 :             CPASSERT(ASSOCIATED(smooth_tau_r))
     613           28 :             CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     614              :             CALL section_vals_val_get(my_xc_section, "XC_GRID%XC_DERIV", &
     615           28 :                                       i_val=xc_deriv_method_id)
     616              :             CALL section_vals_val_get(my_xc_section, "XC_GRID%XC_SMOOTH_RHO", &
     617           28 :                                       i_val=xc_rho_smooth_id)
     618              :             CALL xc_rho_set_create(smooth_rho_set, smooth_rho_r(1)%pw_grid%bounds_local, &
     619              :                                    rho_cutoff=section_get_rval(my_xc_section, "density_cutoff"), &
     620              :                                    drho_cutoff=section_get_rval(my_xc_section, "gradient_cutoff"), &
     621           28 :                                    tau_cutoff=section_get_rval(my_xc_section, "tau_cutoff"))
     622              :             CALL xc_rho_set_update(smooth_rho_set, smooth_rho_r, smooth_rho_g, smooth_tau_r, needs, &
     623           28 :                                    xc_deriv_method_id, xc_rho_smooth_id, auxbas_pw_pool)
     624           84 :             IF (lsd) THEN
     625              :                CALL xc_rho_set_get(smooth_rho_set, rhoa=smooth_rhoa, rhob=smooth_rhob, &
     626              :                                    drhoa=smooth_drhoa, drhob=smooth_drhob, &
     627            0 :                                    tau_a=smooth_tau_a, tau_b=smooth_tau_b)
     628              :                CALL gather_native_grid_field(smooth_rhoa, smooth_rho_r(1)%pw_grid, para_env, &
     629            0 :                                              composite_smooth_rhoa)
     630              :                CALL gather_native_grid_field(smooth_rhob, smooth_rho_r(1)%pw_grid, para_env, &
     631            0 :                                              composite_smooth_rhob)
     632              :                CALL gather_native_grid_field(smooth_tau_a, smooth_rho_r(1)%pw_grid, para_env, &
     633            0 :                                              composite_smooth_tau_a)
     634              :                CALL gather_native_grid_field(smooth_tau_b, smooth_rho_r(1)%pw_grid, para_env, &
     635            0 :                                              composite_smooth_tau_b)
     636            0 :                DO idir = 1, 3
     637              :                   CALL gather_native_grid_field(smooth_drhoa(idir)%array, &
     638              :                                                 smooth_rho_r(1)%pw_grid, para_env, &
     639            0 :                                                 composite_smooth_drhoa(idir)%array)
     640              :                   CALL gather_native_grid_field(smooth_drhob(idir)%array, &
     641              :                                                 smooth_rho_r(1)%pw_grid, para_env, &
     642            0 :                                                 composite_smooth_drhob(idir)%array)
     643              :                END DO
     644              :             ELSE
     645              :                CALL xc_rho_set_get(smooth_rho_set, rho=smooth_rho, drho=smooth_drho, &
     646           28 :                                    tau=smooth_tau)
     647              :                CALL gather_native_grid_field(smooth_rho, smooth_rho_r(1)%pw_grid, para_env, &
     648           28 :                                              composite_smooth_rho)
     649              :                CALL gather_native_grid_field(smooth_tau, smooth_rho_r(1)%pw_grid, para_env, &
     650           28 :                                              composite_smooth_tau)
     651          112 :                DO idir = 1, 3
     652              :                   CALL gather_native_grid_field(smooth_drho(idir)%array, &
     653              :                                                 smooth_rho_r(1)%pw_grid, para_env, &
     654          112 :                                                 composite_smooth_drho(idir)%array)
     655              :                END DO
     656              :             END IF
     657              :          END IF
     658              : 
     659              :          ! Initialize energy contribution from the one center XC terms to zero
     660        27870 :          exc1 = 0.0_dp
     661              : 
     662              :          ! Nullify some pointers for work-arrays
     663        27870 :          NULLIFY (rho_h, drho_h, rho_s, drho_s, weight_h, weight_s)
     664        27870 :          NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
     665        27870 :          NULLIFY (tau_h, tau_s)
     666        27870 :          NULLIFY (vtau_h, vtau_s)
     667              : 
     668              :          ! Here starts the loop over all the atoms
     669              : 
     670        81956 :          DO ikind = 1, SIZE(atomic_kind_set)
     671        54086 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     672        54086 :             NULLIFY (gth_potential, sgp_potential)
     673              :             CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     674              :                              gth_potential=gth_potential, harmonics=harmonics, &
     675              :                              grid_atom=grid_atom, sgp_potential=sgp_potential, &
     676        54086 :                              zatom=zatom, zeff=zeff)
     677        54086 :             CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
     678              : 
     679        54086 :             IF (.NOT. paw_atom) CYCLE
     680              :             IF (skala_atom_grid .AND. .NOT. force_paw_representation .AND. &
     681        48828 :                 (ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential)) .AND. &
     682              :                 ABS(zeff - REAL(zatom, dp)) <= 1.0E-10_dp) CYCLE
     683              : 
     684        48812 :             nr = grid_atom%nr
     685        48812 :             na = grid_atom%ng_sphere
     686              : 
     687              :             ! Prepare the structures needed to calculate and store the xc derivatives
     688              : 
     689              :             ! Array dimension: here anly one dimensional arrays are used,
     690              :             ! i.e. only the first column of deriv_data is read.
     691              :             ! The other to dimensions  are set to size equal 1
     692       488120 :             bounds(1:2, 1:3) = 1
     693        48812 :             bounds(2, 1) = na
     694        48812 :             bounds(2, 2) = nr
     695              : 
     696              :             ! set integration weights
     697        48812 :             IF (accint) THEN
     698        14550 :                weight_h => grid_atom%weight
     699        14550 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
     700        14550 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     701        14016 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
     702              :                END IF
     703        14550 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     704         2136 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
     705        27234 :                   DO ir = 1, nr
     706        26700 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
     707      1362234 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
     708              :                   END DO
     709          534 :                   grid_atom%gapw_weight_alpha = alpha
     710              :                END IF
     711        14550 :                weight_s => grid_atom%gapw_weight_s
     712              :             ELSE
     713        34262 :                weight_h => grid_atom%weight
     714        34262 :                weight_s => grid_atom%weight
     715              :             END IF
     716              : 
     717              :             ! create a place where to put the derivatives
     718        48812 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
     719              :             ! create the place where to store the argument for the functionals
     720              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
     721        48812 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     722              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
     723        48812 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     724              : 
     725              :             ! allocate the required 3d arrays where to store rho and drho
     726        48812 :             CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
     727        48812 :             CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
     728              : 
     729        48812 :             CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
     730        48812 :             CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
     731        48812 :             CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
     732        48812 :             CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
     733              :             !
     734        48812 :             IF (gradient_f) THEN
     735        32682 :                CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
     736        32682 :                CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
     737        32682 :                CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
     738        32682 :                CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
     739              :             END IF
     740              : 
     741        48812 :             IF (tau_f) THEN
     742         1268 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
     743         1268 :                CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
     744         1268 :                CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
     745         1268 :                CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
     746         1268 :                CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
     747              :             END IF
     748              : 
     749              :             ! NLCC: prepare rho and drho of the core charge for this KIND
     750        48812 :             donlcc = .FALSE.
     751        48812 :             IF (nlcc) THEN
     752          462 :                NULLIFY (rho_nlcc)
     753          462 :                rho_nlcc => my_kind_set(ikind)%nlcc_pot
     754          462 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
     755              :             END IF
     756              : 
     757              :             ! Distribute the atoms of this kind
     758              : 
     759        48812 :             num_pe = para_env%num_pe
     760        48812 :             bo = get_limit(natom, para_env%num_pe, para_env%mepos)
     761              : 
     762        87042 :             DO iat = bo(1), bo(2)
     763        38230 :                iatom = atom_list(iat)
     764              : 
     765        38230 :                my_rho_atom_set(iatom)%exc_h = 0.0_dp
     766        38230 :                my_rho_atom_set(iatom)%exc_s = 0.0_dp
     767              : 
     768        38230 :                rho_atom => my_rho_atom_set(iatom)
     769    123566561 :                rho_h = 0.0_dp
     770    123566561 :                rho_s = 0.0_dp
     771        38230 :                IF (gradient_f) THEN
     772        24866 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
     773              :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
     774              :                                     rho_rad_s=r_s, drho_rad_h=dr_h, &
     775              :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
     776        24866 :                                     rho_rad_s_d=r_s_d)
     777    363512178 :                   drho_h = 0.0_dp
     778    363512178 :                   drho_s = 0.0_dp
     779              :                ELSE
     780        13364 :                   NULLIFY (r_h, r_s)
     781        13364 :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
     782        13364 :                   rho_d = 0.0_dp
     783              :                END IF
     784        38230 :                IF (tau_f) THEN
     785              :                   !compute tau on the grid all at once
     786          895 :                   CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
     787              :                ELSE
     788        37335 :                   tau_d = 0.0_dp
     789              :                END IF
     790              : 
     791      2120170 :                DO ir = 1, nr
     792              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
     793              :                                         ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
     794      2081940 :                                         r_h_d, r_s_d, drho_h, drho_s)
     795      2120170 :                   IF (donlcc) THEN
     796              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
     797         8700 :                                         ir, rho_nlcc(:, 1), rho_h, rho_s, rho_nlcc(:, 2), drho_h, drho_s)
     798              :                   END IF
     799              :                END DO
     800              : 
     801        38230 :                IF (atom_composite_active) THEN
     802           28 :                   composite_row = composite_atom_start(iatom) - 1
     803         1428 :                   DO ir = 1, nr
     804        71428 :                      DO ia = 1, na
     805        70000 :                         composite_row = composite_row + 1
     806              :                         composite_point(1) = particle_set(iatom)%r(1) + grid_atom%rad(ir)* &
     807        70000 :                                              grid_atom%sin_pol(ia)*grid_atom%cos_azi(ia)
     808              :                         composite_point(2) = particle_set(iatom)%r(2) + grid_atom%rad(ir)* &
     809        70000 :                                              grid_atom%sin_pol(ia)*grid_atom%sin_azi(ia)
     810              :                         composite_point(3) = particle_set(iatom)%r(3) + &
     811        70000 :                                              grid_atom%rad(ir)*grid_atom%cos_pol(ia)
     812       280000 :                         composite_grid_coords(:, composite_row) = composite_point
     813              :                         CALL smooth_atom_partition( &
     814              :                            composite_point, composite_atom_coords, cell, &
     815              :                            composite_partition_weights, composite_partition_atom_coords, &
     816        70000 :                            composite_distances)
     817        70000 :                         composite_atomic_grid_weights(composite_row) = grid_atom%weight(ia, ir)
     818              :                         composite_grid_weights(composite_row) = grid_atom%weight(ia, ir)* &
     819        70000 :                                                                 composite_partition_weights(iatom)
     820        70000 :                         IF (lsd) THEN
     821            0 :                            DO ispin = 1, 2
     822            0 :                               IF (ispin == 1) THEN
     823              :                                  composite_density(composite_row, ispin) = &
     824              :                                     interpolate_native_grid(composite_smooth_rhoa, &
     825              :                                                             smooth_rho_r(1)%pw_grid, &
     826            0 :                                                             cell, composite_point)
     827              :                                  composite_kin(composite_row, ispin) = &
     828              :                                     interpolate_native_grid(composite_smooth_tau_a, &
     829              :                                                             smooth_rho_r(1)%pw_grid, &
     830            0 :                                                             cell, composite_point)
     831            0 :                                  DO idir = 1, 3
     832              :                                     composite_grad(composite_row, idir, ispin) = &
     833              :                                        interpolate_native_grid(composite_smooth_drhoa(idir)%array, &
     834              :                                                                smooth_rho_r(1)%pw_grid, cell, &
     835            0 :                                                                composite_point)
     836              :                                  END DO
     837              :                               ELSE
     838              :                                  composite_density(composite_row, ispin) = &
     839              :                                     interpolate_native_grid(composite_smooth_rhob, &
     840              :                                                             smooth_rho_r(1)%pw_grid, &
     841            0 :                                                             cell, composite_point)
     842              :                                  composite_kin(composite_row, ispin) = &
     843              :                                     interpolate_native_grid(composite_smooth_tau_b, &
     844              :                                                             smooth_rho_r(1)%pw_grid, &
     845            0 :                                                             cell, composite_point)
     846            0 :                                  DO idir = 1, 3
     847              :                                     composite_grad(composite_row, idir, ispin) = &
     848              :                                        interpolate_native_grid(composite_smooth_drhob(idir)%array, &
     849              :                                                                smooth_rho_r(1)%pw_grid, cell, &
     850            0 :                                                                composite_point)
     851              :                                  END DO
     852              :                               END IF
     853            0 :                               IF (atom_composite_components <= 2) THEN
     854              :                                  composite_density(composite_row, ispin) = &
     855              :                                     composite_density(composite_row, ispin) + &
     856            0 :                                     rho_h(ia, ir, ispin) - rho_s(ia, ir, ispin)
     857            0 :                                  DO idir = 1, 3
     858              :                                     composite_grad(composite_row, idir, ispin) = &
     859              :                                        composite_grad(composite_row, idir, ispin) + &
     860            0 :                                        drho_h(idir, ia, ir, ispin) - drho_s(idir, ia, ir, ispin)
     861              :                                  END DO
     862              :                               END IF
     863            0 :                               IF (atom_composite_components == 1 .OR. &
     864            0 :                                   atom_composite_components == 3) THEN
     865              :                                  composite_kin(composite_row, ispin) = &
     866              :                                     composite_kin(composite_row, ispin) + &
     867            0 :                                     tau_h(ia, ir, ispin) - tau_s(ia, ir, ispin)
     868              :                               END IF
     869              :                            END DO
     870              :                         ELSE
     871              :                            composite_density(composite_row, :) = 0.5_dp* &
     872              :                                                                  interpolate_native_grid(composite_smooth_rho, &
     873              :                                                                                          smooth_rho_r(1)%pw_grid, &
     874       210000 :                                                                                          cell, composite_point)
     875              :                            composite_kin(composite_row, :) = 0.5_dp* &
     876              :                                                              interpolate_native_grid(composite_smooth_tau, &
     877              :                                                                                      smooth_rho_r(1)%pw_grid, &
     878       210000 :                                                                                      cell, composite_point)
     879       280000 :                            DO idir = 1, 3
     880              :                               composite_grad(composite_row, idir, :) = 0.5_dp* &
     881              :                                                                        interpolate_native_grid(composite_smooth_drho(idir)%array, &
     882              :                                                                                                smooth_rho_r(1)%pw_grid, cell, &
     883       700000 :                                                                                                composite_point)
     884              :                            END DO
     885        70000 :                            IF (atom_composite_components <= 2) THEN
     886              :                               composite_density(composite_row, :) = &
     887              :                                  composite_density(composite_row, :) + &
     888       210000 :                                  0.5_dp*(rho_h(ia, ir, 1) - rho_s(ia, ir, 1))
     889       280000 :                               DO idir = 1, 3
     890              :                                  composite_grad(composite_row, idir, :) = &
     891              :                                     composite_grad(composite_row, idir, :) + &
     892              :                                     0.5_dp*(drho_h(idir, ia, ir, 1) - &
     893       700000 :                                             drho_s(idir, ia, ir, 1))
     894              :                               END DO
     895              :                            END IF
     896        70000 :                            IF (atom_composite_components == 1 .OR. &
     897              :                                atom_composite_components == 3) THEN
     898              :                               composite_kin(composite_row, :) = composite_kin(composite_row, :) + &
     899              :                                                                 0.5_dp*(tau_h(ia, ir, 1) - &
     900       210000 :                                                                         tau_s(ia, ir, 1))
     901              :                            END IF
     902              :                         END IF
     903        71400 :                         IF (atom_composite_reference .AND. nlcc) THEN
     904        10000 :                            nlcc_spin_factor = MERGE(1.0_dp, 0.5_dp, lsd)
     905        30000 :                            DO source_atom = 1, SIZE(particle_set)
     906        20000 :                               NULLIFY (gth_potential, sgp_potential)
     907              :                               CALL get_qs_kind(my_kind_set(composite_atom_kind(source_atom)), &
     908              :                                                gth_potential=gth_potential, &
     909        20000 :                                                sgp_potential=sgp_potential)
     910              :                               CALL evaluate_nlcc_primitive_fields( &
     911              :                                  composite_point, particle_set(source_atom)%r, &
     912              :                                  gth_potential, sgp_potential, nlcc_density, &
     913        20000 :                                  nlcc_gradient, nlcc_hessian)
     914              :                               composite_density(composite_row, :) = &
     915              :                                  composite_density(composite_row, :) + &
     916        60000 :                                  nlcc_spin_factor*nlcc_density
     917        90000 :                               DO idir = 1, 3
     918              :                                  composite_grad(composite_row, idir, :) = &
     919              :                                     composite_grad(composite_row, idir, :) + &
     920       200000 :                                     nlcc_spin_factor*nlcc_gradient(idir)
     921              :                               END DO
     922              :                            END DO
     923              :                         END IF
     924              :                      END DO
     925              :                   END DO
     926           28 :                   CPASSERT(composite_row == composite_atom_end(iatom))
     927              :                END IF
     928              : 
     929      2120170 :                DO ir = 1, nr
     930      2120170 :                   IF (tau_f) THEN
     931        46050 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
     932        46050 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
     933      2035890 :                   ELSE IF (gradient_f) THEN
     934      1214590 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
     935      1214590 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
     936              :                   ELSE
     937       821300 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
     938       821300 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
     939              :                   END IF
     940              :                END DO
     941              : 
     942        38230 :                evaluate_hard = .TRUE.
     943        38230 :                evaluate_soft = .TRUE.
     944        38230 :                skala_atom_force_h = 0.0_dp
     945        38230 :                skala_atom_force_s = 0.0_dp
     946        38230 :                skala_atom_virial_h = 0.0_dp
     947        38230 :                skala_atom_virial_s = 0.0_dp
     948        38230 :                IF (skala_atom_grid) THEN
     949              :                   SELECT CASE (gapw_density_partition)
     950              :                   CASE (skala_gapw_density_partition_hard_minus_soft)
     951            0 :                      CONTINUE
     952              :                   CASE (skala_gapw_density_partition_hard_only)
     953            0 :                      evaluate_soft = .FALSE.
     954              :                   CASE (skala_gapw_density_partition_soft_only)
     955            0 :                      evaluate_hard = .FALSE.
     956              :                   CASE (skala_gapw_density_partition_none)
     957            0 :                      evaluate_hard = .FALSE.
     958            0 :                      evaluate_soft = .FALSE.
     959              :                   CASE DEFAULT
     960              :                      CALL cp_abort(__LOCATION__, &
     961           46 :                                    "Unknown GAUXC%NATIVE_GRID_GAPW_DENSITY_PARTITION value.")
     962              :                   END SELECT
     963              :                END IF
     964        38230 :                IF (atom_composite_reference) THEN
     965           28 :                   evaluate_hard = .FALSE.
     966           28 :                   evaluate_soft = .FALSE.
     967              :                END IF
     968              : 
     969              :                !-------------------!
     970              :                ! hard atom density !
     971              :                !-------------------!
     972        38230 :                CALL xc_dset_zero_all(deriv_set)
     973        38230 :                IF (.NOT. evaluate_hard) THEN
     974           28 :                   exc_h = 0.0_dp
     975           28 :                   IF (.NOT. energy_only) THEN
     976        71456 :                      vxc_h = 0.0_dp
     977       281456 :                      IF (ASSOCIATED(vxg_h)) vxg_h = 0.0_dp
     978        71456 :                      IF (ASSOCIATED(vtau_h)) vtau_h = 0.0_dp
     979              :                   END IF
     980        38202 :                ELSE IF (skala_atom_grid) THEN
     981              :                   CALL skala_gapw_atom_vxc_of_r( &
     982              :                      my_xc_section, grid_atom, para_env, particle_set(iatom)%r, &
     983              :                      rho_h, drho_h, tau_h, weight_h, lsd, nspins, na, nr, &
     984              :                      exc_h, vxc_h, vxg_h, vtau_h, energy_only=energy_only, &
     985           18 :                      atom_force=skala_atom_force_h, atom_virial=skala_atom_virial_h)
     986              :                ELSE
     987              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_h, deriv_set, 1, needs, weight_h, &
     988              :                                     lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h, energy_only=energy_only, &
     989        38184 :                                     adiabatic_rescale_factor=my_adiabatic_rescale_factor)
     990              :                END IF
     991        38230 :                rho_atom%exc_h = rho_atom%exc_h + exc_h
     992              : 
     993              :                !-------------------!
     994              :                ! soft atom density !
     995              :                !-------------------!
     996        38230 :                CALL xc_dset_zero_all(deriv_set)
     997        38230 :                IF (.NOT. evaluate_soft) THEN
     998           28 :                   exc_s = 0.0_dp
     999           28 :                   IF (.NOT. energy_only) THEN
    1000        71456 :                      vxc_s = 0.0_dp
    1001       281456 :                      IF (ASSOCIATED(vxg_s)) vxg_s = 0.0_dp
    1002        71456 :                      IF (ASSOCIATED(vtau_s)) vtau_s = 0.0_dp
    1003              :                   END IF
    1004        38202 :                ELSE IF (skala_atom_grid) THEN
    1005              :                   CALL skala_gapw_atom_vxc_of_r( &
    1006              :                      my_xc_section, grid_atom, para_env, particle_set(iatom)%r, &
    1007              :                      rho_s, drho_s, tau_s, weight_s, lsd, nspins, na, nr, &
    1008              :                      exc_s, vxc_s, vxg_s, vtau_s, energy_only=energy_only, &
    1009           18 :                      atom_force=skala_atom_force_s, atom_virial=skala_atom_virial_s)
    1010              :                ELSE
    1011              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_s, deriv_set, 1, needs, weight_s, &
    1012              :                                     lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s, energy_only=energy_only, &
    1013        38184 :                                     adiabatic_rescale_factor=my_adiabatic_rescale_factor)
    1014              :                END IF
    1015        38230 :                rho_atom%exc_s = rho_atom%exc_s + exc_s
    1016              : 
    1017              :                ! Add contributions to the exc energy
    1018              : 
    1019        38230 :                exc1 = exc1 + rho_atom%exc_h - rho_atom%exc_s
    1020        38230 :                IF (skala_atom_grid .AND. my_calculate_forces .AND. ASSOCIATED(force)) THEN
    1021              :                   force(ikind)%rho_elec(:, iat) = force(ikind)%rho_elec(:, iat) + &
    1022           48 :                                                   skala_atom_force_h - skala_atom_force_s
    1023              :                END IF
    1024        38230 :                IF (skala_atom_grid .AND. use_virial) THEN
    1025          104 :                   skala_atom_virial = skala_atom_virial_h - skala_atom_virial_s
    1026           32 :                   DO idir = 1, 3
    1027          104 :                      DO jdir = 1, 3
    1028              :                         virial%pv_gapw(idir, jdir) = virial%pv_gapw(idir, jdir) + &
    1029           72 :                                                      skala_atom_virial(idir, jdir)
    1030              :                         virial%pv_virial(idir, jdir) = virial%pv_virial(idir, jdir) + &
    1031           96 :                                                        skala_atom_virial(idir, jdir)
    1032              :                      END DO
    1033              :                   END DO
    1034              :                END IF
    1035              : 
    1036              :                ! Integration to get the matrix elements relative to the vxc_atom
    1037              :                ! here the products with the primitives is done: gaVxcgb
    1038              :                ! internal transformation to get the integral in cartesian Gaussians
    1039              : 
    1040        38230 :                IF (.NOT. energy_only) THEN
    1041        36615 :                   NULLIFY (int_hh, int_ss)
    1042        36615 :                   CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    1043        36615 :                   IF (gradient_f) THEN
    1044              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    1045        23415 :                                      grid_atom, basis_1c, harmonics, nspins)
    1046              :                   ELSE
    1047              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
    1048        13200 :                                        grid_atom, basis_1c, harmonics, nspins)
    1049              :                   END IF
    1050        36615 :                   IF (tau_f) THEN
    1051              :                      CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
    1052          895 :                                      tau_basis_cache, nspins)
    1053              :                   END IF
    1054              :                END IF ! energy_only
    1055        87042 :                NULLIFY (r_h, r_s, dr_h, dr_s)
    1056              :             END DO ! iat
    1057              : 
    1058        48812 :             IF (tau_f) CALL release_tau_basis_cache(tau_basis_cache)
    1059              : 
    1060              :             ! Release the xc structure used to store the xc derivatives
    1061        48812 :             CALL xc_dset_release(deriv_set)
    1062        48812 :             CALL xc_rho_set_release(rho_set_h)
    1063       179580 :             CALL xc_rho_set_release(rho_set_s)
    1064              :          END DO ! ikind
    1065              : 
    1066        27870 :          IF (atom_composite_active) THEN
    1067              :             ALLOCATE (composite_cross_density(composite_nflat, 2), &
    1068              :                       composite_cross_grad(composite_nflat, 3, 2), &
    1069          190 :                       composite_cross_kin(composite_nflat, 2))
    1070           28 :             composite_cross_density = 0.0_dp
    1071           28 :             composite_cross_grad = 0.0_dp
    1072           28 :             composite_cross_kin = 0.0_dp
    1073           60 :             DO ikind = 1, SIZE(atomic_kind_set)
    1074           32 :                CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    1075           32 :                NULLIFY (gth_potential, sgp_potential)
    1076              :                CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
    1077              :                                 gth_potential=gth_potential, harmonics=harmonics, &
    1078              :                                 grid_atom=grid_atom, sgp_potential=sgp_potential, &
    1079           32 :                                 zatom=zatom, zeff=zeff)
    1080           32 :                CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    1081           32 :                IF (.NOT. paw_atom) CYCLE
    1082              :                IF (.NOT. force_paw_representation .AND. &
    1083           32 :                    (ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential)) .AND. &
    1084              :                    ABS(zeff - REAL(zatom, dp)) <= 1.0E-10_dp) CYCLE
    1085              : 
    1086              :                CALL replicate_rho_atom_radial( &
    1087           32 :                   para_env, my_rho_atom_set, my_kind_set(ikind), atom_list, natom, nspins)
    1088           32 :                nr = grid_atom%nr
    1089           32 :                na = grid_atom%ng_sphere
    1090           32 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    1091            0 :                ALLOCATE (cross_tau_h(na, nr, nspins), cross_tau_s(na, nr, nspins), &
    1092          384 :                          cross_tau_coeff(nr, harmonics%max_iso_not0, nspins))
    1093              : 
    1094              :                ! The one-center density matrices are already globally reduced. Distribute the
    1095              :                ! overlap work by target atom so that every rank constructs only its model rows.
    1096           88 :                DO iat = 1, natom
    1097           56 :                   source_atom = atom_list(iat)
    1098           56 :                   rho_atom => my_rho_atom_set(source_atom)
    1099           56 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    1100              :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s, &
    1101              :                                     drho_rad_h=dr_h, drho_rad_s=dr_s, &
    1102           56 :                                     rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    1103           56 :                   CALL calc_tau_atom(cross_tau_h, cross_tau_s, rho_atom, tau_basis_cache, nspins)
    1104           56 :                   cross_tau_coeff = 0.0_dp
    1105          112 :                   DO ispin = 1, nspins
    1106         2912 :                      DO ir = 1, nr
    1107        26456 :                         DO ia = 1, harmonics%max_iso_not0
    1108              :                            cross_tau_coeff(ir, ia, ispin) = &
    1109              :                               DOT_PRODUCT(grid_atom%wa, &
    1110              :                                           (cross_tau_h(:, ir, ispin) - &
    1111      1206400 :                                            cross_tau_s(:, ir, ispin))*harmonics%slm(:, ia))
    1112              :                         END DO
    1113              :                      END DO
    1114              :                   END DO
    1115              : 
    1116           56 :                   cross_last_ir = 0
    1117           56 :                   DO ir = nr, 1, -1
    1118          584 :                      cross_amplitude = MAXVAL(ABS(cross_tau_coeff(ir, :, :)))
    1119          112 :                      DO ispin = 1, nspins
    1120              :                         cross_amplitude = MAX(cross_amplitude, &
    1121              :                                               MAXVAL(ABS(r_h(ispin)%r_coef(ir, :) - &
    1122              :                                                          r_s(ispin)%r_coef(ir, :))), &
    1123              :                                               MAXVAL(ABS(dr_h(ispin)%r_coef(ir, :) - &
    1124         1000 :                                                          dr_s(ispin)%r_coef(ir, :))))
    1125          280 :                         DO idir = 1, 3
    1126              :                            cross_amplitude = MAX(cross_amplitude, &
    1127              :                                                  MAXVAL(ABS(r_h_d(idir, ispin)%r_coef(ir, :) - &
    1128         1640 :                                                             r_s_d(idir, ispin)%r_coef(ir, :))))
    1129              :                         END DO
    1130              :                      END DO
    1131           56 :                      IF (cross_amplitude > 1.0E-12_dp) THEN
    1132              :                         cross_last_ir = ir
    1133              :                         EXIT
    1134              :                      END IF
    1135              :                   END DO
    1136           56 :                   IF (cross_last_ir == 0) CYCLE
    1137           56 :                   cross_cutoff = grid_atom%rad(MIN(nr, cross_last_ir + 2))
    1138              : 
    1139          144 :                   DO composite_local_atom = 1, composite_local_natom
    1140           56 :                      target_atom = composite_local_atoms(composite_local_atom)
    1141           56 :                      IF (target_atom == source_atom) CYCLE
    1142        70028 :                      DO composite_row = composite_atom_start(target_atom), &
    1143           84 :                         composite_atom_end(target_atom)
    1144              :                         CALL evaluate_gapw_atom_delta( &
    1145              :                            grid_atom, harmonics, r_h, r_s, dr_h, dr_s, r_h_d, r_s_d, &
    1146              :                            cross_tau_coeff, nspins, cross_cutoff, particle_set(source_atom)%r, &
    1147              :                            composite_grid_coords(:, composite_row), cell, &
    1148        70000 :                            cross_density, cross_grad, cross_kin)
    1149        70056 :                         IF (lsd) THEN
    1150            0 :                            IF (atom_composite_components <= 2) THEN
    1151              :                               composite_cross_density(composite_row, 1:2) = &
    1152            0 :                                  composite_cross_density(composite_row, 1:2) + cross_density(1:2)
    1153              :                               composite_cross_grad(composite_row, :, 1:2) = &
    1154            0 :                                  composite_cross_grad(composite_row, :, 1:2) + cross_grad(:, 1:2)
    1155              :                            END IF
    1156            0 :                            IF (atom_composite_components == 1 .OR. &
    1157              :                                atom_composite_components == 3) THEN
    1158              :                               composite_cross_kin(composite_row, 1:2) = &
    1159            0 :                                  composite_cross_kin(composite_row, 1:2) + cross_kin(1:2)
    1160              :                            END IF
    1161              :                         ELSE
    1162        70000 :                            IF (atom_composite_components <= 2) THEN
    1163              :                               composite_cross_density(composite_row, :) = &
    1164       210000 :                                  composite_cross_density(composite_row, :) + 0.5_dp*cross_density(1)
    1165       280000 :                               DO idir = 1, 3
    1166              :                                  composite_cross_grad(composite_row, idir, :) = &
    1167              :                                     composite_cross_grad(composite_row, idir, :) + &
    1168       700000 :                                     0.5_dp*cross_grad(idir, 1)
    1169              :                               END DO
    1170              :                            END IF
    1171        70000 :                            IF (atom_composite_components == 1 .OR. &
    1172              :                                atom_composite_components == 3) THEN
    1173              :                               composite_cross_kin(composite_row, :) = &
    1174       210000 :                                  composite_cross_kin(composite_row, :) + 0.5_dp*cross_kin(1)
    1175              :                            END IF
    1176              :                         END IF
    1177              :                      END DO
    1178              :                   END DO
    1179              :                END DO
    1180              : 
    1181           32 :                DEALLOCATE (cross_tau_coeff, cross_tau_h, cross_tau_s)
    1182           92 :                CALL release_tau_basis_cache(tau_basis_cache)
    1183              :             END DO
    1184              : 
    1185       140084 :             composite_density(:, :) = composite_density(:, :) + composite_cross_density(:, :)
    1186       420252 :             composite_grad(:, :, :) = composite_grad(:, :, :) + composite_cross_grad(:, :, :)
    1187       140084 :             composite_kin(:, :) = composite_kin(:, :) + composite_cross_kin(:, :)
    1188           28 :             DEALLOCATE (composite_cross_density, composite_cross_grad, composite_cross_kin)
    1189              : 
    1190        70028 :             CPASSERT(ALL(composite_grid_weights >= 0.0_dp))
    1191              :             atom_composite_nelec = SUM(composite_grid_weights* &
    1192        70028 :                                        (composite_density(:, 1) + composite_density(:, 2)))
    1193           28 :             CALL para_env%sum(atom_composite_nelec)
    1194           28 :             IF (atom_composite_reference .AND. my_calculate_forces) THEN
    1195              :                CALL skala_gapw_atom_composite_energy( &
    1196              :                   my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
    1197              :                   composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
    1198              :                   composite_local_grid_sizes, composite_local_atom_coords, atom_composite_exc, &
    1199              :                   composite_density_grad, composite_grad_grad, composite_kin_grad, &
    1200              :                   composite_grid_coord_grad, composite_grid_weight_grad, &
    1201            4 :                   composite_atomic_grid_weight_grad, composite_atom_coord_grad)
    1202            0 :                ALLOCATE (composite_explicit_force(3, SIZE(particle_set)), &
    1203            0 :                          composite_grid_coord_force(3, SIZE(particle_set)), &
    1204            0 :                          composite_model_atom_force(3, SIZE(particle_set)), &
    1205            0 :                          composite_moving_smooth_force(3, SIZE(particle_set)), &
    1206            0 :                          composite_nlcc_center_force(3, SIZE(particle_set)), &
    1207            0 :                          composite_partition_force(3, SIZE(particle_set)), &
    1208            0 :                          composite_partition_included(SIZE(particle_set)), &
    1209            0 :                          composite_partition_datom(3, SIZE(particle_set), SIZE(particle_set)), &
    1210           60 :                          composite_partition_dstrain(3, 3, SIZE(particle_set)))
    1211            4 :                composite_model_atom_force = 0.0_dp
    1212            4 :                composite_grid_coord_force = 0.0_dp
    1213            4 :                composite_moving_smooth_force = 0.0_dp
    1214            4 :                composite_nlcc_center_force = 0.0_dp
    1215            4 :                composite_partition_force = 0.0_dp
    1216            8 :                DO composite_local_atom = 1, composite_local_natom
    1217            4 :                   iatom = composite_local_atoms(composite_local_atom)
    1218              :                   composite_model_atom_force(:, iatom) = &
    1219           16 :                      composite_atom_coord_grad(:, composite_local_atom)
    1220        10008 :                   DO composite_row = composite_atom_start(iatom), composite_atom_end(iatom)
    1221              :                      composite_grid_coord_force(:, iatom) = &
    1222              :                         composite_grid_coord_force(:, iatom) + &
    1223        40000 :                         composite_grid_coord_grad(:, composite_row)
    1224        10000 :                      IF (lsd) THEN
    1225              :                         spatial_derivative = &
    1226              :                            composite_density_grad(composite_row, 1)* &
    1227              :                            interpolate_native_grid_gradient( &
    1228              :                            composite_smooth_rhoa, smooth_rho_r(1)%pw_grid, cell, &
    1229              :                            composite_grid_coords(:, composite_row)) + &
    1230              :                            composite_density_grad(composite_row, 2)* &
    1231              :                            interpolate_native_grid_gradient( &
    1232              :                            composite_smooth_rhob, smooth_rho_r(1)%pw_grid, cell, &
    1233              :                            composite_grid_coords(:, composite_row)) + &
    1234              :                            composite_kin_grad(composite_row, 1)* &
    1235              :                            interpolate_native_grid_gradient( &
    1236              :                            composite_smooth_tau_a, smooth_rho_r(1)%pw_grid, cell, &
    1237              :                            composite_grid_coords(:, composite_row)) + &
    1238              :                            composite_kin_grad(composite_row, 2)* &
    1239              :                            interpolate_native_grid_gradient( &
    1240              :                            composite_smooth_tau_b, smooth_rho_r(1)%pw_grid, cell, &
    1241            0 :                            composite_grid_coords(:, composite_row))
    1242            0 :                         DO idir = 1, 3
    1243              :                            spatial_derivative = spatial_derivative + &
    1244              :                                                 composite_grad_grad(composite_row, idir, 1)* &
    1245              :                                                 interpolate_native_grid_gradient( &
    1246              :                                                 composite_smooth_drhoa(idir)%array, &
    1247              :                                                 smooth_rho_r(1)%pw_grid, cell, &
    1248              :                                                 composite_grid_coords(:, composite_row)) + &
    1249              :                                                 composite_grad_grad(composite_row, idir, 2)* &
    1250              :                                                 interpolate_native_grid_gradient( &
    1251              :                                                 composite_smooth_drhob(idir)%array, &
    1252              :                                                 smooth_rho_r(1)%pw_grid, cell, &
    1253            0 :                                                 composite_grid_coords(:, composite_row))
    1254              :                         END DO
    1255              :                      ELSE
    1256              :                         spatial_derivative = 0.5_dp*SUM( &
    1257              :                                              composite_density_grad(composite_row, :))* &
    1258              :                                              interpolate_native_grid_gradient( &
    1259              :                                              composite_smooth_rho, smooth_rho_r(1)%pw_grid, cell, &
    1260              :                                              composite_grid_coords(:, composite_row)) + &
    1261              :                                              0.5_dp*SUM(composite_kin_grad(composite_row, :))* &
    1262              :                                              interpolate_native_grid_gradient( &
    1263              :                                              composite_smooth_tau, smooth_rho_r(1)%pw_grid, cell, &
    1264        80000 :                                              composite_grid_coords(:, composite_row))
    1265        40000 :                         DO idir = 1, 3
    1266              :                            spatial_derivative = spatial_derivative + 0.5_dp*SUM( &
    1267              :                                                 composite_grad_grad(composite_row, idir, :))* &
    1268              :                                                 interpolate_native_grid_gradient( &
    1269              :                                                 composite_smooth_drho(idir)%array, &
    1270              :                                                 smooth_rho_r(1)%pw_grid, &
    1271       190000 :                                                 cell, composite_grid_coords(:, composite_row))
    1272              :                         END DO
    1273              :                      END IF
    1274        10000 :                      IF (nlcc) THEN
    1275         5000 :                         nlcc_spin_factor = MERGE(1.0_dp, 0.5_dp, lsd)
    1276        15000 :                         DO source_atom = 1, SIZE(particle_set)
    1277        10000 :                            NULLIFY (gth_potential, sgp_potential)
    1278              :                            CALL get_qs_kind(my_kind_set(composite_atom_kind(source_atom)), &
    1279              :                                             gth_potential=gth_potential, &
    1280        10000 :                                             sgp_potential=sgp_potential)
    1281              :                            CALL evaluate_nlcc_primitive_fields( &
    1282              :                               composite_grid_coords(:, composite_row), &
    1283              :                               particle_set(source_atom)%r, gth_potential, sgp_potential, &
    1284        10000 :                               nlcc_density, nlcc_gradient, nlcc_hessian)
    1285        10000 :                            nlcc_spatial_derivative = 0.0_dp
    1286        30000 :                            DO ispin = 1, 2
    1287              :                               nlcc_spatial_derivative = nlcc_spatial_derivative + &
    1288              :                                                         nlcc_spin_factor*composite_density_grad(composite_row, ispin)* &
    1289        80000 :                                                         nlcc_gradient
    1290        90000 :                               DO idir = 1, 3
    1291       260000 :                                  DO jdir = 1, 3
    1292              :                                     nlcc_spatial_derivative(jdir) = &
    1293              :                                        nlcc_spatial_derivative(jdir) + nlcc_spin_factor* &
    1294              :                                        composite_grad_grad(composite_row, idir, ispin)* &
    1295       240000 :                                        nlcc_hessian(idir, jdir)
    1296              :                                  END DO
    1297              :                               END DO
    1298              :                            END DO
    1299        40000 :                            spatial_derivative = spatial_derivative + nlcc_spatial_derivative
    1300              :                            composite_nlcc_center_force(:, source_atom) = &
    1301        45000 :                               composite_nlcc_center_force(:, source_atom) - nlcc_spatial_derivative
    1302              :                         END DO
    1303              :                      END IF
    1304              :                      composite_moving_smooth_force(:, iatom) = &
    1305        40000 :                         composite_moving_smooth_force(:, iatom) + spatial_derivative
    1306              :                      CALL skala_gpw_smooth_partition_derivatives( &
    1307              :                         composite_grid_coords(:, composite_row), composite_atom_coords, cell, &
    1308              :                         composite_partition_weights, composite_partition_included, &
    1309        10000 :                         composite_partition_datom, composite_partition_dstrain)
    1310        30000 :                      DO target_atom = 1, SIZE(particle_set)
    1311              :                         composite_partition_force(:, target_atom) = &
    1312              :                            composite_partition_force(:, target_atom) + &
    1313              :                            composite_grid_weight_grad(composite_row)* &
    1314              :                            composite_atomic_grid_weights(composite_row)* &
    1315        90000 :                            composite_partition_datom(:, target_atom, iatom)
    1316              :                      END DO
    1317              :                      composite_partition_force(:, iatom) = composite_partition_force(:, iatom) - &
    1318              :                                                            composite_grid_weight_grad(composite_row)* &
    1319              :                                                            composite_atomic_grid_weights(composite_row)* &
    1320       100004 :                                                            SUM(composite_partition_datom(:, :, iatom), DIM=2)
    1321              :                   END DO
    1322              :                END DO
    1323              :                composite_explicit_force(:, :) = composite_model_atom_force(:, :) + &
    1324              :                                                 composite_grid_coord_force(:, :) + &
    1325              :                                                 composite_moving_smooth_force(:, :) + &
    1326              :                                                 composite_nlcc_center_force(:, :) + &
    1327           36 :                                                 composite_partition_force(:, :)
    1328              :                ! CP2K stores +dE/dR in the electronic force components, but the
    1329              :                ! virial is -dE/dstrain.  A cell deformation moves the atom-grid
    1330              :                ! centers with their atoms while leaving the local radial vectors
    1331              :                ! unchanged, so the explicit atom-composite contribution is
    1332              :                ! -SUM_A dE/dR_A outer R_A.
    1333            4 :                composite_explicit_virial = 0.0_dp
    1334           12 :                DO iatom = 1, SIZE(particle_set)
    1335           36 :                   DO idir = 1, 3
    1336          104 :                      DO jdir = 1, 3
    1337              :                         composite_explicit_virial(idir, jdir) = &
    1338              :                            composite_explicit_virial(idir, jdir) - &
    1339           96 :                            composite_explicit_force(idir, iatom)*particle_set(iatom)%r(jdir)
    1340              :                      END DO
    1341              :                   END DO
    1342              :                END DO
    1343            4 :                IF (ASSOCIATED(force)) THEN
    1344           12 :                   DO iatom = 1, SIZE(particle_set)
    1345            8 :                      ikind = composite_atom_kind(iatom)
    1346            8 :                      iat = composite_atom_kind_index(iatom)
    1347            8 :                      CPASSERT(ikind > 0 .AND. iat > 0)
    1348              :                      force(ikind)%rho_elec(:, iat) = force(ikind)%rho_elec(:, iat) + &
    1349           36 :                                                      composite_explicit_force(:, iatom)
    1350              :                   END DO
    1351              :                END IF
    1352            4 :                IF (use_virial) THEN
    1353            0 :                   virial%pv_xc = 0.0_dp
    1354            0 :                   virial%pv_gapw = virial%pv_gapw + composite_explicit_virial
    1355            0 :                   virial%pv_virial = virial%pv_virial + composite_explicit_virial
    1356              :                END IF
    1357            4 :                IF (native_grid_diagnostics) THEN
    1358            4 :                   CALL para_env%sum(composite_model_atom_force)
    1359            4 :                   CALL para_env%sum(composite_grid_coord_force)
    1360            4 :                   CALL para_env%sum(composite_moving_smooth_force)
    1361            4 :                   CALL para_env%sum(composite_nlcc_center_force)
    1362            4 :                   CALL para_env%sum(composite_partition_force)
    1363            4 :                   CALL para_env%sum(composite_explicit_force)
    1364            4 :                   CALL para_env%sum(composite_explicit_virial)
    1365            4 :                   iw = cp_logger_get_default_io_unit()
    1366            4 :                   IF (iw > 0) THEN
    1367            6 :                      DO iatom = 1, SIZE(particle_set)
    1368              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1369            4 :                            "SKALA_GPW| Atom-composite model-atom force", iatom, &
    1370            8 :                            composite_model_atom_force(:, iatom)
    1371              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1372            4 :                            "SKALA_GPW| Atom-composite grid-coordinate force", iatom, &
    1373            8 :                            composite_grid_coord_force(:, iatom)
    1374              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1375            4 :                            "SKALA_GPW| Atom-composite moving-smooth force", iatom, &
    1376            8 :                            composite_moving_smooth_force(:, iatom)
    1377              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1378            4 :                            "SKALA_GPW| Atom-composite NLCC-center force", iatom, &
    1379            8 :                            composite_nlcc_center_force(:, iatom)
    1380              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1381            4 :                            "SKALA_GPW| Atom-composite partition force", iatom, &
    1382            8 :                            composite_partition_force(:, iatom)
    1383              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1384            4 :                            "SKALA_GPW| Atom-composite explicit force", iatom, &
    1385           10 :                            composite_explicit_force(:, iatom)
    1386              :                      END DO
    1387              :                      WRITE (UNIT=iw, FMT="(T2,A)") &
    1388            2 :                         "SKALA_GPW| Atom-composite explicit virial"
    1389            8 :                      DO idir = 1, 3
    1390              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,3ES20.10)") &
    1391            8 :                            "SKALA_GPW|", composite_explicit_virial(idir, :)
    1392              :                      END DO
    1393              :                   END IF
    1394              :                END IF
    1395            0 :                DEALLOCATE (composite_atom_coord_grad, composite_atomic_grid_weight_grad, &
    1396            0 :                            composite_explicit_force, composite_grid_coord_force, &
    1397            0 :                            composite_grid_coord_grad, composite_grid_weight_grad, &
    1398            0 :                            composite_model_atom_force, composite_moving_smooth_force, &
    1399            0 :                            composite_nlcc_center_force, &
    1400            0 :                            composite_partition_datom, composite_partition_dstrain, &
    1401            4 :                            composite_partition_force, composite_partition_included)
    1402              :             ELSE
    1403              :                CALL skala_gapw_atom_composite_energy( &
    1404              :                   my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
    1405              :                   composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
    1406              :                   composite_local_grid_sizes, composite_local_atom_coords, atom_composite_exc, &
    1407           24 :                   composite_density_grad, composite_grad_grad, composite_kin_grad)
    1408              :             END IF
    1409          112 :             composite_pw_nflat = PRODUCT(smooth_rho_r(1)%pw_grid%npts)
    1410            0 :             ALLOCATE (smooth_density_adjoint(composite_pw_nflat, 2), &
    1411            0 :                       smooth_grad_adjoint(composite_pw_nflat, 3, 2), &
    1412          196 :                       smooth_kin_adjoint(composite_pw_nflat, 2))
    1413           28 :             smooth_density_adjoint = 0.0_dp
    1414           28 :             smooth_grad_adjoint = 0.0_dp
    1415           28 :             smooth_kin_adjoint = 0.0_dp
    1416           28 :             smooth_input_contraction = 0.0_dp
    1417        70028 :             DO composite_row = 1, composite_nflat
    1418       210028 :                DO ispin = 1, 2
    1419              :                   CALL add_native_grid_interpolation_adjoint( &
    1420              :                      smooth_density_adjoint(:, ispin), smooth_rho_r(1)%pw_grid, cell, &
    1421              :                      composite_grid_coords(:, composite_row), &
    1422       140000 :                      composite_density_grad(composite_row, ispin))
    1423              :                   CALL add_native_grid_interpolation_adjoint( &
    1424              :                      smooth_kin_adjoint(:, ispin), smooth_rho_r(1)%pw_grid, cell, &
    1425              :                      composite_grid_coords(:, composite_row), &
    1426       140000 :                      composite_kin_grad(composite_row, ispin))
    1427       560000 :                   DO idir = 1, 3
    1428              :                      CALL add_native_grid_interpolation_adjoint( &
    1429              :                         smooth_grad_adjoint(:, idir, ispin), smooth_rho_r(1)%pw_grid, cell, &
    1430              :                         composite_grid_coords(:, composite_row), &
    1431       560000 :                         composite_grad_grad(composite_row, idir, ispin))
    1432              :                   END DO
    1433       210000 :                   IF (lsd) THEN
    1434            0 :                      IF (ispin == 1) THEN
    1435              :                         smooth_input_contraction = smooth_input_contraction + &
    1436              :                                                    composite_density_grad(composite_row, ispin)* &
    1437              :                                                    interpolate_native_grid(composite_smooth_rhoa, &
    1438              :                                                                            smooth_rho_r(1)%pw_grid, cell, &
    1439              :                                                                            composite_grid_coords(:, composite_row)) + &
    1440              :                                                    composite_kin_grad(composite_row, ispin)* &
    1441              :                                                    interpolate_native_grid(composite_smooth_tau_a, &
    1442              :                                                                            smooth_rho_r(1)%pw_grid, cell, &
    1443            0 :                                                                            composite_grid_coords(:, composite_row))
    1444            0 :                         DO idir = 1, 3
    1445              :                            smooth_input_contraction = smooth_input_contraction + &
    1446              :                                                       composite_grad_grad(composite_row, idir, ispin)* &
    1447              :                                                       interpolate_native_grid(composite_smooth_drhoa(idir)%array, &
    1448              :                                                                               smooth_rho_r(1)%pw_grid, cell, &
    1449            0 :                                                                               composite_grid_coords(:, composite_row))
    1450              :                         END DO
    1451              :                      ELSE
    1452              :                         smooth_input_contraction = smooth_input_contraction + &
    1453              :                                                    composite_density_grad(composite_row, ispin)* &
    1454              :                                                    interpolate_native_grid(composite_smooth_rhob, &
    1455              :                                                                            smooth_rho_r(1)%pw_grid, cell, &
    1456              :                                                                            composite_grid_coords(:, composite_row)) + &
    1457              :                                                    composite_kin_grad(composite_row, ispin)* &
    1458              :                                                    interpolate_native_grid(composite_smooth_tau_b, &
    1459              :                                                                            smooth_rho_r(1)%pw_grid, cell, &
    1460            0 :                                                                            composite_grid_coords(:, composite_row))
    1461            0 :                         DO idir = 1, 3
    1462              :                            smooth_input_contraction = smooth_input_contraction + &
    1463              :                                                       composite_grad_grad(composite_row, idir, ispin)* &
    1464              :                                                       interpolate_native_grid(composite_smooth_drhob(idir)%array, &
    1465              :                                                                               smooth_rho_r(1)%pw_grid, cell, &
    1466            0 :                                                                               composite_grid_coords(:, composite_row))
    1467              :                         END DO
    1468              :                      END IF
    1469              :                   ELSE
    1470              :                      smooth_input_contraction = smooth_input_contraction + 0.5_dp*( &
    1471              :                                                 composite_density_grad(composite_row, ispin)* &
    1472              :                                                 interpolate_native_grid( &
    1473              :                                                 composite_smooth_rho, smooth_rho_r(1)%pw_grid, cell, &
    1474              :                                                 composite_grid_coords(:, composite_row)) + &
    1475              :                                                 composite_kin_grad(composite_row, ispin)* &
    1476              :                                                 interpolate_native_grid( &
    1477              :                                                 composite_smooth_tau, smooth_rho_r(1)%pw_grid, cell, &
    1478       140000 :                                                 composite_grid_coords(:, composite_row)))
    1479       560000 :                      DO idir = 1, 3
    1480              :                         smooth_input_contraction = smooth_input_contraction + 0.5_dp* &
    1481              :                                                    composite_grad_grad(composite_row, idir, ispin)* &
    1482              :                                                    interpolate_native_grid( &
    1483              :                                                    composite_smooth_drho(idir)%array, &
    1484              :                                                    smooth_rho_r(1)%pw_grid, cell, &
    1485       560000 :                                                    composite_grid_coords(:, composite_row))
    1486              :                      END DO
    1487              :                   END IF
    1488              :                END DO
    1489              :             END DO
    1490              :             ! The interpolation transpose still uses CP2K's global FFT-grid layout. Reduce only
    1491              :             ! this PW adjoint; atom-grid feature rows and their model derivatives stay rank-local.
    1492           28 :             CALL para_env%sum(smooth_density_adjoint)
    1493           28 :             CALL para_env%sum(smooth_grad_adjoint)
    1494           28 :             CALL para_env%sum(smooth_kin_adjoint)
    1495           28 :             CALL para_env%sum(smooth_input_contraction)
    1496              :             CALL build_vxc_from_feature_grads( &
    1497              :                smooth_vxc_rho, smooth_vxc_tau, smooth_rho_r, auxbas_pw_pool, &
    1498              :                smooth_density_adjoint, smooth_grad_adjoint, smooth_kin_adjoint, &
    1499           28 :                xc_deriv_method_id, global_grid_layout=.TRUE.)
    1500           28 :             smooth_grid_contraction = 0.0_dp
    1501           56 :             DO ispin = 1, nspins
    1502              :                smooth_grid_contraction = smooth_grid_contraction + smooth_rho_r(1)%pw_grid%dvol* &
    1503              :                                          (SUM(smooth_vxc_rho(ispin)%array* &
    1504              :                                               smooth_rho_r(ispin)%array) + &
    1505              :                                           SUM(smooth_vxc_tau(ispin)%array* &
    1506      1268488 :                                               smooth_tau_r(ispin)%array))
    1507           28 :                IF (atom_composite_reference) THEN
    1508           28 :                   CPASSERT(PRESENT(composite_vxc_rho))
    1509           28 :                   CPASSERT(PRESENT(composite_vxc_tau))
    1510           28 :                   CPASSERT(ASSOCIATED(composite_vxc_rho))
    1511           28 :                   CPASSERT(ASSOCIATED(composite_vxc_tau))
    1512           28 :                   CPASSERT(SIZE(composite_vxc_rho) == nspins)
    1513           28 :                   CPASSERT(SIZE(composite_vxc_tau) == nspins)
    1514           28 :                   CALL pw_axpy(smooth_vxc_rho(ispin), composite_vxc_rho(ispin), 1.0_dp)
    1515           28 :                   CALL pw_axpy(smooth_vxc_tau(ispin), composite_vxc_tau(ispin), 1.0_dp)
    1516              :                END IF
    1517           28 :                CALL auxbas_pw_pool%give_back_pw(smooth_vxc_rho(ispin))
    1518           56 :                CALL auxbas_pw_pool%give_back_pw(smooth_vxc_tau(ispin))
    1519              :             END DO
    1520           28 :             CALL para_env%sum(smooth_grid_contraction)
    1521           28 :             DEALLOCATE (smooth_vxc_rho, smooth_vxc_tau)
    1522              : 
    1523           28 :             one_center_field_contraction = 0.0_dp
    1524           28 :             one_center_matrix_contraction = 0.0_dp
    1525           28 :             one_center_density_field_contraction = 0.0_dp
    1526           28 :             one_center_density_matrix_contraction = 0.0_dp
    1527           28 :             one_center_gradient_field_contraction = 0.0_dp
    1528           28 :             one_center_gradient_matrix_contraction = 0.0_dp
    1529           28 :             one_center_rho_grad_field_contraction = 0.0_dp
    1530           28 :             one_center_rho_grad_matrix_contraction = 0.0_dp
    1531           28 :             one_center_tau_field_contraction = 0.0_dp
    1532           28 :             one_center_tau_matrix_contraction = 0.0_dp
    1533           60 :             DO ikind = 1, SIZE(atomic_kind_set)
    1534           32 :                CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    1535           32 :                NULLIFY (gth_potential, sgp_potential)
    1536              :                CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
    1537              :                                 gth_potential=gth_potential, harmonics=harmonics, &
    1538              :                                 grid_atom=grid_atom, sgp_potential=sgp_potential, &
    1539           32 :                                 zatom=zatom, zeff=zeff)
    1540           32 :                CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    1541           32 :                IF (.NOT. paw_atom) CYCLE
    1542              :                IF (.NOT. force_paw_representation .AND. &
    1543           32 :                    (ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential)) .AND. &
    1544              :                    ABS(zeff - REAL(zatom, dp)) <= 1.0E-10_dp) CYCLE
    1545              : 
    1546           32 :                nr = grid_atom%nr
    1547           32 :                na = grid_atom%ng_sphere
    1548           32 :                CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
    1549           32 :                CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
    1550           32 :                CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
    1551           32 :                CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
    1552           32 :                CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
    1553           32 :                CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
    1554           32 :                CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
    1555           32 :                CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
    1556           32 :                CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
    1557           32 :                CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
    1558           32 :                CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
    1559           32 :                CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
    1560           32 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    1561              : 
    1562           32 :                bo = get_limit(natom, para_env%num_pe, para_env%mepos)
    1563           60 :                DO iat = bo(1), bo(2)
    1564           28 :                   iatom = atom_list(iat)
    1565           28 :                   rho_atom => my_rho_atom_set(iatom)
    1566           28 :                   NULLIFY (cpc_h, cpc_s, r_h, r_s, dr_h, dr_s, r_h_d, r_s_d, int_hh, int_ss)
    1567              :                   CALL get_rho_atom(rho_atom=rho_atom, cpc_h=cpc_h, cpc_s=cpc_s, &
    1568              :                                     rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    1569              :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d, &
    1570           28 :                                     ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    1571        71456 :                   rho_h = 0.0_dp
    1572        71456 :                   rho_s = 0.0_dp
    1573       351456 :                   drho_h = 0.0_dp
    1574       351456 :                   drho_s = 0.0_dp
    1575           28 :                   CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
    1576         1428 :                   DO ir = 1, nr
    1577              :                      CALL calc_rho_angular(grid_atom, harmonics, nspins, .TRUE., &
    1578              :                                            ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
    1579         1428 :                                            r_h_d, r_s_d, drho_h, drho_s)
    1580              :                   END DO
    1581              : 
    1582        71456 :                   vxc_h = 0.0_dp
    1583        71456 :                   vxc_s = 0.0_dp
    1584       281456 :                   vxg_h = 0.0_dp
    1585       281456 :                   vxg_s = 0.0_dp
    1586        71456 :                   vtau_h = 0.0_dp
    1587        71456 :                   vtau_s = 0.0_dp
    1588           28 :                   composite_row = composite_atom_start(iatom) - 1
    1589         1428 :                   DO ir = 1, nr
    1590        71428 :                      DO ia = 1, na
    1591        70000 :                         composite_row = composite_row + 1
    1592        71400 :                         IF (lsd) THEN
    1593            0 :                            IF (atom_composite_components <= 2) THEN
    1594            0 :                               vxc_h(ia, ir, 1:2) = composite_density_grad(composite_row, 1:2)
    1595            0 :                               vxc_s(ia, ir, 1:2) = composite_density_grad(composite_row, 1:2)
    1596            0 :                               DO idir = 1, 3
    1597              :                                  vxg_h(idir, ia, ir, 1:2) = &
    1598            0 :                                     composite_grad_grad(composite_row, idir, 1:2)
    1599              :                                  vxg_s(idir, ia, ir, 1:2) = &
    1600            0 :                                     composite_grad_grad(composite_row, idir, 1:2)
    1601              :                               END DO
    1602              :                            END IF
    1603            0 :                            IF (atom_composite_components == 1 .OR. &
    1604              :                                atom_composite_components == 3) THEN
    1605            0 :                               vtau_h(ia, ir, 1:2) = composite_kin_grad(composite_row, 1:2)
    1606            0 :                               vtau_s(ia, ir, 1:2) = composite_kin_grad(composite_row, 1:2)
    1607              :                            END IF
    1608              :                         ELSE
    1609        70000 :                            IF (atom_composite_components <= 2) THEN
    1610              :                               vxc_h(ia, ir, 1) = 0.5_dp* &
    1611       210000 :                                                  SUM(composite_density_grad(composite_row, :))
    1612        70000 :                               vxc_s(ia, ir, 1) = vxc_h(ia, ir, 1)
    1613       280000 :                               DO idir = 1, 3
    1614              :                                  vxg_h(idir, ia, ir, 1) = 0.5_dp* &
    1615              :                                                           SUM(composite_grad_grad( &
    1616       630000 :                                                               composite_row, idir, :))
    1617       280000 :                                  vxg_s(idir, ia, ir, 1) = vxg_h(idir, ia, ir, 1)
    1618              :                               END DO
    1619              :                            END IF
    1620        70000 :                            IF (atom_composite_components == 1 .OR. &
    1621              :                                atom_composite_components == 3) THEN
    1622              :                               vtau_h(ia, ir, 1) = 0.5_dp* &
    1623       210000 :                                                   SUM(composite_kin_grad(composite_row, :))
    1624        70000 :                               vtau_s(ia, ir, 1) = vtau_h(ia, ir, 1)
    1625              :                            END IF
    1626              :                         END IF
    1627              :                      END DO
    1628              :                   END DO
    1629           28 :                   CPASSERT(composite_row == composite_atom_end(iatom))
    1630              : 
    1631              :                   one_center_rho_grad_field_contraction = &
    1632              :                      one_center_rho_grad_field_contraction + SUM(vxc_h*(rho_h - rho_s)) + &
    1633       352884 :                      SUM(vxg_h*(drho_h(1:3, :, :, :) - drho_s(1:3, :, :, :)))
    1634              :                   one_center_density_field_contraction = one_center_density_field_contraction + &
    1635        71456 :                                                          SUM(vxc_h*(rho_h - rho_s))
    1636              :                   one_center_gradient_field_contraction = one_center_gradient_field_contraction + &
    1637              :                                                           SUM(vxg_h*(drho_h(1:3, :, :, :) - &
    1638       281456 :                                                                      drho_s(1:3, :, :, :)))
    1639              :                   one_center_tau_field_contraction = one_center_tau_field_contraction + &
    1640        71456 :                                                      SUM(vtau_h*(tau_h - tau_s))
    1641              : 
    1642            0 :                   ALLOCATE (composite_int_h(SIZE(int_hh(1)%r_coef, 1), &
    1643              :                                             SIZE(int_hh(1)%r_coef, 2), nspins), &
    1644            0 :                             composite_int_s(SIZE(int_ss(1)%r_coef, 1), &
    1645          252 :                                             SIZE(int_ss(1)%r_coef, 2), nspins))
    1646           56 :                   DO ispin = 1, nspins
    1647         9296 :                      composite_int_h(:, :, ispin) = int_hh(ispin)%r_coef
    1648         9296 :                      composite_int_s(:, :, ispin) = int_ss(ispin)%r_coef
    1649         9296 :                      int_hh(ispin)%r_coef = 0.0_dp
    1650         9324 :                      int_ss(ispin)%r_coef = 0.0_dp
    1651              :                   END DO
    1652              :                   CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
    1653           28 :                                     grid_atom, basis_1c, harmonics, nspins)
    1654           56 :                   DO ispin = 1, nspins
    1655              :                      one_center_density_matrix_contraction = &
    1656              :                         one_center_density_matrix_contraction + &
    1657              :                         contract_one_center_matrix(cpc_h(ispin)%r_coef, &
    1658              :                                                    int_hh(ispin)%r_coef, &
    1659              :                                                    tau_basis_cache%n2oindex) - &
    1660              :                         contract_one_center_matrix(cpc_s(ispin)%r_coef, &
    1661              :                                                    int_ss(ispin)%r_coef, &
    1662           28 :                                                    tau_basis_cache%n2oindex)
    1663         9296 :                      int_hh(ispin)%r_coef = 0.0_dp
    1664         9324 :                      int_ss(ispin)%r_coef = 0.0_dp
    1665              :                   END DO
    1666              :                   CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    1667           28 :                                   grid_atom, basis_1c, harmonics, nspins)
    1668           56 :                   DO ispin = 1, nspins
    1669              :                      one_center_rho_grad_matrix_contraction = &
    1670              :                         one_center_rho_grad_matrix_contraction + &
    1671              :                         contract_one_center_matrix(cpc_h(ispin)%r_coef, &
    1672              :                                                    int_hh(ispin)%r_coef, &
    1673              :                                                    tau_basis_cache%n2oindex) - &
    1674              :                         contract_one_center_matrix(cpc_s(ispin)%r_coef, &
    1675              :                                                    int_ss(ispin)%r_coef, &
    1676           56 :                                                    tau_basis_cache%n2oindex)
    1677              :                   END DO
    1678           28 :                   CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, tau_basis_cache, nspins)
    1679           56 :                   DO ispin = 1, nspins
    1680              :                      one_center_matrix_contraction = one_center_matrix_contraction + &
    1681              :                                                      contract_one_center_matrix(cpc_h(ispin)%r_coef, &
    1682              :                                                                                 int_hh(ispin)%r_coef, &
    1683              :                                                                                 tau_basis_cache%n2oindex) - &
    1684              :                                                      contract_one_center_matrix(cpc_s(ispin)%r_coef, &
    1685              :                                                                                 int_ss(ispin)%r_coef, &
    1686           28 :                                                                                 tau_basis_cache%n2oindex)
    1687           56 :                      IF (.NOT. atom_composite_reference) THEN
    1688            0 :                         int_hh(ispin)%r_coef = composite_int_h(:, :, ispin)
    1689            0 :                         int_ss(ispin)%r_coef = composite_int_s(:, :, ispin)
    1690              :                      END IF
    1691              :                   END DO
    1692           60 :                   DEALLOCATE (composite_int_h, composite_int_s)
    1693              :                END DO
    1694           92 :                CALL release_tau_basis_cache(tau_basis_cache)
    1695              :             END DO
    1696           28 :             CALL para_env%sum(one_center_density_field_contraction)
    1697           28 :             CALL para_env%sum(one_center_density_matrix_contraction)
    1698           28 :             CALL para_env%sum(one_center_gradient_field_contraction)
    1699           28 :             CALL para_env%sum(one_center_matrix_contraction)
    1700           28 :             CALL para_env%sum(one_center_rho_grad_field_contraction)
    1701           28 :             CALL para_env%sum(one_center_rho_grad_matrix_contraction)
    1702           28 :             CALL para_env%sum(one_center_tau_field_contraction)
    1703              :             one_center_field_contraction = one_center_rho_grad_field_contraction + &
    1704           28 :                                            one_center_tau_field_contraction
    1705              :             one_center_gradient_matrix_contraction = one_center_rho_grad_matrix_contraction - &
    1706           28 :                                                      one_center_density_matrix_contraction
    1707              :             one_center_tau_matrix_contraction = one_center_matrix_contraction - &
    1708           28 :                                                 one_center_rho_grad_matrix_contraction
    1709       140084 :             feature_component_analytic(1) = SUM(composite_density_grad*composite_density)
    1710       420252 :             feature_component_analytic(2) = SUM(composite_grad_grad*composite_grad)
    1711       140084 :             feature_component_analytic(3) = SUM(composite_kin_grad*composite_kin)
    1712          112 :             feature_component_analytic(4) = SUM(feature_component_analytic(1:3))
    1713           28 :             CALL para_env%sum(feature_component_analytic)
    1714              :             one_center_tensor_contraction = feature_component_analytic(4) - &
    1715           28 :                                             smooth_input_contraction
    1716           28 :             IF (atom_composite_diagnostic) THEN
    1717            0 :                DO icomponent = 1, 4
    1718            0 :                   SELECT CASE (icomponent)
    1719              :                   CASE (1)
    1720            0 :                      composite_density = (1.0_dp + feature_vxc_step)*composite_density
    1721              :                   CASE (2)
    1722            0 :                      composite_grad = (1.0_dp + feature_vxc_step)*composite_grad
    1723              :                   CASE (3)
    1724            0 :                      composite_kin = (1.0_dp + feature_vxc_step)*composite_kin
    1725              :                   CASE (4)
    1726            0 :                      composite_density = (1.0_dp + feature_vxc_step)*composite_density
    1727            0 :                      composite_grad = (1.0_dp + feature_vxc_step)*composite_grad
    1728            0 :                      composite_kin = (1.0_dp + feature_vxc_step)*composite_kin
    1729              :                   END SELECT
    1730              :                   CALL skala_gapw_atom_composite_energy( &
    1731              :                      my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
    1732              :                      composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
    1733            0 :                      composite_local_grid_sizes, composite_local_atom_coords, feature_vxc_plus)
    1734            0 :                   SELECT CASE (icomponent)
    1735              :                   CASE (1)
    1736              :                      composite_density = ((1.0_dp - feature_vxc_step)/ &
    1737            0 :                                           (1.0_dp + feature_vxc_step))*composite_density
    1738              :                   CASE (2)
    1739              :                      composite_grad = ((1.0_dp - feature_vxc_step)/ &
    1740            0 :                                        (1.0_dp + feature_vxc_step))*composite_grad
    1741              :                   CASE (3)
    1742              :                      composite_kin = ((1.0_dp - feature_vxc_step)/ &
    1743            0 :                                       (1.0_dp + feature_vxc_step))*composite_kin
    1744              :                   CASE (4)
    1745              :                      composite_density = ((1.0_dp - feature_vxc_step)/ &
    1746            0 :                                           (1.0_dp + feature_vxc_step))*composite_density
    1747              :                      composite_grad = ((1.0_dp - feature_vxc_step)/ &
    1748            0 :                                        (1.0_dp + feature_vxc_step))*composite_grad
    1749              :                      composite_kin = ((1.0_dp - feature_vxc_step)/ &
    1750            0 :                                       (1.0_dp + feature_vxc_step))*composite_kin
    1751              :                   END SELECT
    1752              :                   CALL skala_gapw_atom_composite_energy( &
    1753              :                      my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
    1754              :                      composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
    1755            0 :                      composite_local_grid_sizes, composite_local_atom_coords, feature_vxc_minus)
    1756            0 :                   SELECT CASE (icomponent)
    1757              :                   CASE (1)
    1758            0 :                      composite_density = composite_density/(1.0_dp - feature_vxc_step)
    1759              :                   CASE (2)
    1760            0 :                      composite_grad = composite_grad/(1.0_dp - feature_vxc_step)
    1761              :                   CASE (3)
    1762            0 :                      composite_kin = composite_kin/(1.0_dp - feature_vxc_step)
    1763              :                   CASE (4)
    1764            0 :                      composite_density = composite_density/(1.0_dp - feature_vxc_step)
    1765            0 :                      composite_grad = composite_grad/(1.0_dp - feature_vxc_step)
    1766            0 :                      composite_kin = composite_kin/(1.0_dp - feature_vxc_step)
    1767              :                   END SELECT
    1768              :                   feature_component_fd(icomponent) = &
    1769            0 :                      (feature_vxc_plus - feature_vxc_minus)/(2.0_dp*feature_vxc_step)
    1770              :                END DO
    1771            0 :                feature_vxc_analytic = feature_component_analytic(4)
    1772            0 :                feature_vxc_fd = feature_component_fd(4)
    1773            0 :                iw = cp_logger_get_default_io_unit()
    1774            0 :                IF (iw > 0) THEN
    1775              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,I0)") &
    1776            0 :                      "SKALA_GPW| Atom-composite reference components", atom_composite_components
    1777              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    1778            0 :                      "SKALA_GPW| Atom-composite reference electrons", atom_composite_nelec
    1779              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    1780            0 :                      "SKALA_GPW| Atom-composite reference XC energy", atom_composite_exc
    1781              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    1782            0 :                      "SKALA_GPW| Atom-composite feature VXC contraction", feature_vxc_analytic
    1783              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    1784            0 :                      "SKALA_GPW| Atom-composite feature finite difference", feature_vxc_fd
    1785              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    1786            0 :                      "SKALA_GPW| Atom-composite feature VXC error", &
    1787            0 :                      feature_vxc_analytic - feature_vxc_fd
    1788              :                   WRITE (UNIT=iw, FMT="(T2,A,3(1X,ES24.16))") &
    1789            0 :                      "SKALA_GPW| Atom-composite smooth PW adjoint", smooth_input_contraction, &
    1790            0 :                      smooth_grid_contraction, smooth_grid_contraction - smooth_input_contraction
    1791              :                   WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES24.16))") &
    1792            0 :                      "SKALA_GPW| Atom-composite one-center adjoint", one_center_tensor_contraction, &
    1793            0 :                      one_center_field_contraction, one_center_matrix_contraction, &
    1794            0 :                      one_center_matrix_contraction - one_center_tensor_contraction
    1795              :                   WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES24.16))") &
    1796            0 :                      "SKALA_GPW| Atom-composite one-center channels", &
    1797            0 :                      one_center_rho_grad_field_contraction, one_center_rho_grad_matrix_contraction, &
    1798            0 :                      one_center_tau_field_contraction, one_center_tau_matrix_contraction
    1799              :                   WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES24.16))") &
    1800            0 :                      "SKALA_GPW| Atom-composite one-center rho-gradient", &
    1801            0 :                      one_center_density_field_contraction, one_center_density_matrix_contraction, &
    1802            0 :                      one_center_gradient_field_contraction, one_center_gradient_matrix_contraction
    1803            0 :                   DO icomponent = 1, 3
    1804              :                      WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES24.16))") &
    1805            0 :                         "SKALA_GPW| Atom-composite component VXC", icomponent, &
    1806            0 :                         feature_component_analytic(icomponent), feature_component_fd(icomponent), &
    1807            0 :                         feature_component_analytic(icomponent) - feature_component_fd(icomponent)
    1808              :                   END DO
    1809              :                END IF
    1810              :             END IF
    1811           28 :             IF (atom_composite_reference) THEN
    1812           28 :                exc1 = atom_composite_exc
    1813           28 :                IF (native_grid_diagnostics) THEN
    1814           28 :                   IF (composite_nflat > 0) THEN
    1815       140078 :                      composite_density_min = MINVAL(composite_density)
    1816       140078 :                      composite_density_max = MAXVAL(composite_density)
    1817       140078 :                      composite_kin_min = MINVAL(composite_kin)
    1818       140078 :                      composite_kin_max = MAXVAL(composite_kin)
    1819       420234 :                      composite_grad_max = MAXVAL(ABS(composite_grad))
    1820              :                   ELSE
    1821            2 :                      composite_density_min = HUGE(1.0_dp)
    1822            2 :                      composite_density_max = -HUGE(1.0_dp)
    1823            2 :                      composite_kin_min = HUGE(1.0_dp)
    1824            2 :                      composite_kin_max = -HUGE(1.0_dp)
    1825            2 :                      composite_grad_max = 0.0_dp
    1826              :                   END IF
    1827              :                   composite_tau_integral = &
    1828       210028 :                      SUM(composite_grid_weights*SUM(composite_kin, DIM=2))
    1829           28 :                   CALL para_env%min(composite_density_min)
    1830           28 :                   CALL para_env%max(composite_density_max)
    1831           28 :                   CALL para_env%min(composite_kin_min)
    1832           28 :                   CALL para_env%max(composite_kin_max)
    1833           28 :                   CALL para_env%max(composite_grad_max)
    1834           28 :                   CALL para_env%sum(composite_tau_integral)
    1835              :                END IF
    1836           28 :                iw = cp_logger_get_default_io_unit()
    1837           28 :                IF (iw > 0) THEN
    1838              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    1839           14 :                      "SKALA_GPW| Active atom-composite XC energy", atom_composite_exc
    1840           14 :                   IF (native_grid_diagnostics) THEN
    1841              :                      WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    1842           14 :                         "SKALA_GPW| Active atom-composite electrons", atom_composite_nelec
    1843              :                      WRITE (UNIT=iw, FMT="(T2,A,2(1X,ES24.16))") &
    1844           14 :                         "SKALA_GPW| Active atom-composite density range", &
    1845           28 :                         composite_density_min, composite_density_max
    1846              :                      WRITE (UNIT=iw, FMT="(T2,A,2(1X,ES24.16))") &
    1847           14 :                         "SKALA_GPW| Active atom-composite tau range", &
    1848           28 :                         composite_kin_min, composite_kin_max
    1849              :                      WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    1850           14 :                         "SKALA_GPW| Active atom-composite tau integral", &
    1851           28 :                         composite_tau_integral
    1852              :                      WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    1853           14 :                         "SKALA_GPW| Active atom-composite max gradient", &
    1854           28 :                         composite_grad_max
    1855              :                   END IF
    1856              :                END IF
    1857              :             END IF
    1858           28 :             CALL xc_rho_set_release(smooth_rho_set, pw_pool=auxbas_pw_pool)
    1859            0 :             DEALLOCATE (composite_atomic_grid_sizes, composite_atom_kind, &
    1860            0 :                         composite_atom_kind_index, composite_atom_start, composite_atom_end, &
    1861            0 :                         composite_atom_coords, composite_local_atoms, composite_local_grid_sizes, &
    1862            0 :                         composite_local_atom_coords, &
    1863            0 :                         composite_partition_weights, composite_partition_atom_coords, &
    1864            0 :                         composite_distances, composite_density, composite_grad, composite_kin, &
    1865            0 :                         composite_density_grad, composite_grad_grad, composite_kin_grad, &
    1866            0 :                         smooth_density_adjoint, smooth_grad_adjoint, smooth_kin_adjoint, &
    1867            0 :                         composite_grid_coords, composite_grid_weights, &
    1868           28 :                         composite_atomic_grid_weights)
    1869           28 :             IF (lsd) THEN
    1870            0 :                DEALLOCATE (composite_smooth_rhoa, composite_smooth_rhob, &
    1871            0 :                            composite_smooth_tau_a, composite_smooth_tau_b)
    1872            0 :                DO idir = 1, 3
    1873            0 :                   DEALLOCATE (composite_smooth_drhoa(idir)%array, &
    1874            0 :                               composite_smooth_drhob(idir)%array)
    1875              :                END DO
    1876              :             ELSE
    1877           28 :                DEALLOCATE (composite_smooth_rho, composite_smooth_tau)
    1878          112 :                DO idir = 1, 3
    1879          112 :                   DEALLOCATE (composite_smooth_drho(idir)%array)
    1880              :                END DO
    1881              :             END IF
    1882              :          END IF
    1883              : 
    1884        27870 :          IF (.NOT. atom_composite_reference) CALL para_env%sum(exc1)
    1885              : 
    1886        27870 :          IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
    1887        27870 :          IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
    1888        27870 :          IF (ASSOCIATED(vxc_h)) DEALLOCATE (vxc_h)
    1889        27870 :          IF (ASSOCIATED(vxc_s)) DEALLOCATE (vxc_s)
    1890              : 
    1891        27870 :          IF (gradient_f) THEN
    1892        19134 :             IF (ASSOCIATED(drho_h)) DEALLOCATE (drho_h)
    1893        19134 :             IF (ASSOCIATED(drho_s)) DEALLOCATE (drho_s)
    1894        19134 :             IF (ASSOCIATED(vxg_h)) DEALLOCATE (vxg_h)
    1895        19134 :             IF (ASSOCIATED(vxg_s)) DEALLOCATE (vxg_s)
    1896              :          END IF
    1897              : 
    1898        27870 :          IF (tau_f) THEN
    1899          752 :             IF (ASSOCIATED(tau_h)) DEALLOCATE (tau_h)
    1900          752 :             IF (ASSOCIATED(tau_s)) DEALLOCATE (tau_s)
    1901          752 :             IF (ASSOCIATED(vtau_h)) DEALLOCATE (vtau_h)
    1902          752 :             IF (ASSOCIATED(vtau_s)) DEALLOCATE (vtau_s)
    1903              :          END IF
    1904              : 
    1905              :       END IF !xc_none
    1906              : 
    1907        32056 :       CALL timestop(handle)
    1908              : 
    1909      1859248 :    END SUBROUTINE calculate_vxc_atom
    1910              : 
    1911              : ! **************************************************************************************************
    1912              : !> \brief Add the GAPW one-center correction to CDFT values and operators.
    1913              : !> \param qs_env Quickstep environment
    1914              : !> \param energy_only skip construction of the CDFT one-center operator
    1915              : !> \param calculate_forces evaluate explicit derivatives of the partition weights
    1916              : !> \param values constraint values from the hard-minus-soft one-center densities
    1917              : !> \param electronic_charge optional one-center corrections to atomic populations
    1918              : !> \param operator_group optional group for which to build the unscaled weight operator
    1919              : !> \param rho_atom_operator_set optional destination for the one-center operator integrals
    1920              : ! **************************************************************************************************
    1921          424 :    SUBROUTINE gapw_cdft_one_center(qs_env, energy_only, calculate_forces, values, &
    1922          424 :                                    electronic_charge, operator_group, rho_atom_operator_set)
    1923              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1924              :       LOGICAL, INTENT(IN)                                :: energy_only, calculate_forces
    1925              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: values
    1926              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT), &
    1927              :          OPTIONAL                                        :: electronic_charge
    1928              :       INTEGER, INTENT(IN), OPTIONAL                      :: operator_group
    1929              :       TYPE(rho_atom_type), DIMENSION(:), POINTER, &
    1930              :          OPTIONAL                                        :: rho_atom_operator_set
    1931              : 
    1932              :       INTEGER                                            :: atom, channel, ia, iat, igroup, ikind, &
    1933              :                                                             ir, natom, natom_kind, nspins
    1934              :       INTEGER, DIMENSION(2)                              :: atom_bounds
    1935          424 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
    1936              :       LOGICAL                                            :: lsd, paw_atom
    1937              :       REAL(KIND=dp)                                      :: delta_density, point_factor, spin_factor
    1938          424 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: atomic_weights, group_weights
    1939          424 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: explicit_derivative, &
    1940          424 :                                                             group_point_derivative
    1941          424 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: group_atom_derivative
    1942              :       REAL(KIND=dp), DIMENSION(3)                        :: point
    1943          424 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: rho_h, rho_s
    1944          424 :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: drho_h, drho_s
    1945          424 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: vlocal_h, vlocal_s
    1946          424 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1947              :       TYPE(cdft_control_type), POINTER                   :: cdft_control
    1948          424 :       TYPE(cdft_point_context_type)                      :: context
    1949              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1950              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    1951              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    1952              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    1953              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1954          424 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1955          424 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    1956          424 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1957          424 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
    1958          424 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    1959          424 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: operator_atom_set, rho_atom_set
    1960              :       TYPE(rho_atom_type), POINTER                       :: operator_atom, rho_atom
    1961              : 
    1962          424 :       NULLIFY (atom_list, atomic_kind_set, basis_1c, cdft_control, dft_control, force, &
    1963          424 :                grid_atom, harmonics, int_hh, int_ss, para_env, particle_set, r_h, r_s, &
    1964          424 :                dr_h, dr_s, r_h_d, r_s_d, rho_h, rho_s, drho_h, drho_s, &
    1965          424 :                operator_atom, operator_atom_set, rho_atom, rho_atom_set, qs_kind_set, &
    1966          424 :                vlocal_h, vlocal_s)
    1967              :       CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, dft_control=dft_control, &
    1968              :                       force=force, natom=natom, para_env=para_env, particle_set=particle_set, &
    1969          424 :                       qs_kind_set=qs_kind_set, rho_atom_set=rho_atom_set)
    1970          424 :       CPASSERT(ASSOCIATED(atomic_kind_set))
    1971          424 :       CPASSERT(ASSOCIATED(dft_control))
    1972          424 :       CPASSERT(ASSOCIATED(para_env))
    1973          424 :       CPASSERT(ASSOCIATED(particle_set))
    1974          424 :       CPASSERT(ASSOCIATED(qs_kind_set))
    1975          424 :       CPASSERT(ASSOCIATED(rho_atom_set))
    1976          424 :       operator_atom_set => rho_atom_set
    1977          424 :       IF (PRESENT(rho_atom_operator_set)) operator_atom_set => rho_atom_operator_set
    1978          424 :       CPASSERT(ASSOCIATED(operator_atom_set))
    1979          424 :       cdft_control => dft_control%qs_control%cdft_control
    1980          424 :       CPASSERT(ASSOCIATED(cdft_control))
    1981          424 :       nspins = dft_control%nspins
    1982          424 :       lsd = dft_control%lsd
    1983          424 :       CPASSERT(SIZE(values) == SIZE(cdft_control%group))
    1984          424 :       IF (PRESENT(operator_group)) THEN
    1985            4 :          CPASSERT(operator_group >= 1 .AND. operator_group <= SIZE(cdft_control%group))
    1986              :       END IF
    1987          424 :       IF (PRESENT(electronic_charge)) THEN
    1988           76 :          CPASSERT(SIZE(electronic_charge, 1) == natom)
    1989           76 :          CPASSERT(SIZE(electronic_charge, 2) == nspins)
    1990              :       END IF
    1991              : 
    1992          424 :       CALL cdft_point_context_create(qs_env, context, calculate_forces)
    1993              :       ALLOCATE (group_weights(context%ngroup), group_point_derivative(3, context%ngroup), &
    1994              :                 group_atom_derivative(3, natom, context%ngroup), &
    1995         4240 :                 explicit_derivative(3, natom))
    1996          576 :       IF (PRESENT(electronic_charge)) ALLOCATE (atomic_weights(natom))
    1997          920 :       values = 0.0_dp
    1998          424 :       explicit_derivative = 0.0_dp
    1999          972 :       IF (PRESENT(electronic_charge)) electronic_charge = 0.0_dp
    2000              : 
    2001          988 :       DO ikind = 1, SIZE(atomic_kind_set)
    2002          564 :          CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom_kind)
    2003              :          CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom, grid_atom=grid_atom, &
    2004          564 :                           harmonics=harmonics)
    2005          564 :          IF (.NOT. paw_atom) CYCLE
    2006          564 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    2007          564 :          CPASSERT(ASSOCIATED(grid_atom))
    2008          564 :          CPASSERT(ASSOCIATED(harmonics))
    2009          564 :          CPASSERT(ASSOCIATED(basis_1c))
    2010              :          ALLOCATE (vlocal_h(grid_atom%ng_sphere, grid_atom%nr, nspins), &
    2011         5076 :                    vlocal_s(grid_atom%ng_sphere, grid_atom%nr, nspins))
    2012              : 
    2013          564 :          atom_bounds = get_limit(natom_kind, para_env%num_pe, para_env%mepos)
    2014         1043 :          DO iat = atom_bounds(1), atom_bounds(2)
    2015          479 :             atom = atom_list(iat)
    2016          479 :             rho_atom => rho_atom_set(atom)
    2017          479 :             NULLIFY (r_h, r_s)
    2018          479 :             CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    2019          479 :             CALL reallocate(rho_h, 1, grid_atom%ng_sphere, 1, grid_atom%nr, 1, nspins)
    2020          479 :             CALL reallocate(rho_s, 1, grid_atom%ng_sphere, 1, grid_atom%nr, 1, nspins)
    2021      1668833 :             rho_h = 0.0_dp
    2022      1668833 :             rho_s = 0.0_dp
    2023        24429 :             DO ir = 1, grid_atom%nr
    2024              :                CALL calc_rho_angular(grid_atom, harmonics, nspins, .FALSE., ir, r_h, r_s, &
    2025        24429 :                                      rho_h, rho_s, dr_h, dr_s, r_h_d, r_s_d, drho_h, drho_s)
    2026              :             END DO
    2027      1668833 :             vlocal_h = 0.0_dp
    2028      1668833 :             vlocal_s = 0.0_dp
    2029              : 
    2030        24429 :             DO ir = 1, grid_atom%nr
    2031      1221929 :                DO ia = 1, grid_atom%ng_sphere
    2032              :                   point(1) = particle_set(atom)%r(1) + grid_atom%rad(ir)* &
    2033      1197500 :                              grid_atom%sin_pol(ia)*grid_atom%cos_azi(ia)
    2034              :                   point(2) = particle_set(atom)%r(2) + grid_atom%rad(ir)* &
    2035      1197500 :                              grid_atom%sin_pol(ia)*grid_atom%sin_azi(ia)
    2036      1197500 :                   point(3) = particle_set(atom)%r(3) + grid_atom%rad(ir)*grid_atom%cos_pol(ia)
    2037      1197500 :                   IF (PRESENT(electronic_charge)) THEN
    2038              :                      CALL cdft_point_weights(context, point, group_weights, &
    2039              :                                              group_point_derivative, group_atom_derivative, &
    2040       247500 :                                              atomic_weights)
    2041              :                   ELSE
    2042              :                      CALL cdft_point_weights(context, point, group_weights, &
    2043       950000 :                                              group_point_derivative, group_atom_derivative)
    2044              :                   END IF
    2045      2856450 :                   DO channel = 1, nspins
    2046      1635000 :                      delta_density = rho_h(ia, ir, channel) - rho_s(ia, ir, channel)
    2047      1635000 :                      IF (PRESENT(electronic_charge)) THEN
    2048              :                         electronic_charge(:, channel) = electronic_charge(:, channel) + &
    2049              :                                                         grid_atom%weight(ia, ir)*atomic_weights* &
    2050      1830000 :                                                         delta_density
    2051              :                      END IF
    2052      1635000 :                      point_factor = 0.0_dp
    2053      3630000 :                      DO igroup = 1, context%ngroup
    2054              :                         spin_factor = cdft_spin_factor( &
    2055      1995000 :                                       cdft_control%group(igroup)%constraint_type, channel, lsd)
    2056      1995000 :                         IF (PRESENT(operator_group)) THEN
    2057        10000 :                            IF (igroup == operator_group) THEN
    2058        10000 :                               point_factor = point_factor + group_weights(igroup)
    2059              :                            END IF
    2060              :                         ELSE
    2061              :                            point_factor = point_factor + cdft_control%strength(igroup)* &
    2062      1985000 :                                           group_weights(igroup)*spin_factor
    2063              :                         END IF
    2064              :                         values(igroup) = values(igroup) + grid_atom%weight(ia, ir)* &
    2065      1995000 :                                          group_weights(igroup)*delta_density*spin_factor
    2066      3630000 :                         IF (calculate_forces) THEN
    2067              :                            explicit_derivative(:, :) = &
    2068              :                               explicit_derivative + grid_atom%weight(ia, ir)* &
    2069              :                               cdft_control%strength(igroup)*delta_density* &
    2070       367500 :                               spin_factor*group_atom_derivative(:, :, igroup)
    2071              :                            explicit_derivative(:, atom) = explicit_derivative(:, atom) + &
    2072              :                                                           grid_atom%weight(ia, ir)* &
    2073              :                                                           cdft_control%strength(igroup)*delta_density* &
    2074       150000 :                                                           spin_factor*group_point_derivative(:, igroup)
    2075              :                         END IF
    2076              :                      END DO
    2077      1635000 :                      vlocal_h(ia, ir, channel) = grid_atom%weight(ia, ir)*point_factor
    2078      2832500 :                      vlocal_s(ia, ir, channel) = vlocal_h(ia, ir, channel)
    2079              :                   END DO
    2080              :                END DO
    2081              :             END DO
    2082              : 
    2083         1043 :             IF (.NOT. energy_only) THEN
    2084          360 :                NULLIFY (int_hh, int_ss)
    2085          360 :                operator_atom => operator_atom_set(atom)
    2086          360 :                CALL get_rho_atom(rho_atom=operator_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    2087              :                CALL gaVxcgb_noGC(vlocal_h, vlocal_s, int_hh, int_ss, grid_atom, &
    2088          360 :                                  basis_1c, harmonics, nspins)
    2089              :             END IF
    2090              :          END DO
    2091         1552 :          DEALLOCATE (vlocal_h, vlocal_s)
    2092              :       END DO
    2093              : 
    2094         1416 :       CALL para_env%sum(values)
    2095          424 :       CALL para_env%sum(explicit_derivative)
    2096         1520 :       IF (PRESENT(electronic_charge)) CALL para_env%sum(electronic_charge)
    2097          424 :       IF (calculate_forces .AND. ASSOCIATED(force) .AND. para_env%is_source()) THEN
    2098            9 :          DO ikind = 1, SIZE(atomic_kind_set)
    2099            5 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom_kind)
    2100           18 :             DO iat = 1, natom_kind
    2101            9 :                atom = atom_list(iat)
    2102              :                force(ikind)%rho_elec(:, iat) = force(ikind)%rho_elec(:, iat) + &
    2103           41 :                                                explicit_derivative(:, atom)
    2104              :             END DO
    2105              :          END DO
    2106              :       END IF
    2107              : 
    2108          424 :       IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
    2109          424 :       IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
    2110          424 :       IF (ALLOCATED(atomic_weights)) DEALLOCATE (atomic_weights)
    2111          424 :       DEALLOCATE (explicit_derivative, group_atom_derivative, group_point_derivative, group_weights)
    2112          848 :       CALL cdft_point_context_release(context)
    2113              : 
    2114              :    CONTAINS
    2115              : 
    2116              : ! **************************************************************************************************
    2117              : !> \brief ...
    2118              : !> \param constraint_type ...
    2119              : !> \param channel ...
    2120              : !> \param lsd ...
    2121              : !> \return ...
    2122              : ! **************************************************************************************************
    2123      1995000 :       FUNCTION cdft_spin_factor(constraint_type, channel, lsd) RESULT(factor)
    2124              :       INTEGER, INTENT(IN)                                :: constraint_type, channel
    2125              :       LOGICAL, INTENT(IN)                                :: lsd
    2126              :       REAL(KIND=dp)                                      :: factor
    2127              : 
    2128      1995000 :          SELECT CASE (constraint_type)
    2129              :          CASE (cdft_charge_constraint)
    2130            0 :             factor = 1.0_dp
    2131              :          CASE (cdft_magnetization_constraint)
    2132            0 :             CPASSERT(lsd)
    2133            0 :             factor = MERGE(1.0_dp, -1.0_dp, channel == 1)
    2134              :          CASE (cdft_alpha_constraint)
    2135       360000 :             CPASSERT(lsd)
    2136       360000 :             factor = MERGE(1.0_dp, 0.0_dp, channel == 1)
    2137              :          CASE (cdft_beta_constraint)
    2138       360000 :             CPASSERT(lsd)
    2139       360000 :             factor = MERGE(1.0_dp, 0.0_dp, channel == 2)
    2140              :          CASE DEFAULT
    2141      1995000 :             CPABORT("Unknown CDFT constraint type.")
    2142              :          END SELECT
    2143      1995000 :       END FUNCTION cdft_spin_factor
    2144              : 
    2145              :    END SUBROUTINE gapw_cdft_one_center
    2146              : 
    2147              : ! **************************************************************************************************
    2148              : !> \brief Contract a compact one-center density matrix with an integral in the padded old basis.
    2149              : !> \param density_matrix ...
    2150              : !> \param integral_matrix ...
    2151              : !> \param new_to_old ...
    2152              : !> \return ...
    2153              : ! **************************************************************************************************
    2154          168 :    FUNCTION contract_one_center_matrix(density_matrix, integral_matrix, new_to_old) RESULT(value)
    2155              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: density_matrix, integral_matrix
    2156              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: new_to_old
    2157              :       REAL(KIND=dp)                                      :: value
    2158              : 
    2159              :       INTEGER                                            :: ibas, jbas, nbas
    2160              : 
    2161          168 :       nbas = SIZE(density_matrix, 1)
    2162          168 :       CPASSERT(SIZE(density_matrix, 2) == nbas)
    2163          168 :       CPASSERT(SIZE(new_to_old) >= nbas)
    2164         1644 :       CPASSERT(MINVAL(new_to_old(1:nbas)) >= 1)
    2165         1644 :       CPASSERT(MAXVAL(new_to_old(1:nbas)) <= SIZE(integral_matrix, 1))
    2166         1644 :       CPASSERT(MAXVAL(new_to_old(1:nbas)) <= SIZE(integral_matrix, 2))
    2167              : 
    2168          168 :       value = 0.0_dp
    2169         1644 :       DO jbas = 1, nbas
    2170        21576 :          DO ibas = 1, nbas
    2171              :             value = value + density_matrix(ibas, jbas)* &
    2172        21408 :                     integral_matrix(new_to_old(ibas), new_to_old(jbas))
    2173              :          END DO
    2174              :       END DO
    2175              : 
    2176          168 :    END FUNCTION contract_one_center_matrix
    2177              : 
    2178              : ! **************************************************************************************************
    2179              : !> \brief Replicate a distributed real-space field for atom-grid interpolation.
    2180              : !> \param local_values ...
    2181              : !> \param pw_grid ...
    2182              : !> \param group ...
    2183              : !> \param global_values ...
    2184              : ! **************************************************************************************************
    2185          140 :    SUBROUTINE gather_native_grid_field(local_values, pw_grid, group, global_values)
    2186              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN), &
    2187              :          POINTER                                         :: local_values
    2188              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    2189              :       TYPE(mp_para_env_type), INTENT(IN)                 :: group
    2190              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(OUT), &
    2191              :          POINTER                                         :: global_values
    2192              : 
    2193              :       INTEGER, DIMENSION(2, 3)                           :: bo
    2194              : 
    2195          140 :       CPASSERT(ASSOCIATED(local_values))
    2196          140 :       CPASSERT(ASSOCIATED(pw_grid))
    2197          140 :       CPASSERT(.NOT. ASSOCIATED(global_values))
    2198         1400 :       bo = pw_grid%bounds_local
    2199              :       ALLOCATE (global_values(pw_grid%bounds(1, 1):pw_grid%bounds(2, 1), &
    2200              :                               pw_grid%bounds(1, 2):pw_grid%bounds(2, 2), &
    2201          700 :                               pw_grid%bounds(1, 3):pw_grid%bounds(2, 3)))
    2202      6167480 :       global_values = 0.0_dp
    2203              :       global_values(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)) = &
    2204      6342580 :          local_values
    2205     12334820 :       CALL group%sum(global_values)
    2206              : 
    2207          140 :    END SUBROUTINE gather_native_grid_field
    2208              : 
    2209              : ! **************************************************************************************************
    2210              : !> \brief Interpolate a replicated native-grid field at a Cartesian point.
    2211              : !> \param values ...
    2212              : !> \param pw_grid ...
    2213              : !> \param cell ...
    2214              : !> \param point ...
    2215              : !> \return ...
    2216              : ! **************************************************************************************************
    2217      1050000 :    FUNCTION interpolate_native_grid(values, pw_grid, cell, point) RESULT(value)
    2218              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: values
    2219              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    2220              :       TYPE(cell_type), INTENT(IN), POINTER               :: cell
    2221              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: point
    2222              :       REAL(KIND=dp)                                      :: value
    2223              : 
    2224              :       INTEGER                                            :: corner_x, corner_y, corner_z, idir
    2225              :       INTEGER, DIMENSION(3)                              :: base, index, relative_index
    2226              :       REAL(KIND=dp)                                      :: coefficient
    2227              :       REAL(KIND=dp), DIMENSION(3)                        :: fraction, relative
    2228              :       REAL(KIND=dp), &
    2229              :          DIMENSION(native_grid_interp_npts, 3)           :: weights
    2230              : 
    2231      1050000 :       CPASSERT(ASSOCIATED(pw_grid))
    2232      1050000 :       CPASSERT(ASSOCIATED(cell))
    2233      4200000 :       DO idir = 1, 3
    2234      4200000 :          CPASSERT(SIZE(values, idir) == pw_grid%npts(idir))
    2235              :       END DO
    2236              : 
    2237     13650000 :       relative = MATMUL(pw_grid%dh_inv, point)
    2238      3828390 :       DO idir = 1, 3
    2239      2942700 :          IF (cell%perd(idir) == 1) THEN
    2240            0 :             relative(idir) = MODULO(relative(idir), REAL(pw_grid%npts(idir), KIND=dp))
    2241      2942700 :          ELSE IF (relative(idir) <= -REAL(native_grid_interp_offset_max, dp) .OR. &
    2242              :                   relative(idir) >= REAL(pw_grid%npts(idir) - &
    2243              :                                          native_grid_interp_offset_min, KIND=dp)) THEN
    2244      1050000 :             value = 0.0_dp
    2245              :             RETURN
    2246              :          END IF
    2247      2778390 :          base(idir) = FLOOR(relative(idir))
    2248      2778390 :          FRACTION(idir) = relative(idir) - REAL(base(idir), KIND=dp)
    2249      3664080 :          CALL native_grid_lagrange_weights(FRACTION(idir), weights(:, idir))
    2250              :       END DO
    2251              : 
    2252              :       value = 0.0_dp
    2253      7971210 :       DO corner_z = native_grid_interp_offset_min, native_grid_interp_offset_max
    2254     64655370 :          DO corner_y = native_grid_interp_offset_min, native_grid_interp_offset_max
    2255    517242960 :             DO corner_x = native_grid_interp_offset_min, native_grid_interp_offset_max
    2256   1813893120 :                relative_index = base + [corner_x, corner_y, corner_z]
    2257              :                coefficient = weights(corner_x - native_grid_interp_offset_min + 1, 1)* &
    2258              :                              weights(corner_y - native_grid_interp_offset_min + 1, 2)* &
    2259    453473280 :                              weights(corner_z - native_grid_interp_offset_min + 1, 3)
    2260   1813893120 :                DO idir = 1, 3
    2261   1813893120 :                   IF (cell%perd(idir) == 1) THEN
    2262            0 :                      relative_index(idir) = MODULO(relative_index(idir), pw_grid%npts(idir))
    2263   1360419840 :                   ELSE IF (relative_index(idir) < 0 .OR. &
    2264              :                            relative_index(idir) >= pw_grid%npts(idir)) THEN
    2265     25432320 :                      coefficient = 0.0_dp
    2266              :                   END IF
    2267              :                END DO
    2268    453473280 :                IF (coefficient == 0.0_dp) CYCLE
    2269   1728102960 :                index = LBOUND(values) + relative_index
    2270    510157440 :                value = value + coefficient*values(INDEX(1), INDEX(2), INDEX(3))
    2271              :             END DO
    2272              :          END DO
    2273              :       END DO
    2274              : 
    2275              :    END FUNCTION interpolate_native_grid
    2276              : 
    2277              : ! **************************************************************************************************
    2278              : !> \brief Return the Cartesian gradient of native-grid interpolation at one point.
    2279              : !> \param values ...
    2280              : !> \param pw_grid ...
    2281              : !> \param cell ...
    2282              : !> \param point ...
    2283              : !> \return ...
    2284              : ! **************************************************************************************************
    2285        50000 :    FUNCTION interpolate_native_grid_gradient(values, pw_grid, cell, point) RESULT(gradient)
    2286              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: values
    2287              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    2288              :       TYPE(cell_type), INTENT(IN), POINTER               :: cell
    2289              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: point
    2290              :       REAL(KIND=dp), DIMENSION(3)                        :: gradient
    2291              : 
    2292              :       INTEGER                                            :: corner_x, corner_y, corner_z, idir, jdir
    2293              :       INTEGER, DIMENSION(3)                              :: base, corner_index, index, relative_index
    2294              :       REAL(KIND=dp)                                      :: coefficient
    2295              :       REAL(KIND=dp), DIMENSION(3)                        :: fraction, gradient_relative, relative
    2296              :       REAL(KIND=dp), &
    2297              :          DIMENSION(native_grid_interp_npts, 3)           :: derivative_weights, weights
    2298              : 
    2299        50000 :       CPASSERT(ASSOCIATED(pw_grid))
    2300        50000 :       CPASSERT(ASSOCIATED(cell))
    2301       200000 :       DO idir = 1, 3
    2302       200000 :          CPASSERT(SIZE(values, idir) == pw_grid%npts(idir))
    2303              :       END DO
    2304              : 
    2305       650000 :       relative = MATMUL(pw_grid%dh_inv, point)
    2306       178165 :       DO idir = 1, 3
    2307       137650 :          IF (cell%perd(idir) == 1) THEN
    2308            0 :             relative(idir) = MODULO(relative(idir), REAL(pw_grid%npts(idir), KIND=dp))
    2309       137650 :          ELSE IF (relative(idir) <= -REAL(native_grid_interp_offset_max, dp) .OR. &
    2310              :                   relative(idir) >= REAL(pw_grid%npts(idir) - &
    2311              :                                          native_grid_interp_offset_min, KIND=dp)) THEN
    2312        37940 :             gradient = 0.0_dp
    2313         9485 :             RETURN
    2314              :          END IF
    2315       128165 :          base(idir) = FLOOR(relative(idir))
    2316       128165 :          FRACTION(idir) = relative(idir) - REAL(base(idir), KIND=dp)
    2317              :          CALL native_grid_lagrange_weights( &
    2318       168680 :             FRACTION(idir), weights(:, idir), derivative_weights(:, idir))
    2319              :       END DO
    2320              : 
    2321        40515 :       gradient_relative = 0.0_dp
    2322       364635 :       DO corner_z = native_grid_interp_offset_min, native_grid_interp_offset_max
    2323      2957595 :          DO corner_y = native_grid_interp_offset_min, native_grid_interp_offset_max
    2324     23660760 :             DO corner_x = native_grid_interp_offset_min, native_grid_interp_offset_max
    2325     82974720 :                relative_index = base + [corner_x, corner_y, corner_z]
    2326              :                corner_index = [corner_x, corner_y, corner_z] - &
    2327     82974720 :                               native_grid_interp_offset_min + 1
    2328     80568215 :                DO idir = 1, 3
    2329     81727880 :                   IF (cell%perd(idir) == 1) THEN
    2330            0 :                      relative_index(idir) = MODULO(relative_index(idir), pw_grid%npts(idir))
    2331     60984200 :                   ELSE IF (relative_index(idir) < 0 .OR. &
    2332              :                            relative_index(idir) >= pw_grid%npts(idir)) THEN
    2333              :                      EXIT
    2334              :                   END IF
    2335              :                END DO
    2336     20743680 :                IF (idir <= 3) CYCLE
    2337     78336060 :                index = LBOUND(values) + relative_index
    2338     80929020 :                DO idir = 1, 3
    2339              :                   coefficient = 1.0_dp
    2340    235008180 :                   DO jdir = 1, 3
    2341    235008180 :                      IF (jdir == idir) THEN
    2342              :                         coefficient = coefficient*derivative_weights( &
    2343     58752045 :                                       corner_index(jdir), jdir)
    2344              :                      ELSE
    2345              :                         coefficient = coefficient*weights( &
    2346    117504090 :                                       corner_index(jdir), jdir)
    2347              :                      END IF
    2348              :                   END DO
    2349              :                   gradient_relative(idir) = gradient_relative(idir) + &
    2350     79495725 :                                             coefficient*values(INDEX(1), INDEX(2), INDEX(3))
    2351              :                END DO
    2352              :             END DO
    2353              :          END DO
    2354              :       END DO
    2355        40515 :       gradient = MATMUL(TRANSPOSE(pw_grid%dh_inv), gradient_relative)
    2356              : 
    2357              :    END FUNCTION interpolate_native_grid_gradient
    2358              : 
    2359              : ! **************************************************************************************************
    2360              : !> \brief Apply the transpose of native-grid interpolation for one point.
    2361              : !> \param values ...
    2362              : !> \param pw_grid ...
    2363              : !> \param cell ...
    2364              : !> \param point ...
    2365              : !> \param value ...
    2366              : ! **************************************************************************************************
    2367       700000 :    SUBROUTINE add_native_grid_interpolation_adjoint(values, pw_grid, cell, point, value)
    2368              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: values
    2369              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    2370              :       TYPE(cell_type), INTENT(IN), POINTER               :: cell
    2371              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: point
    2372              :       REAL(KIND=dp), INTENT(IN)                          :: value
    2373              : 
    2374              :       INTEGER                                            :: corner_x, corner_y, corner_z, idir, ipt
    2375              :       INTEGER, DIMENSION(3)                              :: base, relative_index
    2376              :       REAL(KIND=dp)                                      :: coefficient
    2377              :       REAL(KIND=dp), DIMENSION(3)                        :: fraction, relative
    2378              :       REAL(KIND=dp), &
    2379              :          DIMENSION(native_grid_interp_npts, 3)           :: weights
    2380              : 
    2381       700000 :       CPASSERT(ASSOCIATED(pw_grid))
    2382       700000 :       CPASSERT(ASSOCIATED(cell))
    2383      2800000 :       CPASSERT(SIZE(values) == PRODUCT(pw_grid%npts))
    2384              : 
    2385      9100000 :       relative = MATMUL(pw_grid%dh_inv, point)
    2386      2552260 :       DO idir = 1, 3
    2387      1961800 :          IF (cell%perd(idir) == 1) THEN
    2388            0 :             relative(idir) = MODULO(relative(idir), REAL(pw_grid%npts(idir), KIND=dp))
    2389      1961800 :          ELSE IF (relative(idir) <= -REAL(native_grid_interp_offset_max, dp) .OR. &
    2390              :                   relative(idir) >= REAL(pw_grid%npts(idir) - &
    2391              :                                          native_grid_interp_offset_min, KIND=dp)) THEN
    2392       109540 :             RETURN
    2393              :          END IF
    2394      1852260 :          base(idir) = FLOOR(relative(idir))
    2395      1852260 :          FRACTION(idir) = relative(idir) - REAL(base(idir), KIND=dp)
    2396      2442720 :          CALL native_grid_lagrange_weights(FRACTION(idir), weights(:, idir))
    2397              :       END DO
    2398              : 
    2399      5314140 :       DO corner_z = native_grid_interp_offset_min, native_grid_interp_offset_max
    2400     43103580 :          DO corner_y = native_grid_interp_offset_min, native_grid_interp_offset_max
    2401    344828640 :             DO corner_x = native_grid_interp_offset_min, native_grid_interp_offset_max
    2402   1209262080 :                relative_index = base + [corner_x, corner_y, corner_z]
    2403              :                coefficient = weights(corner_x - native_grid_interp_offset_min + 1, 1)* &
    2404              :                              weights(corner_y - native_grid_interp_offset_min + 1, 2)* &
    2405    302315520 :                              weights(corner_z - native_grid_interp_offset_min + 1, 3)
    2406   1209262080 :                DO idir = 1, 3
    2407   1209262080 :                   IF (cell%perd(idir) == 1) THEN
    2408            0 :                      relative_index(idir) = MODULO(relative_index(idir), pw_grid%npts(idir))
    2409    906946560 :                   ELSE IF (relative_index(idir) < 0 .OR. &
    2410              :                            relative_index(idir) >= pw_grid%npts(idir)) THEN
    2411     16954880 :                      coefficient = 0.0_dp
    2412              :                   END IF
    2413              :                END DO
    2414    302315520 :                IF (coefficient == 0.0_dp) CYCLE
    2415              :                ipt = 1 + relative_index(1) + pw_grid%npts(1)*( &
    2416    288017160 :                      relative_index(2) + pw_grid%npts(2)*relative_index(3))
    2417    340104960 :                values(ipt) = values(ipt) + coefficient*value
    2418              :             END DO
    2419              :          END DO
    2420              :       END DO
    2421              : 
    2422              :    END SUBROUTINE add_native_grid_interpolation_adjoint
    2423              : 
    2424              : ! **************************************************************************************************
    2425              : !> \brief Build the value and optional derivative weights for the native-grid interpolation.
    2426              : !> \param fraction fractional coordinate between two grid points
    2427              : !> \param weights interpolation weights
    2428              : !> \param derivative_weights optional derivatives with respect to fraction
    2429              : ! **************************************************************************************************
    2430      4758815 :    SUBROUTINE native_grid_lagrange_weights(fraction, weights, derivative_weights)
    2431              :       REAL(KIND=dp), INTENT(IN)                          :: fraction
    2432              :       REAL(KIND=dp), &
    2433              :          DIMENSION(native_grid_interp_npts), INTENT(OUT) :: weights
    2434              :       REAL(KIND=dp), &
    2435              :          DIMENSION(native_grid_interp_npts), &
    2436              :          INTENT(OUT), OPTIONAL                           :: derivative_weights
    2437              : 
    2438              :       INTEGER                                            :: inode, jnode, knode
    2439              :       REAL(KIND=dp)                                      :: denominator, derivative, numerator
    2440              :       REAL(KIND=dp), DIMENSION(native_grid_interp_npts)  :: nodes
    2441              : 
    2442     42829335 :       DO inode = 1, native_grid_interp_npts
    2443     42829335 :          nodes(inode) = REAL(native_grid_interp_offset_min + inode - 1, dp)
    2444              :       END DO
    2445     42829335 :       DO inode = 1, native_grid_interp_npts
    2446              :          denominator = 1.0_dp
    2447              :          numerator = 1.0_dp
    2448    342634680 :          DO jnode = 1, native_grid_interp_npts
    2449    304564160 :             IF (jnode == inode) CYCLE
    2450    266493640 :             denominator = denominator*(nodes(inode) - nodes(jnode))
    2451    342634680 :             numerator = numerator*(fraction - nodes(jnode))
    2452              :          END DO
    2453     38070520 :          weights(inode) = numerator/denominator
    2454     42829335 :          IF (PRESENT(derivative_weights)) THEN
    2455              :             derivative = 0.0_dp
    2456      9227880 :             DO knode = 1, native_grid_interp_npts
    2457      8202560 :                IF (knode == inode) CYCLE
    2458              :                numerator = 1.0_dp
    2459     64595160 :                DO jnode = 1, native_grid_interp_npts
    2460     57417920 :                   IF (jnode == inode .OR. jnode == knode) CYCLE
    2461     64595160 :                   numerator = numerator*(fraction - nodes(jnode))
    2462              :                END DO
    2463      9227880 :                derivative = derivative + numerator/denominator
    2464              :             END DO
    2465      1025320 :             derivative_weights(inode) = derivative
    2466              :          END IF
    2467              :       END DO
    2468              : 
    2469      4758815 :    END SUBROUTINE native_grid_lagrange_weights
    2470              : 
    2471              : ! **************************************************************************************************
    2472              : !> \brief Evaluate one GAPW hard-minus-soft atom correction at an arbitrary point.
    2473              : !> \param grid_atom ...
    2474              : !> \param harmonics ...
    2475              : !> \param r_h ...
    2476              : !> \param r_s ...
    2477              : !> \param dr_h ...
    2478              : !> \param dr_s ...
    2479              : !> \param r_h_d ...
    2480              : !> \param r_s_d ...
    2481              : !> \param tau_coeff ...
    2482              : !> \param nspins ...
    2483              : !> \param cutoff ...
    2484              : !> \param atom_coord ...
    2485              : !> \param point ...
    2486              : !> \param cell ...
    2487              : !> \param density ...
    2488              : !> \param grad ...
    2489              : !> \param kin ...
    2490              : ! **************************************************************************************************
    2491        70000 :    SUBROUTINE evaluate_gapw_atom_delta(grid_atom, harmonics, r_h, r_s, dr_h, dr_s, r_h_d, r_s_d, &
    2492              :                                        tau_coeff, nspins, cutoff, atom_coord, point, cell, &
    2493              :                                        density, grad, kin)
    2494              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    2495              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    2496              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: r_h, r_s, dr_h, dr_s
    2497              :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    2498              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
    2499              :          INTENT(IN)                                      :: tau_coeff
    2500              :       INTEGER, INTENT(IN)                                :: nspins
    2501              :       REAL(KIND=dp), INTENT(IN)                          :: cutoff
    2502              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: atom_coord, point
    2503              :       TYPE(cell_type), POINTER                           :: cell
    2504              :       REAL(KIND=dp), DIMENSION(2), INTENT(OUT)           :: density
    2505              :       REAL(KIND=dp), DIMENSION(3, 2), INTENT(OUT)        :: grad
    2506              :       REAL(KIND=dp), DIMENSION(2), INTENT(OUT)           :: kin
    2507              : 
    2508              :       INTEGER                                            :: idir, iso, ispin, l, m
    2509              :       REAL(KIND=dp)                                      :: dradial, radial, value, y(1)
    2510              :       REAL(KIND=dp), DIMENSION(3)                        :: displacement, unit_vector
    2511              :       REAL(KIND=dp), DIMENSION(3, 1)                     :: direction
    2512              : 
    2513        70000 :       density = 0.0_dp
    2514        70000 :       grad = 0.0_dp
    2515        70000 :       kin = 0.0_dp
    2516       280000 :       displacement = pbc(point - atom_coord, cell)
    2517       280000 :       radial = SQRT(SUM(displacement**2))
    2518        70000 :       IF (radial > cutoff) RETURN
    2519            0 :       IF (radial > 1.0E-14_dp) THEN
    2520            0 :          unit_vector = displacement/radial
    2521              :       ELSE
    2522            0 :          unit_vector = [0.0_dp, 0.0_dp, 1.0_dp]
    2523              :       END IF
    2524            0 :       direction(:, 1) = unit_vector
    2525              : 
    2526            0 :       DO iso = 1, harmonics%max_iso_not0
    2527            0 :          l = indso(1, iso)
    2528            0 :          m = indso(2, iso)
    2529            0 :          CALL y_lm(direction, y, l, m)
    2530            0 :          DO ispin = 1, nspins
    2531              :             value = interpolate_radial_difference( &
    2532            0 :                     grid_atom%rad, r_h(ispin)%r_coef(:, iso), r_s(ispin)%r_coef(:, iso), radial)
    2533            0 :             density(ispin) = density(ispin) + value*y(1)
    2534              :             dradial = interpolate_radial_difference( &
    2535            0 :                       grid_atom%rad, dr_h(ispin)%r_coef(:, iso), dr_s(ispin)%r_coef(:, iso), radial)
    2536            0 :             DO idir = 1, 3
    2537              :                value = interpolate_radial_difference( &
    2538              :                        grid_atom%rad, r_h_d(idir, ispin)%r_coef(:, iso), &
    2539            0 :                        r_s_d(idir, ispin)%r_coef(:, iso), radial)
    2540              :                grad(idir, ispin) = grad(idir, ispin) + &
    2541            0 :                                    (dradial*unit_vector(idir) + value)*y(1)
    2542              :             END DO
    2543            0 :             value = interpolate_radial_value(grid_atom%rad, tau_coeff(:, iso, ispin), radial)
    2544            0 :             kin(ispin) = kin(ispin) + value*y(1)
    2545              :          END DO
    2546              :       END DO
    2547              : 
    2548              :    END SUBROUTINE evaluate_gapw_atom_delta
    2549              : 
    2550              : ! **************************************************************************************************
    2551              : !> \brief Cubically interpolate the difference of two nonuniform radial tables.
    2552              : !> \param radial_grid ...
    2553              : !> \param hard ...
    2554              : !> \param soft ...
    2555              : !> \param radius ...
    2556              : !> \return ...
    2557              : ! **************************************************************************************************
    2558            0 :    FUNCTION interpolate_radial_difference(radial_grid, hard, soft, radius) RESULT(value)
    2559              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: radial_grid, hard, soft
    2560              :       REAL(KIND=dp), INTENT(IN)                          :: radius
    2561              :       REAL(KIND=dp)                                      :: value
    2562              : 
    2563            0 :       value = interpolate_radial_value(radial_grid, hard - soft, radius)
    2564              : 
    2565            0 :    END FUNCTION interpolate_radial_difference
    2566              : 
    2567              : ! **************************************************************************************************
    2568              : !> \brief Cubically interpolate a nonuniform radial table.
    2569              : !> \param radial_grid ...
    2570              : !> \param samples ...
    2571              : !> \param radius ...
    2572              : !> \return ...
    2573              : ! **************************************************************************************************
    2574            0 :    FUNCTION interpolate_radial_value(radial_grid, samples, radius) RESULT(value)
    2575              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: radial_grid, samples
    2576              :       REAL(KIND=dp), INTENT(IN)                          :: radius
    2577              :       REAL(KIND=dp)                                      :: value
    2578              : 
    2579              :       INTEGER                                            :: i, j, k, left, n, start
    2580              :       REAL(KIND=dp)                                      :: weight
    2581              : 
    2582            0 :       n = SIZE(radial_grid)
    2583            0 :       CPASSERT(SIZE(samples) == n)
    2584            0 :       IF (radius > radial_grid(n)) THEN
    2585            0 :          value = 0.0_dp
    2586              :          RETURN
    2587              :       END IF
    2588            0 :       IF (n < 4) THEN
    2589            0 :          CPASSERT(n >= 2)
    2590            0 :          IF (radius <= radial_grid(1)) THEN
    2591              :             left = 1
    2592              :          ELSE
    2593            0 :             left = n - 1
    2594            0 :             DO i = 1, n - 1
    2595            0 :                IF (radius < radial_grid(i + 1)) THEN
    2596              :                   left = i
    2597              :                   EXIT
    2598              :                END IF
    2599              :             END DO
    2600              :          END IF
    2601              :          weight = (radius - radial_grid(left))/ &
    2602            0 :                   (radial_grid(left + 1) - radial_grid(left))
    2603            0 :          value = (1.0_dp - weight)*samples(left) + weight*samples(left + 1)
    2604            0 :          RETURN
    2605              :       END IF
    2606              : 
    2607            0 :       IF (radius <= radial_grid(2)) THEN
    2608              :          start = 1
    2609            0 :       ELSE IF (radius >= radial_grid(n - 1)) THEN
    2610            0 :          start = n - 3
    2611              :       ELSE
    2612            0 :          left = 2
    2613            0 :          DO i = 2, n - 2
    2614            0 :             IF (radius < radial_grid(i + 1)) THEN
    2615              :                left = i
    2616              :                EXIT
    2617              :             END IF
    2618              :          END DO
    2619            0 :          start = left - 1
    2620              :       END IF
    2621              : 
    2622            0 :       value = 0.0_dp
    2623            0 :       DO j = start, start + 3
    2624              :          weight = 1.0_dp
    2625            0 :          DO k = start, start + 3
    2626            0 :             IF (k == j) CYCLE
    2627            0 :             weight = weight*(radius - radial_grid(k))/(radial_grid(j) - radial_grid(k))
    2628              :          END DO
    2629            0 :          value = value + weight*samples(j)
    2630              :       END DO
    2631              : 
    2632              :    END FUNCTION interpolate_radial_value
    2633              : 
    2634              : ! **************************************************************************************************
    2635              : !> \brief ...
    2636              : !> \param qs_env ...
    2637              : !> \param exc1 the on-body ex energy contribution
    2638              : !> \param gradient_atom_set ...
    2639              : ! **************************************************************************************************
    2640           10 :    SUBROUTINE calculate_vxc_atom_epr(qs_env, exc1, gradient_atom_set)
    2641              : 
    2642              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2643              :       REAL(dp), INTENT(INOUT)                            :: exc1
    2644              :       TYPE(nablavks_atom_type), DIMENSION(:), POINTER    :: gradient_atom_set
    2645              : 
    2646              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_vxc_atom_epr'
    2647              : 
    2648              :       INTEGER                                            :: bo(2), handle, ia, iat, iatom, idir, &
    2649              :                                                             ikind, ir, ispin, myfun, na, natom, &
    2650              :                                                             nr, nspins, num_pe
    2651              :       INTEGER, DIMENSION(2, 3)                           :: bounds
    2652           10 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
    2653              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
    2654              :                                                             paw_atom, tau_f
    2655              :       REAL(dp)                                           :: agr, alpha, density_cut, exc_h, exc_s, &
    2656              :                                                             gradient_cut, tau_cut
    2657              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
    2658              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
    2659           20 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
    2660           20 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho_h, rho_s, tau_h, tau_s, vtau_h, &
    2661           10 :                                                             vtau_s, vxc_h, vxc_s
    2662           20 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho_h, drho_s, vxg_h, vxg_s
    2663           10 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2664              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2665              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    2666              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    2667              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    2668              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2669           10 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: my_kind_set
    2670           10 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
    2671           10 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    2672           10 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: my_rho_atom_set
    2673              :       TYPE(rho_atom_type), POINTER                       :: rho_atom
    2674              :       TYPE(section_vals_type), POINTER                   :: input, my_xc_section, xc_fun_section
    2675           10 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
    2676              :       TYPE(xc_derivative_set_type)                       :: deriv_set
    2677              :       TYPE(xc_rho_cflags_type)                           :: needs
    2678              :       TYPE(xc_rho_set_type)                              :: rho_set_h, rho_set_s
    2679              : 
    2680              : ! -------------------------------------------------------------------------
    2681              : 
    2682           10 :       CALL timeset(routineN, handle)
    2683              : 
    2684           10 :       NULLIFY (atom_list)
    2685           10 :       NULLIFY (my_kind_set)
    2686           10 :       NULLIFY (atomic_kind_set)
    2687           10 :       NULLIFY (grid_atom)
    2688           10 :       NULLIFY (harmonics)
    2689           10 :       NULLIFY (input)
    2690           10 :       NULLIFY (para_env)
    2691           10 :       NULLIFY (rho_atom)
    2692           10 :       NULLIFY (my_rho_atom_set)
    2693           10 :       NULLIFY (rho_nlcc)
    2694              : 
    2695              :       CALL get_qs_env(qs_env=qs_env, &
    2696              :                       dft_control=dft_control, &
    2697              :                       para_env=para_env, &
    2698              :                       atomic_kind_set=atomic_kind_set, &
    2699              :                       qs_kind_set=my_kind_set, &
    2700              :                       input=input, &
    2701           10 :                       rho_atom_set=my_rho_atom_set)
    2702              : 
    2703           10 :       nlcc = has_nlcc(my_kind_set)
    2704           10 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
    2705              : 
    2706              :       my_xc_section => section_vals_get_subs_vals(input, &
    2707           10 :                                                   "PROPERTIES%LINRES%EPR%PRINT%G_TENSOR%XC")
    2708           10 :       xc_fun_section => section_vals_get_subs_vals(my_xc_section, "XC_FUNCTIONAL")
    2709              :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", &
    2710           10 :                                 i_val=myfun)
    2711              : 
    2712           10 :       IF (myfun == xc_none) THEN
    2713            0 :          exc1 = 0.0_dp
    2714            0 :          my_rho_atom_set(:)%exc_h = 0.0_dp
    2715            0 :          my_rho_atom_set(:)%exc_s = 0.0_dp
    2716              :       ELSE
    2717              :          CALL section_vals_val_get(my_xc_section, "DENSITY_CUTOFF", &
    2718           10 :                                    r_val=density_cut)
    2719              :          CALL section_vals_val_get(my_xc_section, "GRADIENT_CUTOFF", &
    2720           10 :                                    r_val=gradient_cut)
    2721              :          CALL section_vals_val_get(my_xc_section, "TAU_CUTOFF", &
    2722           10 :                                    r_val=tau_cut)
    2723              : 
    2724           10 :          lsd = dft_control%lsd
    2725           10 :          nspins = dft_control%nspins
    2726              :          needs = xc_functionals_get_needs(xc_fun_section, &
    2727              :                                           lsd=lsd, &
    2728           10 :                                           calc_potential=.TRUE.)
    2729              : 
    2730              :          ! whatever the xc, if epr_xc, drho_spin is needed
    2731           10 :          needs%drho_spin = .TRUE.
    2732              : 
    2733           10 :          gradient_f = (needs%drho .OR. needs%drho_spin)
    2734           10 :          tau_f = (needs%tau .OR. needs%tau_spin)
    2735              : 
    2736              :          ! Initialize energy contribution from the one center XC terms to zero
    2737           10 :          exc1 = 0.0_dp
    2738              : 
    2739              :          ! Nullify some pointers for work-arrays
    2740           10 :          NULLIFY (rho_h, drho_h, rho_s, drho_s, weight_h, weight_s)
    2741           10 :          NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
    2742           10 :          NULLIFY (tau_h, tau_s)
    2743           10 :          NULLIFY (vtau_h, vtau_s)
    2744              : 
    2745              :          ! Here starts the loop over all the atoms
    2746              : 
    2747           30 :          DO ikind = 1, SIZE(atomic_kind_set)
    2748           20 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    2749              :             CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
    2750           20 :                              harmonics=harmonics, grid_atom=grid_atom)
    2751           20 :             CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    2752              : 
    2753           20 :             IF (.NOT. paw_atom) CYCLE
    2754              : 
    2755           20 :             nr = grid_atom%nr
    2756           20 :             na = grid_atom%ng_sphere
    2757              : 
    2758              :             ! Prepare the structures needed to calculate and store the xc derivatives
    2759              : 
    2760              :             ! Array dimension: here anly one dimensional arrays are used,
    2761              :             ! i.e. only the first column of deriv_data is read.
    2762              :             ! The other to dimensions  are set to size equal 1
    2763          200 :             bounds(1:2, 1:3) = 1
    2764           20 :             bounds(2, 1) = na
    2765           20 :             bounds(2, 2) = nr
    2766              : 
    2767              :             ! set integration weights
    2768           20 :             IF (accint) THEN
    2769            0 :                weight_h => grid_atom%weight
    2770            0 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
    2771            0 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    2772            0 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
    2773              :                END IF
    2774            0 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    2775            0 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
    2776            0 :                   DO ir = 1, nr
    2777            0 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
    2778            0 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
    2779              :                   END DO
    2780            0 :                   grid_atom%gapw_weight_alpha = alpha
    2781              :                END IF
    2782            0 :                weight_s => grid_atom%gapw_weight_s
    2783              :             ELSE
    2784           20 :                weight_h => grid_atom%weight
    2785           20 :                weight_s => grid_atom%weight
    2786              :             END IF
    2787              : 
    2788              :             ! create a place where to put the derivatives
    2789           20 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
    2790              :             ! create the place where to store the argument for the functionals
    2791              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
    2792           20 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    2793              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
    2794           20 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    2795              : 
    2796              :             ! allocate the required 3d arrays where to store rho and drho
    2797           20 :             CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
    2798           20 :             CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
    2799              : 
    2800           20 :             CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
    2801           20 :             CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
    2802           20 :             CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
    2803           20 :             CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
    2804              :             !
    2805              :             IF (gradient_f) THEN
    2806           20 :                CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
    2807           20 :                CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
    2808           20 :                CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
    2809           20 :                CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
    2810              :             END IF
    2811              : 
    2812           20 :             IF (tau_f) THEN
    2813            0 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    2814            0 :                CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
    2815            0 :                CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
    2816            0 :                CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
    2817            0 :                CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
    2818              :             END IF
    2819              : 
    2820              :             ! NLCC: prepare rho and drho of the core charge for this KIND
    2821           20 :             donlcc = .FALSE.
    2822           20 :             IF (nlcc) THEN
    2823            0 :                NULLIFY (rho_nlcc)
    2824            0 :                rho_nlcc => my_kind_set(ikind)%nlcc_pot
    2825            0 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
    2826              :             END IF
    2827              : 
    2828              :             ! Distribute the atoms of this kind
    2829              : 
    2830           20 :             num_pe = para_env%num_pe
    2831           20 :             bo = get_limit(natom, para_env%num_pe, para_env%mepos)
    2832              : 
    2833           35 :             DO iat = bo(1), bo(2)
    2834           15 :                iatom = atom_list(iat)
    2835              : 
    2836           15 :                my_rho_atom_set(iatom)%exc_h = 0.0_dp
    2837           15 :                my_rho_atom_set(iatom)%exc_s = 0.0_dp
    2838              : 
    2839           15 :                rho_atom => my_rho_atom_set(iatom)
    2840        76545 :                rho_h = 0.0_dp
    2841        76545 :                rho_s = 0.0_dp
    2842              :                IF (gradient_f) THEN
    2843           15 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    2844              :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
    2845              :                                     rho_rad_s=r_s, drho_rad_h=dr_h, &
    2846              :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
    2847           15 :                                     rho_rad_s_d=r_s_d)
    2848       376545 :                   drho_h = 0.0_dp
    2849       376545 :                   drho_s = 0.0_dp
    2850              :                ELSE
    2851              :                   NULLIFY (r_h, r_s)
    2852              :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    2853              :                   rho_d = 0.0_dp
    2854              :                END IF
    2855           15 :                IF (tau_f) THEN
    2856              :                   !compute tau on the grid all at once
    2857            0 :                   CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
    2858              :                ELSE
    2859           15 :                   tau_d = 0.0_dp
    2860              :                END IF
    2861              : 
    2862          765 :                DO ir = 1, nr
    2863              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    2864              :                                         ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
    2865          750 :                                         r_h_d, r_s_d, drho_h, drho_s)
    2866          765 :                   IF (donlcc) THEN
    2867              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
    2868            0 :                                         ir, rho_nlcc(:, 1), rho_h, rho_s, rho_nlcc(:, 2), drho_h, drho_s)
    2869              :                   END IF
    2870              :                END DO
    2871          765 :                DO ir = 1, nr
    2872          765 :                   IF (tau_f) THEN
    2873            0 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
    2874            0 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
    2875              :                   ELSE IF (gradient_f) THEN
    2876          750 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
    2877          750 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
    2878              :                   ELSE
    2879              :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
    2880              :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
    2881              :                   END IF
    2882              :                END DO
    2883              : 
    2884              :                !-------------------!
    2885              :                ! hard atom density !
    2886              :                !-------------------!
    2887           15 :                CALL xc_dset_zero_all(deriv_set)
    2888              :                CALL vxc_of_r_epr(xc_fun_section, rho_set_h, deriv_set, needs, weight_h, &
    2889           15 :                                  lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h)
    2890           15 :                rho_atom%exc_h = rho_atom%exc_h + exc_h
    2891              : 
    2892              :                !-------------------!
    2893              :                ! soft atom density !
    2894              :                !-------------------!
    2895           15 :                CALL xc_dset_zero_all(deriv_set)
    2896              :                CALL vxc_of_r_epr(xc_fun_section, rho_set_s, deriv_set, needs, weight_s, &
    2897           15 :                                  lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s)
    2898           15 :                rho_atom%exc_s = rho_atom%exc_s + exc_s
    2899              : 
    2900           45 :                DO ispin = 1, nspins
    2901          135 :                   DO idir = 1, 3
    2902         4620 :                      DO ir = 1, nr
    2903       229590 :                         DO ia = 1, na
    2904              :                            gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) = &
    2905              :                               gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) &
    2906       225000 :                               + vxg_h(idir, ia, ir, ispin)
    2907              :                            gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) = &
    2908              :                               gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) &
    2909       229500 :                               + vxg_s(idir, ia, ir, ispin)
    2910              :                         END DO ! ia
    2911              :                      END DO ! ir
    2912              :                   END DO ! idir
    2913              :                END DO ! ispin
    2914              : 
    2915              :                ! Add contributions to the exc energy
    2916              : 
    2917           15 :                exc1 = exc1 + rho_atom%exc_h - rho_atom%exc_s
    2918              : 
    2919              :                ! Integration to get the matrix elements relative to the vxc_atom
    2920              :                ! here the products with the primitives is done: gaVxcgb
    2921              :                ! internal transformation to get the integral in cartesian Gaussians
    2922              : 
    2923           15 :                NULLIFY (int_hh, int_ss)
    2924           15 :                CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    2925              :                IF (gradient_f) THEN
    2926              :                   CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    2927           15 :                                   grid_atom, basis_1c, harmonics, nspins)
    2928              :                ELSE
    2929              :                   CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
    2930              :                                     grid_atom, basis_1c, harmonics, nspins)
    2931              :                END IF
    2932           15 :                IF (tau_f) THEN
    2933              :                   CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
    2934            0 :                                   tau_basis_cache, nspins)
    2935              :                END IF
    2936           35 :                NULLIFY (r_h, r_s, dr_h, dr_s)
    2937              :             END DO ! iat
    2938              : 
    2939           20 :             IF (tau_f) CALL release_tau_basis_cache(tau_basis_cache)
    2940              : 
    2941              :             ! Release the xc structure used to store the xc derivatives
    2942           20 :             CALL xc_dset_release(deriv_set)
    2943           20 :             CALL xc_rho_set_release(rho_set_h)
    2944           70 :             CALL xc_rho_set_release(rho_set_s)
    2945              :          END DO ! ikind
    2946              : 
    2947           10 :          CALL para_env%sum(exc1)
    2948              : 
    2949           10 :          IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
    2950           10 :          IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
    2951           10 :          IF (ASSOCIATED(vxc_h)) DEALLOCATE (vxc_h)
    2952           10 :          IF (ASSOCIATED(vxc_s)) DEALLOCATE (vxc_s)
    2953              : 
    2954              :          IF (gradient_f) THEN
    2955           10 :             IF (ASSOCIATED(drho_h)) DEALLOCATE (drho_h)
    2956           10 :             IF (ASSOCIATED(drho_s)) DEALLOCATE (drho_s)
    2957           10 :             IF (ASSOCIATED(vxg_h)) DEALLOCATE (vxg_h)
    2958           10 :             IF (ASSOCIATED(vxg_s)) DEALLOCATE (vxg_s)
    2959              :          END IF
    2960              : 
    2961           10 :          IF (tau_f) THEN
    2962            0 :             IF (ASSOCIATED(tau_h)) DEALLOCATE (tau_h)
    2963            0 :             IF (ASSOCIATED(tau_s)) DEALLOCATE (tau_s)
    2964            0 :             IF (ASSOCIATED(vtau_h)) DEALLOCATE (vtau_h)
    2965            0 :             IF (ASSOCIATED(vtau_s)) DEALLOCATE (vtau_s)
    2966              :          END IF
    2967              : 
    2968              :       END IF !xc_none
    2969              : 
    2970           10 :       CALL timestop(handle)
    2971              : 
    2972          380 :    END SUBROUTINE calculate_vxc_atom_epr
    2973              : 
    2974              : ! **************************************************************************************************
    2975              : !> \brief ...
    2976              : !> \param rho_atom_set ...
    2977              : !> \param rho1_atom_set ...
    2978              : !> \param qs_env ...
    2979              : !> \param xc_section ...
    2980              : !> \param para_env ...
    2981              : !> \param do_tddfpt2 New implementation of TDDFT.
    2982              : !> \param do_triplet ...
    2983              : !> \param do_sf ...
    2984              : !> \param kind_set_external ...
    2985              : ! **************************************************************************************************
    2986         6130 :    SUBROUTINE calculate_xc_2nd_deriv_atom(rho_atom_set, rho1_atom_set, qs_env, xc_section, para_env, &
    2987              :                                           do_tddfpt2, do_triplet, do_sf, kind_set_external)
    2988              : 
    2989              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho_atom_set, rho1_atom_set
    2990              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2991              :       TYPE(section_vals_type), POINTER                   :: xc_section
    2992              :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env
    2993              :       LOGICAL, INTENT(IN), OPTIONAL                      :: do_tddfpt2, do_triplet, do_sf
    2994              :       TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
    2995              :          POINTER                                         :: kind_set_external
    2996              : 
    2997              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_xc_2nd_deriv_atom'
    2998              : 
    2999              :       INTEGER                                            :: atom, handle, iatom, ikind, ir, na, &
    3000              :                                                             natom, nr, nspins
    3001              :       INTEGER, DIMENSION(2)                              :: local_loop_limit
    3002              :       INTEGER, DIMENSION(2, 3)                           :: bounds
    3003         6130 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
    3004              :       LOGICAL                                            :: accint, gradient_functional, lsd, &
    3005              :                                                             my_do_sf, paw_atom, scale_rho, tau_f
    3006              :       REAL(KIND=dp)                                      :: agr, alpha, density_cut, gradient_cut, &
    3007              :                                                             rtot, tau_cut
    3008              :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), &
    3009         6130 :          POINTER                                         :: vtau_h, vtau_s, vxc_h, vxc_s
    3010              :       REAL(KIND=dp), DIMENSION(1, 1, 1)                  :: rtau
    3011              :       REAL(KIND=dp), DIMENSION(1, 1, 1, 1)               :: rrho
    3012         6130 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: weight_h, weight_s
    3013        18390 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: rho1_h, rho1_s, rho_h, rho_s, tau1_h, &
    3014         6130 :                                                             tau1_s, tau_h, tau_s
    3015        12260 :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: drho1_h, drho1_s, drho_h, drho_s, vxg_h, &
    3016         6130 :                                                             vxg_s
    3017         6130 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3018              :       TYPE(dft_control_type), POINTER                    :: dft_control
    3019              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    3020              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    3021              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    3022         6130 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: my_kind_set, qs_kind_set
    3023         6130 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr1_h, dr1_s, dr_h, dr_s, int_hh, &
    3024         6130 :                                                             int_ss, r1_h, r1_s, r_h, r_s
    3025         6130 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r1_h_d, r1_s_d, r_h_d, r_s_d
    3026              :       TYPE(rho_atom_type), POINTER                       :: rho1_atom, rho_atom
    3027              :       TYPE(section_vals_type), POINTER                   :: input, xc_fun_section
    3028         6130 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
    3029              :       TYPE(xc_derivative_set_type)                       :: deriv_set
    3030              :       TYPE(xc_rho_cflags_type)                           :: needs
    3031              :       TYPE(xc_rho_set_type)                              :: rho1_set_h, rho1_set_s, rho_set_h, &
    3032              :                                                             rho_set_s
    3033              : 
    3034              : ! -------------------------------------------------------------------------
    3035              : 
    3036         6130 :       CALL timeset(routineN, handle)
    3037              : 
    3038         6130 :       NULLIFY (qs_kind_set)
    3039         6130 :       NULLIFY (rho_h, rho_s, drho_h, drho_s, weight_h, weight_s)
    3040         6130 :       NULLIFY (rho1_h, rho1_s, drho1_h, drho1_s)
    3041         6130 :       NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
    3042         6130 :       NULLIFY (tau_h, tau_s, tau1_h, tau1_s, vtau_h, vtau_s)
    3043              : 
    3044              :       CALL get_qs_env(qs_env=qs_env, &
    3045              :                       input=input, &
    3046              :                       dft_control=dft_control, &
    3047              :                       qs_kind_set=qs_kind_set, &
    3048         6130 :                       atomic_kind_set=atomic_kind_set)
    3049              : 
    3050         6130 :       IF (PRESENT(kind_set_external)) THEN
    3051          726 :          my_kind_set => kind_set_external
    3052              :       ELSE
    3053         5404 :          my_kind_set => qs_kind_set
    3054              :       END IF
    3055              : 
    3056         6130 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
    3057              : 
    3058         6130 :       CALL section_vals_val_get(input, "DFT%LSD", l_val=lsd)
    3059              :       CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", &
    3060         6130 :                                 r_val=density_cut)
    3061              :       CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", &
    3062         6130 :                                 r_val=gradient_cut)
    3063              :       CALL section_vals_val_get(xc_section, "TAU_CUTOFF", &
    3064         6130 :                                 r_val=tau_cut)
    3065              : 
    3066         6130 :       my_do_sf = .FALSE.
    3067         6130 :       IF (PRESENT(do_sf)) my_do_sf = do_sf
    3068              : 
    3069              :       xc_fun_section => section_vals_get_subs_vals(xc_section, &
    3070         6130 :                                                    "XC_FUNCTIONAL")
    3071         6130 :       IF (lsd) THEN
    3072          190 :          nspins = 2
    3073              :       ELSE
    3074         5940 :          nspins = 1
    3075              :       END IF
    3076              : 
    3077         6130 :       scale_rho = .FALSE.
    3078         6130 :       IF (PRESENT(do_tddfpt2) .AND. PRESENT(do_triplet)) THEN
    3079         2864 :          IF (nspins == 1 .AND. do_triplet) THEN
    3080          310 :             lsd = .TRUE.
    3081          310 :             scale_rho = .TRUE.
    3082              :          END IF
    3083         3266 :       ELSE IF (PRESENT(do_triplet)) THEN
    3084         2858 :          IF (nspins == 1 .AND. do_triplet) lsd = .TRUE.
    3085              :       END IF
    3086              : 
    3087              :       needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, &
    3088         6130 :                                        calc_potential=.TRUE.)
    3089         6130 :       gradient_functional = needs%drho .OR. needs%drho_spin
    3090         6130 :       tau_f = (needs%tau .OR. needs%tau_spin)
    3091         6130 :       IF (.NOT. tau_f) rtau = 0.0_dp
    3092              : 
    3093              :       !  Here starts the loop over all the atoms
    3094        19524 :       DO ikind = 1, SIZE(atomic_kind_set)
    3095              : 
    3096        13394 :          NULLIFY (atom_list, harmonics, grid_atom)
    3097        13394 :          CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    3098              :          CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
    3099        13394 :                           harmonics=harmonics, grid_atom=grid_atom)
    3100        13394 :          CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    3101        13394 :          IF (.NOT. paw_atom) CYCLE
    3102              : 
    3103        12576 :          nr = grid_atom%nr
    3104        12576 :          na = grid_atom%ng_sphere
    3105              : 
    3106              :          ! set integration weights
    3107        12576 :          IF (accint) THEN
    3108         4772 :             weight_h => grid_atom%weight
    3109         4772 :             alpha = dft_control%qs_control%gapw_control%aw(ikind)
    3110         4772 :             IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    3111         4768 :                IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
    3112              :             END IF
    3113         4772 :             IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    3114           16 :                ALLOCATE (grid_atom%gapw_weight_s(na, nr))
    3115          204 :                DO ir = 1, nr
    3116          200 :                   agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
    3117        10204 :                   grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
    3118              :                END DO
    3119            4 :                grid_atom%gapw_weight_alpha = alpha
    3120              :             END IF
    3121         4772 :             weight_s => grid_atom%gapw_weight_s
    3122              :          ELSE
    3123         7804 :             weight_h => grid_atom%weight
    3124         7804 :             weight_s => grid_atom%weight
    3125              :          END IF
    3126              : 
    3127              :          ! Array dimension: here anly one dimensional arrays are used,
    3128              :          ! i.e. only the first column of deriv_data is read.
    3129              :          ! The other to dimensions  are set to size equal 1.
    3130       125760 :          bounds(1:2, 1:3) = 1
    3131        12576 :          bounds(2, 1) = na
    3132        12576 :          bounds(2, 2) = nr
    3133              : 
    3134        12576 :          CALL xc_dset_create(deriv_set, local_bounds=bounds)
    3135              :          CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
    3136        12576 :                                 drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3137              :          CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
    3138        12576 :                                 drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3139              :          CALL xc_rho_set_create(rho1_set_h, bounds, rho_cutoff=density_cut, &
    3140        12576 :                                 drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3141              :          CALL xc_rho_set_create(rho1_set_s, bounds, rho_cutoff=density_cut, &
    3142        12576 :                                 drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3143              : 
    3144              :          ! allocate the required 3d arrays where to store rho and drho
    3145        12576 :          IF (nspins == 1 .AND. .NOT. lsd) THEN
    3146        11714 :             CALL xc_rho_set_atom_update(rho_set_h, needs, 1, bounds)
    3147        11714 :             CALL xc_rho_set_atom_update(rho1_set_h, needs, 1, bounds)
    3148        11714 :             CALL xc_rho_set_atom_update(rho_set_s, needs, 1, bounds)
    3149        11714 :             CALL xc_rho_set_atom_update(rho1_set_s, needs, 1, bounds)
    3150              :          ELSE
    3151          862 :             CALL xc_rho_set_atom_update(rho_set_h, needs, 2, bounds)
    3152          862 :             CALL xc_rho_set_atom_update(rho1_set_h, needs, 2, bounds)
    3153          862 :             CALL xc_rho_set_atom_update(rho_set_s, needs, 2, bounds)
    3154          862 :             CALL xc_rho_set_atom_update(rho1_set_s, needs, 2, bounds)
    3155              :          END IF
    3156              : 
    3157              :          ALLOCATE (rho_h(1:na, 1:nr, 1:nspins), rho1_h(1:na, 1:nr, 1:nspins), &
    3158       176064 :                    rho_s(1:na, 1:nr, 1:nspins), rho1_s(1:na, 1:nr, 1:nspins))
    3159              : 
    3160        88032 :          ALLOCATE (vxc_h(1:na, 1:nr, 1:nspins), vxc_s(1:na, 1:nr, 1:nspins))
    3161        12576 :          vxc_h = 0.0_dp
    3162        12576 :          vxc_s = 0.0_dp
    3163              : 
    3164        12576 :          IF (tau_f) THEN
    3165            0 :             CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    3166              :             ALLOCATE (tau_h(1:na, 1:nr, 1:nspins), tau1_h(1:na, 1:nr, 1:nspins), &
    3167            0 :                       tau_s(1:na, 1:nr, 1:nspins), tau1_s(1:na, 1:nr, 1:nspins))
    3168            0 :             ALLOCATE (vtau_h(1:na, 1:nr, 1:nspins), vtau_s(1:na, 1:nr, 1:nspins))
    3169              :          END IF
    3170              : 
    3171        12576 :          IF (gradient_functional) THEN
    3172              :             ALLOCATE (drho_h(1:4, 1:na, 1:nr, 1:nspins), drho1_h(1:4, 1:na, 1:nr, 1:nspins), &
    3173       127148 :                       drho_s(1:4, 1:na, 1:nr, 1:nspins), drho1_s(1:4, 1:na, 1:nr, 1:nspins))
    3174        72656 :             ALLOCATE (vxg_h(1:3, 1:na, 1:nr, 1:nspins), vxg_s(1:3, 1:na, 1:nr, 1:nspins))
    3175              :          ELSE
    3176              :             ALLOCATE (drho_h(1, 1, 1, 1), drho1_h(1, 1, 1, 1), &
    3177         3494 :                       drho_s(1, 1, 1, 1), drho1_s(1, 1, 1, 1))
    3178         3494 :             ALLOCATE (vxg_h(1, 1, 1, 1), vxg_s(1, 1, 1, 1))
    3179         3494 :             rrho = 0.0_dp
    3180              :          END IF
    3181     94325034 :          vxg_h = 0.0_dp
    3182     94325034 :          vxg_s = 0.0_dp
    3183              : 
    3184              :          ! parallelization
    3185        12576 :          local_loop_limit = get_limit(natom, para_env%num_pe, para_env%mepos)
    3186              : 
    3187        21505 :          DO iatom = local_loop_limit(1), local_loop_limit(2) !1,natom
    3188         8929 :             atom = atom_list(iatom)
    3189              : 
    3190         8929 :             rho_atom_set(atom)%exc_h = 0.0_dp
    3191         8929 :             rho_atom_set(atom)%exc_s = 0.0_dp
    3192         8929 :             rho1_atom_set(atom)%exc_h = 0.0_dp
    3193         8929 :             rho1_atom_set(atom)%exc_s = 0.0_dp
    3194              : 
    3195         8929 :             rho_atom => rho_atom_set(atom)
    3196         8929 :             rho1_atom => rho1_atom_set(atom)
    3197         8929 :             NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    3198         8929 :             NULLIFY (r1_h, r1_s, dr1_h, dr1_s, r1_h_d, r1_s_d)
    3199     23424558 :             rho_h = 0.0_dp
    3200     23424558 :             rho_s = 0.0_dp
    3201     23424558 :             rho1_h = 0.0_dp
    3202     23424558 :             rho1_s = 0.0_dp
    3203         8929 :             IF (gradient_functional) THEN
    3204              :                CALL get_rho_atom(rho_atom=rho_atom, &
    3205              :                                  rho_rad_h=r_h, rho_rad_s=r_s, &
    3206              :                                  drho_rad_h=dr_h, drho_rad_s=dr_s, &
    3207         6480 :                                  rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    3208              :                CALL get_rho_atom(rho_atom=rho1_atom, &
    3209              :                                  rho_rad_h=r1_h, rho_rad_s=r1_s, &
    3210              :                                  drho_rad_h=dr1_h, drho_rad_s=dr1_s, &
    3211         6480 :                                  rho_rad_h_d=r1_h_d, rho_rad_s_d=r1_s_d)
    3212    168691920 :                drho_h = 0.0_dp; drho_s = 0.0_dp
    3213    168691920 :                drho1_h = 0.0_dp; drho1_s = 0.0_dp
    3214              :             ELSE
    3215              :                CALL get_rho_atom(rho_atom=rho_atom, &
    3216         2449 :                                  rho_rad_h=r_h, rho_rad_s=r_s)
    3217              :                CALL get_rho_atom(rho_atom=rho1_atom, &
    3218         2449 :                                  rho_rad_h=r1_h, rho_rad_s=r1_s)
    3219              :             END IF
    3220              : 
    3221         8929 :             rtot = 0.0_dp
    3222              : 
    3223       455379 :             DO ir = 1, nr
    3224              :                CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_functional, &
    3225              :                                      ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, r_h_d, r_s_d, &
    3226       446450 :                                      drho_h, drho_s)
    3227              :                CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_functional, &
    3228              :                                      ir, r1_h, r1_s, rho1_h, rho1_s, dr1_h, dr1_s, r1_h_d, r1_s_d, &
    3229       455379 :                                      drho1_h, drho1_s)
    3230              :             END DO
    3231         8929 :             IF (tau_f) THEN
    3232            0 :                CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
    3233            0 :                CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, tau_basis_cache, nspins)
    3234              :             END IF
    3235         8929 :             IF (scale_rho) THEN
    3236       926376 :                rho_h = 2.0_dp*rho_h
    3237       926376 :                rho_s = 2.0_dp*rho_s
    3238          363 :                IF (gradient_functional) THEN
    3239      3426696 :                   drho_h = 2.0_dp*drho_h
    3240      3426696 :                   drho_s = 2.0_dp*drho_s
    3241              :                END IF
    3242          363 :                IF (tau_f) THEN
    3243            0 :                   tau_h = 2.0_dp*tau_h
    3244            0 :                   tau_s = 2.0_dp*tau_s
    3245              :                END IF
    3246              :             END IF
    3247              : 
    3248       455379 :             DO ir = 1, nr
    3249       455379 :                IF (tau_f) THEN
    3250            0 :                   CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
    3251            0 :                   CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau1_h, na, ir)
    3252            0 :                   CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
    3253            0 :                   CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau1_s, na, ir)
    3254       446450 :                ELSE IF (gradient_functional) THEN
    3255       324000 :                   CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, rtau, na, ir)
    3256       324000 :                   CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, rtau, na, ir)
    3257       324000 :                   CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, rtau, na, ir)
    3258       324000 :                   CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, rtau, na, ir)
    3259              :                ELSE
    3260       122450 :                   CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rrho, rtau, na, ir)
    3261       122450 :                   CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, rrho, rtau, na, ir)
    3262       122450 :                   CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rrho, rtau, na, ir)
    3263       122450 :                   CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, rrho, rtau, na, ir)
    3264              :                END IF
    3265              :             END DO
    3266              : 
    3267              :             CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
    3268              :                                    rho_set=rho_set_h, rho1_set=rho1_set_h, &
    3269              :                                    deriv_set=deriv_set, &
    3270              :                                    w=weight_h, vxc=vxc_h, vxg=vxg_h, vtau=vtau_h, do_triplet=do_triplet, &
    3271         8929 :                                    do_sf=my_do_sf)
    3272              :             CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
    3273              :                                    rho_set=rho_set_s, rho1_set=rho1_set_s, &
    3274              :                                    deriv_set=deriv_set, &
    3275              :                                    w=weight_s, vxc=vxc_s, vxg=vxg_s, vtau=vtau_s, do_triplet=do_triplet, &
    3276         8929 :                                    do_sf=my_do_sf)
    3277              : 
    3278         8929 :             CALL get_rho_atom(rho_atom=rho1_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    3279         8929 :             IF (gradient_functional) THEN
    3280              :                CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    3281         6480 :                                grid_atom, basis_1c, harmonics, nspins)
    3282              :             ELSE
    3283              :                CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
    3284         2449 :                                  grid_atom, basis_1c, harmonics, nspins)
    3285              :             END IF
    3286         8929 :             IF (tau_f) THEN
    3287              :                CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
    3288            0 :                                tau_basis_cache, nspins)
    3289              :             END IF
    3290              : 
    3291        21505 :             NULLIFY (r_h, r_s, dr_h, dr_s)
    3292              : 
    3293              :          END DO
    3294              : 
    3295              :          ! some cleanup
    3296        12576 :          DEALLOCATE (rho_h, rho_s, rho1_h, rho1_s, vxc_h, vxc_s)
    3297        12576 :          DEALLOCATE (drho_h, drho_s, vxg_h, vxg_s)
    3298        12576 :          DEALLOCATE (drho1_h, drho1_s)
    3299        12576 :          IF (tau_f) THEN
    3300            0 :             DEALLOCATE (tau_h, tau_s, tau1_h, tau1_s)
    3301            0 :             DEALLOCATE (vtau_h, vtau_s)
    3302            0 :             CALL release_tau_basis_cache(tau_basis_cache)
    3303              :          END IF
    3304              : 
    3305        12576 :          CALL xc_dset_release(deriv_set)
    3306        12576 :          CALL xc_rho_set_release(rho_set_h)
    3307        12576 :          CALL xc_rho_set_release(rho1_set_h)
    3308        12576 :          CALL xc_rho_set_release(rho_set_s)
    3309        45494 :          CALL xc_rho_set_release(rho1_set_s)
    3310              :       END DO
    3311              : 
    3312         6130 :       CALL timestop(handle)
    3313              : 
    3314       453620 :    END SUBROUTINE calculate_xc_2nd_deriv_atom
    3315              : 
    3316              : ! **************************************************************************************************
    3317              : !> \brief ...
    3318              : !> \param qs_env ...
    3319              : !> \param rho0_atom_set ...
    3320              : !> \param rho1_atom_set ...
    3321              : !> \param rho2_atom_set ...
    3322              : !> \param kind_set ...
    3323              : !> \param xc_section ...
    3324              : !> \param is_triplet ...
    3325              : !> \param accuracy ...
    3326              : ! **************************************************************************************************
    3327            0 :    SUBROUTINE calculate_gfxc_atom(qs_env, rho0_atom_set, rho1_atom_set, rho2_atom_set, &
    3328              :                                   kind_set, xc_section, is_triplet, accuracy)
    3329              : 
    3330              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3331              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set, rho1_atom_set, &
    3332              :                                                             rho2_atom_set
    3333              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: kind_set
    3334              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: xc_section
    3335              :       LOGICAL, INTENT(IN)                                :: is_triplet
    3336              :       INTEGER, INTENT(IN)                                :: accuracy
    3337              : 
    3338              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_gfxc_atom'
    3339              :       REAL(KIND=dp), PARAMETER                           :: epsrho = 5.e-4_dp
    3340              : 
    3341              :       INTEGER                                            :: bo(2), handle, iat, iatom, ikind, ir, &
    3342              :                                                             istep, mspins, myfun, na, natom, nf, &
    3343              :                                                             nr, ns, nspins, nstep, num_pe
    3344              :       INTEGER, DIMENSION(2, 3)                           :: bounds
    3345            0 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
    3346              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
    3347              :                                                             paw_atom, tau_f
    3348              :       REAL(dp)                                           :: agr, alpha, beta, density_cut, exc_h, &
    3349              :                                                             exc_s, gradient_cut, oeps1, oeps2, &
    3350              :                                                             tau_cut
    3351              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
    3352              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
    3353            0 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
    3354            0 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho0_h, rho0_s, rho1_h, rho1_s, rho_h, &
    3355            0 :                                                             rho_s, tau0_h, tau0_s, tau1_h, tau1_s, &
    3356            0 :                                                             tau_h, tau_s, vtau_h, vtau_s, vxc_h, &
    3357            0 :                                                             vxc_s
    3358            0 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho0_h, drho0_s, drho1_h, drho1_s, &
    3359            0 :                                                             drho_h, drho_s, vxg_h, vxg_s
    3360              :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak, bl
    3361            0 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3362              :       TYPE(dft_control_type), POINTER                    :: dft_control
    3363              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    3364              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    3365              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    3366              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3367            0 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, fint_hh, fint_ss, int_hh, &
    3368            0 :                                                             int_ss, r_h, r_s
    3369            0 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    3370              :       TYPE(rho_atom_type), POINTER                       :: rho0_atom, rho1_atom, rho2_atom
    3371              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
    3372            0 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
    3373              :       TYPE(xc_derivative_set_type)                       :: deriv_set
    3374              :       TYPE(xc_rho_cflags_type)                           :: needs
    3375              :       TYPE(xc_rho_set_type)                              :: rho_set_h, rho_set_s
    3376              : 
    3377            0 :       CALL timeset(routineN, handle)
    3378              : 
    3379            0 :       NULLIFY (vtau_h, vtau_s)
    3380              : 
    3381            0 :       ak = 0.0_dp
    3382            0 :       bl = 0.0_dp
    3383            0 :       SELECT CASE (accuracy)
    3384              :       CASE (:4)
    3385            0 :          nstep = 2
    3386            0 :          ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
    3387            0 :          bl(-2:2) = [-1.0_dp, 16.0_dp, -30.0_dp, 16.0_dp, -1.0_dp]/12.0_dp
    3388              :       CASE (5:7)
    3389            0 :          nstep = 3
    3390            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
    3391            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
    3392              :       CASE (8:)
    3393            0 :          nstep = 4
    3394              :          ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
    3395            0 :                      224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
    3396              :          bl(-4:4) = [-1.0_dp, 128.0_dp/9.0_dp, -112.0_dp, 896.0_dp, -14350.0_dp/9.0_dp, &
    3397            0 :                      896.0_dp, -112.0_dp, 128.0_dp/9.0_dp, -1.0_dp]/560.0_dp
    3398              :       END SELECT
    3399            0 :       oeps1 = 1.0_dp/epsrho
    3400            0 :       oeps2 = 1.0_dp/(epsrho**2)
    3401              : 
    3402              :       CALL get_qs_env(qs_env=qs_env, &
    3403              :                       dft_control=dft_control, &
    3404              :                       para_env=para_env, &
    3405            0 :                       atomic_kind_set=atomic_kind_set)
    3406              : 
    3407            0 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
    3408            0 :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", i_val=myfun)
    3409              : 
    3410            0 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
    3411              : 
    3412            0 :       IF (myfun == xc_none) THEN
    3413              :          ! no action needed?
    3414              :       ELSE
    3415            0 :          CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", r_val=density_cut)
    3416            0 :          CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", r_val=gradient_cut)
    3417            0 :          CALL section_vals_val_get(xc_section, "TAU_CUTOFF", r_val=tau_cut)
    3418              : 
    3419            0 :          nlcc = has_nlcc(kind_set)
    3420            0 :          lsd = dft_control%lsd
    3421            0 :          nspins = dft_control%nspins
    3422            0 :          mspins = nspins
    3423            0 :          IF (is_triplet) THEN
    3424            0 :             CPASSERT(nspins == 1)
    3425            0 :             lsd = .TRUE.
    3426            0 :             mspins = 2
    3427              :          END IF
    3428            0 :          needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, calc_potential=.TRUE.)
    3429            0 :          gradient_f = (needs%drho .OR. needs%drho_spin)
    3430            0 :          tau_f = (needs%tau .OR. needs%tau_spin)
    3431              : 
    3432              :          ! Here starts the loop over all the atoms
    3433            0 :          DO ikind = 1, SIZE(atomic_kind_set)
    3434            0 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    3435              :             CALL get_qs_kind(kind_set(ikind), paw_atom=paw_atom, &
    3436            0 :                              harmonics=harmonics, grid_atom=grid_atom)
    3437            0 :             CALL get_qs_kind(kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    3438              : 
    3439            0 :             IF (.NOT. paw_atom) CYCLE
    3440              : 
    3441            0 :             nr = grid_atom%nr
    3442            0 :             na = grid_atom%ng_sphere
    3443              : 
    3444              :             ! set integration weights
    3445            0 :             IF (accint) THEN
    3446            0 :                weight_h => grid_atom%weight
    3447            0 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
    3448            0 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    3449            0 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
    3450              :                END IF
    3451            0 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    3452            0 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
    3453            0 :                   DO ir = 1, nr
    3454            0 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
    3455            0 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
    3456              :                   END DO
    3457            0 :                   grid_atom%gapw_weight_alpha = alpha
    3458              :                END IF
    3459            0 :                weight_s => grid_atom%gapw_weight_s
    3460              :             ELSE
    3461            0 :                weight_h => grid_atom%weight
    3462            0 :                weight_s => grid_atom%weight
    3463              :             END IF
    3464              : 
    3465              :             ! Prepare the structures needed to calculate and store the xc derivatives
    3466              : 
    3467              :             ! Array dimension: here anly one dimensional arrays are used,
    3468              :             ! i.e. only the first column of deriv_data is read.
    3469              :             ! The other to dimensions  are set to size equal 1
    3470            0 :             bounds(1:2, 1:3) = 1
    3471            0 :             bounds(2, 1) = na
    3472            0 :             bounds(2, 2) = nr
    3473              : 
    3474              :             ! create a place where to put the derivatives
    3475            0 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
    3476              :             ! create the place where to store the argument for the functionals
    3477              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
    3478            0 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3479              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
    3480            0 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3481              : 
    3482              :             ! allocate the required 3d arrays where to store rho and drho
    3483            0 :             CALL xc_rho_set_atom_update(rho_set_h, needs, mspins, bounds)
    3484            0 :             CALL xc_rho_set_atom_update(rho_set_s, needs, mspins, bounds)
    3485              : 
    3486              :             ALLOCATE (rho_h(na, nr, mspins), rho_s(na, nr, mspins), &
    3487              :                       rho0_h(na, nr, nspins), rho0_s(na, nr, nspins), &
    3488            0 :                       rho1_h(na, nr, nspins), rho1_s(na, nr, nspins))
    3489            0 :             ALLOCATE (vxc_h(na, nr, mspins), vxc_s(na, nr, mspins))
    3490            0 :             IF (gradient_f) THEN
    3491              :                ALLOCATE (drho_h(4, na, nr, mspins), drho_s(4, na, nr, mspins), &
    3492              :                          drho0_h(4, na, nr, nspins), drho0_s(4, na, nr, nspins), &
    3493            0 :                          drho1_h(4, na, nr, nspins), drho1_s(4, na, nr, nspins))
    3494            0 :                ALLOCATE (vxg_h(3, na, nr, mspins), vxg_s(3, na, nr, mspins))
    3495              :             END IF
    3496            0 :             IF (tau_f) THEN
    3497            0 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    3498              :                ALLOCATE (tau_h(na, nr, mspins), tau_s(na, nr, mspins), &
    3499              :                          tau0_h(na, nr, nspins), tau0_s(na, nr, nspins), &
    3500            0 :                          tau1_h(na, nr, nspins), tau1_s(na, nr, nspins))
    3501            0 :                ALLOCATE (vtau_h(na, nr, mspins), vtau_s(na, nr, mspins))
    3502              :             END IF
    3503              :             !
    3504              :             ! NLCC: prepare rho and drho of the core charge for this KIND
    3505            0 :             donlcc = .FALSE.
    3506            0 :             IF (nlcc) THEN
    3507            0 :                NULLIFY (rho_nlcc)
    3508            0 :                rho_nlcc => kind_set(ikind)%nlcc_pot
    3509            0 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
    3510              :             END IF
    3511              : 
    3512              :             ! Distribute the atoms of this kind
    3513            0 :             num_pe = para_env%num_pe
    3514            0 :             bo = get_limit(natom, num_pe, para_env%mepos)
    3515              : 
    3516            0 :             DO iat = bo(1), bo(2)
    3517            0 :                iatom = atom_list(iat)
    3518              :                !
    3519            0 :                NULLIFY (int_hh, int_ss)
    3520            0 :                rho0_atom => rho0_atom_set(iatom)
    3521            0 :                CALL get_rho_atom(rho_atom=rho0_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    3522            0 :                ALLOCATE (fint_ss(nspins), fint_hh(nspins))
    3523            0 :                DO ns = 1, nspins
    3524            0 :                   nf = SIZE(int_ss(ns)%r_coef, 1)
    3525            0 :                   ALLOCATE (fint_ss(ns)%r_coef(nf, nf))
    3526            0 :                   nf = SIZE(int_hh(ns)%r_coef, 1)
    3527            0 :                   ALLOCATE (fint_hh(ns)%r_coef(nf, nf))
    3528              :                END DO
    3529              : 
    3530              :                ! RHO0
    3531            0 :                rho0_h = 0.0_dp
    3532            0 :                rho0_s = 0.0_dp
    3533            0 :                rho0_atom => rho0_atom_set(iatom)
    3534            0 :                IF (gradient_f) THEN
    3535            0 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    3536              :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    3537            0 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    3538            0 :                   drho0_h = 0.0_dp
    3539            0 :                   drho0_s = 0.0_dp
    3540              :                ELSE
    3541            0 :                   NULLIFY (r_h, r_s)
    3542            0 :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    3543            0 :                   rho_d = 0.0_dp
    3544              :                END IF
    3545            0 :                DO ir = 1, nr
    3546              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    3547              :                                         ir, r_h, r_s, rho0_h, rho0_s, dr_h, dr_s, &
    3548            0 :                                         r_h_d, r_s_d, drho0_h, drho0_s)
    3549            0 :                   IF (donlcc) THEN
    3550              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
    3551            0 :                                         ir, rho_nlcc(:, 1), rho0_h, rho0_s, rho_nlcc(:, 2), drho0_h, drho0_s)
    3552              :                   END IF
    3553              :                END DO
    3554            0 :                IF (tau_f) THEN
    3555              :                   !compute tau on the grid all at once
    3556            0 :                   CALL calc_tau_atom(tau0_h, tau0_s, rho0_atom, tau_basis_cache, nspins)
    3557              :                ELSE
    3558            0 :                   tau_d = 0.0_dp
    3559              :                END IF
    3560              :                ! RHO1
    3561            0 :                rho1_h = 0.0_dp
    3562            0 :                rho1_s = 0.0_dp
    3563            0 :                rho1_atom => rho1_atom_set(iatom)
    3564            0 :                IF (gradient_f) THEN
    3565            0 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    3566              :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    3567            0 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    3568            0 :                   drho1_h = 0.0_dp
    3569            0 :                   drho1_s = 0.0_dp
    3570              :                ELSE
    3571            0 :                   NULLIFY (r_h, r_s)
    3572            0 :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    3573              :                END IF
    3574            0 :                DO ir = 1, nr
    3575              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    3576              :                                         ir, r_h, r_s, rho1_h, rho1_s, dr_h, dr_s, &
    3577            0 :                                         r_h_d, r_s_d, drho1_h, drho1_s)
    3578              :                END DO
    3579            0 :                IF (tau_f) THEN
    3580              :                   !compute tau on the grid all at once
    3581            0 :                   CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, tau_basis_cache, nspins)
    3582              :                END IF
    3583              :                ! RHO2
    3584            0 :                rho2_atom => rho2_atom_set(iatom)
    3585              : 
    3586            0 :                DO istep = -nstep, nstep
    3587              : 
    3588            0 :                   beta = REAL(istep, KIND=dp)*epsrho
    3589              : 
    3590            0 :                   IF (is_triplet) THEN
    3591            0 :                      rho_h(:, :, 1) = rho0_h(:, :, 1) + beta*rho1_h(:, :, 1)
    3592            0 :                      rho_h(:, :, 2) = rho0_h(:, :, 1)
    3593            0 :                      rho_h = 0.5_dp*rho_h
    3594            0 :                      rho_s(:, :, 1) = rho0_s(:, :, 1) + beta*rho1_s(:, :, 1)
    3595            0 :                      rho_s(:, :, 2) = rho0_s(:, :, 1)
    3596            0 :                      rho_s = 0.5_dp*rho_s
    3597            0 :                      IF (gradient_f) THEN
    3598            0 :                         drho_h(:, :, :, 1) = drho0_h(:, :, :, 1) + beta*drho1_h(:, :, :, 1)
    3599            0 :                         drho_h(:, :, :, 2) = drho0_h(:, :, :, 1)
    3600            0 :                         drho_h = 0.5_dp*drho_h
    3601            0 :                         drho_s(:, :, :, 1) = drho0_s(:, :, :, 1) + beta*drho1_s(:, :, :, 1)
    3602            0 :                         drho_s(:, :, :, 2) = drho0_s(:, :, :, 1)
    3603            0 :                         drho_s = 0.5_dp*drho_s
    3604              :                      END IF
    3605            0 :                      IF (tau_f) THEN
    3606            0 :                         tau_h(:, :, 1) = tau0_h(:, :, 1) + beta*tau1_h(:, :, 1)
    3607            0 :                         tau_h(:, :, 2) = tau0_h(:, :, 1)
    3608            0 :                         tau_h = 0.5_dp*tau0_h
    3609            0 :                         tau_s(:, :, 1) = tau0_s(:, :, 1) + beta*tau1_s(:, :, 1)
    3610            0 :                         tau_s(:, :, 2) = tau0_s(:, :, 1)
    3611            0 :                         tau_s = 0.5_dp*tau0_s
    3612              :                      END IF
    3613              :                   ELSE
    3614            0 :                      rho_h = rho0_h + beta*rho1_h
    3615            0 :                      rho_s = rho0_s + beta*rho1_s
    3616            0 :                      IF (gradient_f) THEN
    3617            0 :                         drho_h = drho0_h + beta*drho1_h
    3618            0 :                         drho_s = drho0_s + beta*drho1_s
    3619              :                      END IF
    3620            0 :                      IF (tau_f) THEN
    3621            0 :                         tau_h = tau0_h + beta*tau1_h
    3622            0 :                         tau_s = tau0_s + beta*tau1_s
    3623              :                      END IF
    3624              :                   END IF
    3625              :                   !
    3626            0 :                   IF (gradient_f) THEN
    3627              :                      drho_h(4, :, :, :) = SQRT( &
    3628              :                                           drho_h(1, :, :, :)*drho_h(1, :, :, :) + &
    3629              :                                           drho_h(2, :, :, :)*drho_h(2, :, :, :) + &
    3630            0 :                                           drho_h(3, :, :, :)*drho_h(3, :, :, :))
    3631              : 
    3632              :                      drho_s(4, :, :, :) = SQRT( &
    3633              :                                           drho_s(1, :, :, :)*drho_s(1, :, :, :) + &
    3634              :                                           drho_s(2, :, :, :)*drho_s(2, :, :, :) + &
    3635            0 :                                           drho_s(3, :, :, :)*drho_s(3, :, :, :))
    3636              :                   END IF
    3637              : 
    3638            0 :                   DO ir = 1, nr
    3639            0 :                      IF (tau_f) THEN
    3640            0 :                         CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, drho_h, tau_h, na, ir)
    3641            0 :                         CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, drho_s, tau_s, na, ir)
    3642            0 :                      ELSE IF (gradient_f) THEN
    3643            0 :                         CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, drho_h, tau_d, na, ir)
    3644            0 :                         CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, drho_s, tau_d, na, ir)
    3645              :                      ELSE
    3646            0 :                         CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, rho_d, tau_d, na, ir)
    3647            0 :                         CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, rho_d, tau_d, na, ir)
    3648              :                      END IF
    3649              :                   END DO
    3650              : 
    3651              :                   ! hard atom density !
    3652            0 :                   CALL xc_dset_zero_all(deriv_set)
    3653              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_h, deriv_set, 1, needs, weight_h, &
    3654            0 :                                     lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h)
    3655            0 :                   IF (is_triplet) THEN
    3656            0 :                      vxc_h(:, :, 1) = vxc_h(:, :, 1) - vxc_h(:, :, 2)
    3657            0 :                      IF (gradient_f) THEN
    3658            0 :                         vxg_h(:, :, :, 1) = vxg_h(:, :, :, 1) - vxg_h(:, :, :, 2)
    3659              :                      END IF
    3660            0 :                      IF (tau_f) THEN
    3661            0 :                         vtau_h(:, :, 1) = vtau_h(:, :, 1) - vtau_h(:, :, 2)
    3662              :                      END IF
    3663              :                   END IF
    3664              :                   ! soft atom density !
    3665            0 :                   CALL xc_dset_zero_all(deriv_set)
    3666              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_s, deriv_set, 1, needs, weight_s, &
    3667            0 :                                     lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s)
    3668            0 :                   IF (is_triplet) THEN
    3669            0 :                      vxc_s(:, :, 1) = vxc_s(:, :, 1) - vxc_s(:, :, 2)
    3670            0 :                      IF (gradient_f) THEN
    3671            0 :                         vxg_s(:, :, :, 1) = vxg_s(:, :, :, 1) - vxg_s(:, :, :, 2)
    3672              :                      END IF
    3673            0 :                      IF (tau_f) THEN
    3674            0 :                         vtau_s(:, :, 1) = vtau_s(:, :, 1) - vtau_s(:, :, 2)
    3675              :                      END IF
    3676              :                   END IF
    3677              :                   ! potentials
    3678            0 :                   DO ns = 1, nspins
    3679            0 :                      fint_hh(ns)%r_coef(:, :) = 0.0_dp
    3680            0 :                      fint_ss(ns)%r_coef(:, :) = 0.0_dp
    3681              :                   END DO
    3682            0 :                   IF (gradient_f) THEN
    3683              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, fint_hh, fint_ss, &
    3684            0 :                                      grid_atom, basis_1c, harmonics, nspins)
    3685              :                   ELSE
    3686              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, fint_hh, fint_ss, &
    3687            0 :                                        grid_atom, basis_1c, harmonics, nspins)
    3688              :                   END IF
    3689            0 :                   IF (tau_f) THEN
    3690              :                      CALL dgaVtaudgb(vtau_h, vtau_s, fint_hh, fint_ss, &
    3691            0 :                                      tau_basis_cache, nspins)
    3692              :                   END IF
    3693              :                   ! first derivative fxc
    3694            0 :                   NULLIFY (int_hh, int_ss)
    3695            0 :                   CALL get_rho_atom(rho_atom=rho1_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    3696            0 :                   DO ns = 1, nspins
    3697            0 :                      int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_ss(ns)%r_coef(:, :)
    3698            0 :                      int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_hh(ns)%r_coef(:, :)
    3699              :                   END DO
    3700              :                   ! second derivative gxc
    3701            0 :                   NULLIFY (int_hh, int_ss)
    3702            0 :                   CALL get_rho_atom(rho_atom=rho2_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    3703            0 :                   DO ns = 1, nspins
    3704            0 :                      int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps2*bl(istep)*fint_ss(ns)%r_coef(:, :)
    3705            0 :                      int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps2*bl(istep)*fint_hh(ns)%r_coef(:, :)
    3706              :                   END DO
    3707              :                END DO
    3708              :                !
    3709            0 :                DO ns = 1, nspins
    3710            0 :                   DEALLOCATE (fint_ss(ns)%r_coef)
    3711            0 :                   DEALLOCATE (fint_hh(ns)%r_coef)
    3712              :                END DO
    3713            0 :                DEALLOCATE (fint_ss, fint_hh)
    3714              : 
    3715              :             END DO ! iat
    3716              : 
    3717              :             ! Release the xc structure used to store the xc derivatives
    3718            0 :             CALL xc_dset_release(deriv_set)
    3719            0 :             CALL xc_rho_set_release(rho_set_h)
    3720            0 :             CALL xc_rho_set_release(rho_set_s)
    3721              : 
    3722            0 :             DEALLOCATE (rho_h, rho_s, rho0_h, rho0_s, rho1_h, rho1_s)
    3723            0 :             DEALLOCATE (vxc_h, vxc_s)
    3724            0 :             IF (gradient_f) THEN
    3725            0 :                DEALLOCATE (drho_h, drho_s, drho0_h, drho0_s, drho1_h, drho1_s)
    3726            0 :                DEALLOCATE (vxg_h, vxg_s)
    3727              :             END IF
    3728            0 :             IF (tau_f) THEN
    3729            0 :                DEALLOCATE (tau_h, tau_s, tau0_h, tau0_s, tau1_h, tau1_s)
    3730            0 :                DEALLOCATE (vtau_h, vtau_s)
    3731            0 :                CALL release_tau_basis_cache(tau_basis_cache)
    3732              :             END IF
    3733              :          END DO ! ikind
    3734              : 
    3735              :       END IF !xc_none
    3736              : 
    3737            0 :       CALL timestop(handle)
    3738              : 
    3739            0 :    END SUBROUTINE calculate_gfxc_atom
    3740              : 
    3741              : ! **************************************************************************************************
    3742              : !> \brief ...
    3743              : !> \param qs_env ...
    3744              : !> \param rho0_atom_set ...
    3745              : !> \param rho1_atom_set ...
    3746              : !> \param rho2_atom_set ...
    3747              : !> \param kind_set ...
    3748              : !> \param xc_section ...
    3749              : !> \param is_triplet ...
    3750              : !> \param accuracy ...
    3751              : !> \param epsrho ...
    3752              : ! **************************************************************************************************
    3753          114 :    SUBROUTINE gfxc_atom_diff(qs_env, rho0_atom_set, rho1_atom_set, rho2_atom_set, &
    3754              :                              kind_set, xc_section, is_triplet, accuracy, epsrho)
    3755              : 
    3756              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3757              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set, rho1_atom_set, &
    3758              :                                                             rho2_atom_set
    3759              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: kind_set
    3760              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: xc_section
    3761              :       LOGICAL, INTENT(IN)                                :: is_triplet
    3762              :       INTEGER, INTENT(IN)                                :: accuracy
    3763              :       REAL(KIND=dp), INTENT(IN)                          :: epsrho
    3764              : 
    3765              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'gfxc_atom_diff'
    3766              : 
    3767              :       INTEGER                                            :: bo(2), handle, iat, iatom, ikind, ir, &
    3768              :                                                             istep, mspins, myfun, na, natom, nf, &
    3769              :                                                             nr, ns, nspins, nstep, num_pe
    3770              :       INTEGER, DIMENSION(2, 3)                           :: bounds
    3771          114 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
    3772              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
    3773              :                                                             paw_atom, tau_f
    3774              :       REAL(dp)                                           :: agr, alpha, beta, density_cut, &
    3775              :                                                             gradient_cut, oeps1, tau_cut
    3776          114 :       REAL(dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER  :: vtau_h, vtau_s, vxc_h, vxc_s
    3777              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
    3778              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
    3779          228 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
    3780          228 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho0_h, rho0_s, rho1_h, rho1_s, rho_h, &
    3781          228 :                                                             rho_s, tau0_h, tau0_s, tau1_h, tau1_s, &
    3782          114 :                                                             tau_h, tau_s
    3783          114 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho0_h, drho0_s, drho1_h, drho1_s, &
    3784          228 :                                                             drho_h, drho_s, vxg_h, vxg_s
    3785              :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak
    3786          114 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3787              :       TYPE(dft_control_type), POINTER                    :: dft_control
    3788              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    3789              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    3790              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    3791              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3792          114 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, fint_hh, fint_ss, int_hh, &
    3793          114 :                                                             int_ss, r_h, r_s
    3794          114 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    3795              :       TYPE(rho_atom_type), POINTER                       :: rho0_atom, rho1_atom, rho2_atom
    3796              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
    3797          114 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
    3798              :       TYPE(xc_derivative_set_type)                       :: deriv_set
    3799              :       TYPE(xc_rho_cflags_type)                           :: needs
    3800              :       TYPE(xc_rho_set_type)                              :: rho1_set_h, rho1_set_s, rho_set_h, &
    3801              :                                                             rho_set_s
    3802              : 
    3803          114 :       CALL timeset(routineN, handle)
    3804              : 
    3805          114 :       NULLIFY (vtau_h, vtau_s)
    3806              : 
    3807          114 :       ak = 0.0_dp
    3808          114 :       SELECT CASE (accuracy)
    3809              :       CASE (:4)
    3810            0 :          nstep = 2
    3811            0 :          ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
    3812              :       CASE (5:7)
    3813          912 :          nstep = 3
    3814          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
    3815              :       CASE (8:)
    3816            0 :          nstep = 4
    3817              :          ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
    3818          114 :                      224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
    3819              :       END SELECT
    3820          114 :       oeps1 = 1.0_dp/epsrho
    3821              : 
    3822              :       CALL get_qs_env(qs_env=qs_env, &
    3823              :                       dft_control=dft_control, &
    3824              :                       para_env=para_env, &
    3825          114 :                       atomic_kind_set=atomic_kind_set)
    3826              : 
    3827          114 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
    3828          114 :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", i_val=myfun)
    3829              : 
    3830          114 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
    3831              : 
    3832          114 :       IF (myfun == xc_none) THEN
    3833              :          ! no action needed?
    3834              :       ELSE
    3835              :          ! calculate fxc
    3836              :          CALL calculate_xc_2nd_deriv_atom(rho0_atom_set, rho1_atom_set, qs_env, xc_section, para_env, &
    3837          114 :                                           do_triplet=is_triplet, kind_set_external=kind_set)
    3838              : 
    3839          114 :          CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", r_val=density_cut)
    3840          114 :          CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", r_val=gradient_cut)
    3841          114 :          CALL section_vals_val_get(xc_section, "TAU_CUTOFF", r_val=tau_cut)
    3842              : 
    3843          114 :          nlcc = has_nlcc(kind_set)
    3844          114 :          lsd = dft_control%lsd
    3845          114 :          nspins = dft_control%nspins
    3846          114 :          mspins = nspins
    3847          114 :          IF (is_triplet) THEN
    3848           12 :             CPASSERT(nspins == 1)
    3849           12 :             lsd = .TRUE.
    3850           12 :             mspins = 2
    3851              :          END IF
    3852          114 :          needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, calc_potential=.TRUE.)
    3853          114 :          gradient_f = (needs%drho .OR. needs%drho_spin)
    3854          114 :          tau_f = (needs%tau .OR. needs%tau_spin)
    3855              : 
    3856              :          ! Here starts the loop over all the atoms
    3857          386 :          DO ikind = 1, SIZE(atomic_kind_set)
    3858          272 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    3859              :             CALL get_qs_kind(kind_set(ikind), paw_atom=paw_atom, &
    3860          272 :                              harmonics=harmonics, grid_atom=grid_atom)
    3861          272 :             CALL get_qs_kind(kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    3862              : 
    3863          272 :             IF (.NOT. paw_atom) CYCLE
    3864              : 
    3865          258 :             nr = grid_atom%nr
    3866          258 :             na = grid_atom%ng_sphere
    3867              : 
    3868              :             ! set integration weights
    3869          258 :             IF (accint) THEN
    3870          138 :                weight_h => grid_atom%weight
    3871          138 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
    3872          138 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    3873          138 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
    3874              :                END IF
    3875          138 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    3876            0 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
    3877            0 :                   DO ir = 1, nr
    3878            0 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
    3879            0 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
    3880              :                   END DO
    3881            0 :                   grid_atom%gapw_weight_alpha = alpha
    3882              :                END IF
    3883          138 :                weight_s => grid_atom%gapw_weight_s
    3884              :             ELSE
    3885          120 :                weight_h => grid_atom%weight
    3886          120 :                weight_s => grid_atom%weight
    3887              :             END IF
    3888              : 
    3889              :             ! Prepare the structures needed to calculate and store the xc derivatives
    3890              : 
    3891              :             ! Array dimension: here anly one dimensional arrays are used,
    3892              :             ! i.e. only the first column of deriv_data is read.
    3893              :             ! The other to dimensions  are set to size equal 1
    3894         2580 :             bounds(1:2, 1:3) = 1
    3895          258 :             bounds(2, 1) = na
    3896          258 :             bounds(2, 2) = nr
    3897              : 
    3898              :             ! create a place where to put the derivatives
    3899          258 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
    3900              :             ! create the place where to store the argument for the functionals
    3901              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
    3902          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3903              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
    3904          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3905              :             CALL xc_rho_set_create(rho1_set_h, bounds, rho_cutoff=density_cut, &
    3906          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3907              :             CALL xc_rho_set_create(rho1_set_s, bounds, rho_cutoff=density_cut, &
    3908          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3909              : 
    3910              :             ! allocate the required 3d arrays where to store rho and drho
    3911          258 :             CALL xc_rho_set_atom_update(rho_set_h, needs, mspins, bounds)
    3912          258 :             CALL xc_rho_set_atom_update(rho_set_s, needs, mspins, bounds)
    3913          258 :             CALL xc_rho_set_atom_update(rho1_set_h, needs, mspins, bounds)
    3914          258 :             CALL xc_rho_set_atom_update(rho1_set_s, needs, mspins, bounds)
    3915              : 
    3916              :             ALLOCATE (rho_h(na, nr, nspins), rho_s(na, nr, nspins), &
    3917              :                       rho0_h(na, nr, nspins), rho0_s(na, nr, nspins), &
    3918         5160 :                       rho1_h(na, nr, nspins), rho1_s(na, nr, nspins))
    3919         1806 :             ALLOCATE (vxc_h(na, nr, nspins), vxc_s(na, nr, nspins))
    3920          258 :             IF (gradient_f) THEN
    3921              :                ALLOCATE (drho_h(4, na, nr, nspins), drho_s(4, na, nr, nspins), &
    3922              :                          drho0_h(4, na, nr, nspins), drho0_s(4, na, nr, nspins), &
    3923         3520 :                          drho1_h(4, na, nr, nspins), drho1_s(4, na, nr, nspins))
    3924         1408 :                ALLOCATE (vxg_h(3, na, nr, nspins), vxg_s(3, na, nr, nspins))
    3925              :             END IF
    3926          258 :             IF (tau_f) THEN
    3927            0 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    3928              :                ALLOCATE (tau_h(na, nr, nspins), tau_s(na, nr, nspins), &
    3929              :                          tau0_h(na, nr, nspins), tau0_s(na, nr, nspins), &
    3930            0 :                          tau1_h(na, nr, nspins), tau1_s(na, nr, nspins))
    3931            0 :                ALLOCATE (vtau_h(na, nr, nspins), vtau_s(na, nr, nspins))
    3932              :             END IF
    3933              :             !
    3934              :             ! NLCC: prepare rho and drho of the core charge for this KIND
    3935          258 :             donlcc = .FALSE.
    3936          258 :             IF (nlcc) THEN
    3937            0 :                NULLIFY (rho_nlcc)
    3938            0 :                rho_nlcc => kind_set(ikind)%nlcc_pot
    3939            0 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
    3940              :             END IF
    3941              : 
    3942              :             ! Distribute the atoms of this kind
    3943          258 :             num_pe = para_env%num_pe
    3944          258 :             bo = get_limit(natom, num_pe, para_env%mepos)
    3945              : 
    3946          441 :             DO iat = bo(1), bo(2)
    3947          183 :                iatom = atom_list(iat)
    3948              :                !
    3949          183 :                NULLIFY (int_hh, int_ss)
    3950          183 :                rho0_atom => rho0_atom_set(iatom)
    3951          183 :                CALL get_rho_atom(rho_atom=rho0_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    3952         1098 :                ALLOCATE (fint_ss(nspins), fint_hh(nspins))
    3953          366 :                DO ns = 1, nspins
    3954          183 :                   nf = SIZE(int_ss(ns)%r_coef, 1)
    3955          732 :                   ALLOCATE (fint_ss(ns)%r_coef(nf, nf))
    3956          183 :                   nf = SIZE(int_hh(ns)%r_coef, 1)
    3957          915 :                   ALLOCATE (fint_hh(ns)%r_coef(nf, nf))
    3958              :                END DO
    3959              : 
    3960              :                ! RHO0
    3961       467016 :                rho0_h = 0.0_dp
    3962       467016 :                rho0_s = 0.0_dp
    3963          183 :                rho0_atom => rho0_atom_set(iatom)
    3964          183 :                IF (gradient_f) THEN
    3965          126 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    3966              :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    3967          126 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    3968      1581552 :                   drho0_h = 0.0_dp
    3969      1581552 :                   drho0_s = 0.0_dp
    3970              :                ELSE
    3971           57 :                   NULLIFY (r_h, r_s)
    3972           57 :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    3973           57 :                   rho_d = 0.0_dp
    3974              :                END IF
    3975         9333 :                DO ir = 1, nr
    3976              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    3977              :                                         ir, r_h, r_s, rho0_h, rho0_s, dr_h, dr_s, &
    3978         9150 :                                         r_h_d, r_s_d, drho0_h, drho0_s)
    3979         9333 :                   IF (donlcc) THEN
    3980              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
    3981            0 :                                         ir, rho_nlcc(:, 1), rho0_h, rho0_s, rho_nlcc(:, 2), drho0_h, drho0_s)
    3982              :                   END IF
    3983              :                END DO
    3984          183 :                IF (tau_f) THEN
    3985              :                   !compute tau on the grid all at once
    3986            0 :                   CALL calc_tau_atom(tau0_h, tau0_s, rho0_atom, tau_basis_cache, nspins)
    3987              :                ELSE
    3988          183 :                   tau_d = 0.0_dp
    3989              :                END IF
    3990              :                ! RHO1
    3991       467016 :                rho1_h = 0.0_dp
    3992       467016 :                rho1_s = 0.0_dp
    3993          183 :                rho1_atom => rho1_atom_set(iatom)
    3994          183 :                IF (gradient_f) THEN
    3995          126 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    3996              :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    3997          126 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    3998      1581552 :                   drho1_h = 0.0_dp
    3999      1581552 :                   drho1_s = 0.0_dp
    4000              :                ELSE
    4001           57 :                   NULLIFY (r_h, r_s)
    4002           57 :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    4003              :                END IF
    4004         9333 :                DO ir = 1, nr
    4005              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    4006              :                                         ir, r_h, r_s, rho1_h, rho1_s, dr_h, dr_s, &
    4007         9333 :                                         r_h_d, r_s_d, drho1_h, drho1_s)
    4008              :                END DO
    4009          183 :                IF (tau_f) THEN
    4010              :                   !compute tau on the grid all at once
    4011            0 :                   CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, tau_basis_cache, nspins)
    4012              :                END IF
    4013              : 
    4014         9333 :                DO ir = 1, nr
    4015         9333 :                   IF (tau_f) THEN
    4016            0 :                      CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau1_h, na, ir)
    4017            0 :                      CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau1_s, na, ir)
    4018         9150 :                   ELSE IF (gradient_f) THEN
    4019         6300 :                      CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau_d, na, ir)
    4020         6300 :                      CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau_d, na, ir)
    4021              :                   ELSE
    4022         2850 :                      CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, rho_d, tau_d, na, ir)
    4023         2850 :                      CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, rho_d, tau_d, na, ir)
    4024              :                   END IF
    4025              :                END DO
    4026              : 
    4027              :                ! RHO2
    4028          183 :                rho2_atom => rho2_atom_set(iatom)
    4029              : 
    4030         1464 :                DO istep = -nstep, nstep
    4031              : 
    4032         1281 :                   beta = REAL(istep, KIND=dp)*epsrho
    4033              : 
    4034      6536943 :                   rho_h = rho0_h + beta*rho1_h
    4035      6536943 :                   rho_s = rho0_s + beta*rho1_s
    4036         1281 :                   IF (gradient_f) THEN
    4037     22140846 :                      drho_h = drho0_h + beta*drho1_h
    4038     22140846 :                      drho_s = drho0_s + beta*drho1_s
    4039              :                   END IF
    4040         1281 :                   IF (tau_f) THEN
    4041            0 :                      tau_h = tau0_h + beta*tau1_h
    4042            0 :                      tau_s = tau0_s + beta*tau1_s
    4043              :                   END IF
    4044              :                   !
    4045         1281 :                   IF (gradient_f) THEN
    4046              :                      drho_h(4, :, :, :) = SQRT( &
    4047              :                                           drho_h(1, :, :, :)*drho_h(1, :, :, :) + &
    4048              :                                           drho_h(2, :, :, :)*drho_h(2, :, :, :) + &
    4049      2250864 :                                           drho_h(3, :, :, :)*drho_h(3, :, :, :))
    4050              : 
    4051              :                      drho_s(4, :, :, :) = SQRT( &
    4052              :                                           drho_s(1, :, :, :)*drho_s(1, :, :, :) + &
    4053              :                                           drho_s(2, :, :, :)*drho_s(2, :, :, :) + &
    4054      2250864 :                                           drho_s(3, :, :, :)*drho_s(3, :, :, :))
    4055              :                   END IF
    4056              : 
    4057        65331 :                   DO ir = 1, nr
    4058        65331 :                      IF (tau_f) THEN
    4059            0 :                         CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
    4060            0 :                         CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
    4061        64050 :                      ELSE IF (gradient_f) THEN
    4062        44100 :                         CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
    4063        44100 :                         CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
    4064              :                      ELSE
    4065        19950 :                         CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
    4066        19950 :                         CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
    4067              :                      END IF
    4068              :                   END DO
    4069              : 
    4070              :                   ! hard atom density !
    4071         1281 :                   CALL xc_dset_zero_all(deriv_set)
    4072              :                   CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
    4073              :                                          rho_set=rho_set_h, rho1_set=rho1_set_h, &
    4074              :                                          deriv_set=deriv_set, &
    4075              :                                          w=weight_h, vxc=vxc_h, vxg=vxg_h, vtau=vtau_h, &
    4076         1281 :                                          do_triplet=is_triplet)
    4077              :                   ! soft atom density !
    4078         1281 :                   CALL xc_dset_zero_all(deriv_set)
    4079              :                   CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
    4080              :                                          rho_set=rho_set_s, rho1_set=rho1_set_s, &
    4081              :                                          deriv_set=deriv_set, &
    4082              :                                          w=weight_s, vxc=vxc_s, vxg=vxg_s, vtau=vtau_s, &
    4083         1281 :                                          do_triplet=is_triplet)
    4084              :                   ! potentials
    4085         2562 :                   DO ns = 1, nspins
    4086      2410793 :                      fint_hh(ns)%r_coef(:, :) = 0.0_dp
    4087      2412074 :                      fint_ss(ns)%r_coef(:, :) = 0.0_dp
    4088              :                   END DO
    4089         1281 :                   IF (gradient_f) THEN
    4090              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, fint_hh, fint_ss, &
    4091          882 :                                      grid_atom, basis_1c, harmonics, nspins)
    4092              :                   ELSE
    4093              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, fint_hh, fint_ss, &
    4094          399 :                                        grid_atom, basis_1c, harmonics, nspins)
    4095              :                   END IF
    4096         1281 :                   IF (tau_f) THEN
    4097              :                      CALL dgaVtaudgb(vtau_h, vtau_s, fint_hh, fint_ss, &
    4098            0 :                                      tau_basis_cache, nspins)
    4099              :                   END IF
    4100              :                   ! second derivative gxc
    4101         1281 :                   NULLIFY (int_hh, int_ss)
    4102         1281 :                   CALL get_rho_atom(rho_atom=rho2_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    4103         2745 :                   DO ns = 1, nspins
    4104      4820305 :                      int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_ss(ns)%r_coef(:, :)
    4105      4821586 :                      int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_hh(ns)%r_coef(:, :)
    4106              :                   END DO
    4107              :                END DO
    4108              :                !
    4109          366 :                DO ns = 1, nspins
    4110          183 :                   DEALLOCATE (fint_ss(ns)%r_coef)
    4111          366 :                   DEALLOCATE (fint_hh(ns)%r_coef)
    4112              :                END DO
    4113          441 :                DEALLOCATE (fint_ss, fint_hh)
    4114              : 
    4115              :             END DO ! iat
    4116              : 
    4117              :             ! Release the xc structure used to store the xc derivatives
    4118          258 :             CALL xc_dset_release(deriv_set)
    4119          258 :             CALL xc_rho_set_release(rho_set_h)
    4120          258 :             CALL xc_rho_set_release(rho_set_s)
    4121          258 :             CALL xc_rho_set_release(rho1_set_h)
    4122          258 :             CALL xc_rho_set_release(rho1_set_s)
    4123              : 
    4124          258 :             DEALLOCATE (rho_h, rho_s, rho0_h, rho0_s, rho1_h, rho1_s)
    4125          258 :             DEALLOCATE (vxc_h, vxc_s)
    4126          258 :             IF (gradient_f) THEN
    4127          176 :                DEALLOCATE (drho_h, drho_s, drho0_h, drho0_s, drho1_h, drho1_s)
    4128          176 :                DEALLOCATE (vxg_h, vxg_s)
    4129              :             END IF
    4130          902 :             IF (tau_f) THEN
    4131            0 :                DEALLOCATE (tau_h, tau_s, tau0_h, tau0_s, tau1_h, tau1_s)
    4132            0 :                DEALLOCATE (vtau_h, vtau_s)
    4133            0 :                CALL release_tau_basis_cache(tau_basis_cache)
    4134              :             END IF
    4135              :          END DO ! ikind
    4136              : 
    4137              :       END IF !xc_none
    4138              : 
    4139          114 :       CALL timestop(handle)
    4140              : 
    4141         8436 :    END SUBROUTINE gfxc_atom_diff
    4142              : 
    4143              : ! **************************************************************************************************
    4144              : !> \brief ...
    4145              : !> \param grid_atom ...
    4146              : !> \param harmonics ...
    4147              : !> \param nspins ...
    4148              : !> \param grad_func ...
    4149              : !> \param ir ...
    4150              : !> \param r_h ...
    4151              : !> \param r_s ...
    4152              : !> \param rho_h ...
    4153              : !> \param rho_s ...
    4154              : !> \param dr_h ...
    4155              : !> \param dr_s ...
    4156              : !> \param r_h_d ...
    4157              : !> \param r_s_d ...
    4158              : !> \param drho_h ...
    4159              : !> \param drho_s ...
    4160              : ! **************************************************************************************************
    4161      3019240 :    SUBROUTINE calc_rho_angular(grid_atom, harmonics, nspins, grad_func, &
    4162              :                                ir, r_h, r_s, rho_h, rho_s, &
    4163              :                                dr_h, dr_s, r_h_d, r_s_d, drho_h, drho_s)
    4164              : 
    4165              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    4166              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    4167              :       INTEGER, INTENT(IN)                                :: nspins
    4168              :       LOGICAL, INTENT(IN)                                :: grad_func
    4169              :       INTEGER, INTENT(IN)                                :: ir
    4170              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: r_h, r_s
    4171              :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: rho_h, rho_s
    4172              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s
    4173              :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    4174              :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: drho_h, drho_s
    4175              : 
    4176              :       INTEGER                                            :: ia, iso, ispin, na
    4177              :       REAL(KIND=dp)                                      :: rad, urad
    4178              : 
    4179      3019240 :       CPASSERT(ASSOCIATED(r_h))
    4180      3019240 :       CPASSERT(ASSOCIATED(r_s))
    4181      3019240 :       CPASSERT(ASSOCIATED(rho_h))
    4182      3019240 :       CPASSERT(ASSOCIATED(rho_s))
    4183      3019240 :       IF (grad_func) THEN
    4184      1923390 :          CPASSERT(ASSOCIATED(dr_h))
    4185      1923390 :          CPASSERT(ASSOCIATED(dr_s))
    4186      1923390 :          CPASSERT(ASSOCIATED(r_h_d))
    4187      1923390 :          CPASSERT(ASSOCIATED(r_s_d))
    4188      1923390 :          CPASSERT(ASSOCIATED(drho_h))
    4189      1923390 :          CPASSERT(ASSOCIATED(drho_s))
    4190              :       END IF
    4191              : 
    4192      3019240 :       na = grid_atom%ng_sphere
    4193      3019240 :       rad = grid_atom%rad(ir)
    4194      3019240 :       urad = grid_atom%oorad2l(ir, 1)
    4195      6410770 :       DO ispin = 1, nspins
    4196     50955740 :          DO iso = 1, harmonics%max_iso_not0
    4197   2276726520 :             DO ia = 1, na
    4198              :                rho_h(ia, ir, ispin) = rho_h(ia, ir, ispin) + &
    4199   2228790020 :                                       r_h(ispin)%r_coef(ir, iso)*harmonics%slm(ia, iso)
    4200              :                rho_s(ia, ir, ispin) = rho_s(ia, ir, ispin) + &
    4201   2273334990 :                                       r_s(ispin)%r_coef(ir, iso)*harmonics%slm(ia, iso)
    4202              :             END DO ! ia
    4203              :          END DO ! iso
    4204              :       END DO ! ispin
    4205              : 
    4206      3019240 :       IF (grad_func) THEN
    4207      4057370 :          DO ispin = 1, nspins
    4208     31072600 :             DO iso = 1, harmonics%max_iso_not0
    4209   1479545120 :                DO ia = 1, na
    4210              : 
    4211              :                   ! components of the gradient of rho1 hard
    4212              :                   drho_h(1, ia, ir, ispin) = drho_h(1, ia, ir, ispin) + &
    4213              :                                              dr_h(ispin)%r_coef(ir, iso)* &
    4214              :                                              harmonics%a(1, ia)*harmonics%slm(ia, iso) + &
    4215              :                                              r_h_d(1, ispin)%r_coef(ir, iso)* &
    4216   1448472520 :                                              harmonics%slm(ia, iso)
    4217              : 
    4218              :                   drho_h(2, ia, ir, ispin) = drho_h(2, ia, ir, ispin) + &
    4219              :                                              dr_h(ispin)%r_coef(ir, iso)* &
    4220              :                                              harmonics%a(2, ia)*harmonics%slm(ia, iso) + &
    4221              :                                              r_h_d(2, ispin)%r_coef(ir, iso)* &
    4222   1448472520 :                                              harmonics%slm(ia, iso)
    4223              : 
    4224              :                   drho_h(3, ia, ir, ispin) = drho_h(3, ia, ir, ispin) + &
    4225              :                                              dr_h(ispin)%r_coef(ir, iso)* &
    4226              :                                              harmonics%a(3, ia)*harmonics%slm(ia, iso) + &
    4227              :                                              r_h_d(3, ispin)%r_coef(ir, iso)* &
    4228   1448472520 :                                              harmonics%slm(ia, iso)
    4229              : 
    4230              :                   ! components of the gradient of rho1 soft
    4231              :                   drho_s(1, ia, ir, ispin) = drho_s(1, ia, ir, ispin) + &
    4232              :                                              dr_s(ispin)%r_coef(ir, iso)* &
    4233              :                                              harmonics%a(1, ia)*harmonics%slm(ia, iso) + &
    4234              :                                              r_s_d(1, ispin)%r_coef(ir, iso)* &
    4235   1448472520 :                                              harmonics%slm(ia, iso)
    4236              : 
    4237              :                   drho_s(2, ia, ir, ispin) = drho_s(2, ia, ir, ispin) + &
    4238              :                                              dr_s(ispin)%r_coef(ir, iso)* &
    4239              :                                              harmonics%a(2, ia)*harmonics%slm(ia, iso) + &
    4240              :                                              r_s_d(2, ispin)%r_coef(ir, iso)* &
    4241   1448472520 :                                              harmonics%slm(ia, iso)
    4242              : 
    4243              :                   drho_s(3, ia, ir, ispin) = drho_s(3, ia, ir, ispin) + &
    4244              :                                              dr_s(ispin)%r_coef(ir, iso)* &
    4245              :                                              harmonics%a(3, ia)*harmonics%slm(ia, iso) + &
    4246              :                                              r_s_d(3, ispin)%r_coef(ir, iso)* &
    4247   1477411140 :                                              harmonics%slm(ia, iso)
    4248              : 
    4249              :                END DO ! ia
    4250              :             END DO ! iso
    4251    110834850 :             DO ia = 1, na
    4252              :                drho_h(4, ia, ir, ispin) = SQRT( &
    4253              :                                           drho_h(1, ia, ir, ispin)*drho_h(1, ia, ir, ispin) + &
    4254              :                                           drho_h(2, ia, ir, ispin)*drho_h(2, ia, ir, ispin) + &
    4255    106777480 :                                           drho_h(3, ia, ir, ispin)*drho_h(3, ia, ir, ispin))
    4256              : 
    4257              :                drho_s(4, ia, ir, ispin) = SQRT( &
    4258              :                                           drho_s(1, ia, ir, ispin)*drho_s(1, ia, ir, ispin) + &
    4259              :                                           drho_s(2, ia, ir, ispin)*drho_s(2, ia, ir, ispin) + &
    4260    108911460 :                                           drho_s(3, ia, ir, ispin)*drho_s(3, ia, ir, ispin))
    4261              :             END DO ! ia
    4262              :          END DO ! ispin
    4263              :       END IF
    4264              : 
    4265      3019240 :    END SUBROUTINE calc_rho_angular
    4266              : 
    4267              : ! **************************************************************************************************
    4268              : !> \brief Precompute radial and angular factors for GAPW meta-GGA tau contractions
    4269              : !> \param tau_cache precomputed compact one-center gradient basis
    4270              : !> \param grid_atom atom-centered integration grid
    4271              : !> \param basis_1c GAPW one-center basis
    4272              : !> \param harmonics spherical harmonics on the atom-centered grid
    4273              : ! **************************************************************************************************
    4274         1332 :    SUBROUTINE create_tau_basis_cache(tau_cache, grid_atom, basis_1c, harmonics)
    4275              : 
    4276              :       TYPE(tau_basis_cache_type), INTENT(INOUT)          :: tau_cache
    4277              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    4278              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    4279              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    4280              : 
    4281              :       INTEGER                                            :: dir, ia, igrid, ip, ipgf, ir, iset, iso, &
    4282              :                                                             l, starti
    4283         1332 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: a1, a2, gexp, r1, r2
    4284         1332 :       REAL(dp), DIMENSION(:, :), POINTER                 :: slm
    4285         1332 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: dslm_dxyz
    4286              : 
    4287         1332 :       NULLIFY (slm, dslm_dxyz)
    4288              : 
    4289         1332 :       CALL release_tau_basis_cache(tau_cache)
    4290              : 
    4291              :       CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=tau_cache%lmax, &
    4292              :                              lmin=tau_cache%lmin, maxso=tau_cache%maxso, &
    4293              :                              npgf=tau_cache%npgf, nset=tau_cache%nset, &
    4294         1332 :                              zet=tau_cache%zet)
    4295              :       CALL get_paw_basis_info(basis_1c, o2nindex=tau_cache%o2nindex, &
    4296              :                               n2oindex=tau_cache%n2oindex, &
    4297         1332 :                               nsatbas=tau_cache%nsatbas)
    4298              : 
    4299         1332 :       tau_cache%nr = grid_atom%nr
    4300         1332 :       tau_cache%na = grid_atom%ng_sphere
    4301         1332 :       slm => harmonics%slm
    4302         1332 :       dslm_dxyz => harmonics%dslm_dxyz
    4303              : 
    4304         6660 :       ALLOCATE (tau_cache%grad(tau_cache%na*tau_cache%nr, tau_cache%nsatbas, 3))
    4305              :       ALLOCATE (a1(tau_cache%na), a2(tau_cache%na), gexp(tau_cache%nr), &
    4306        10656 :                 r1(tau_cache%nr), r2(tau_cache%nr))
    4307    291013758 :       tau_cache%grad = 0.0_dp
    4308              : 
    4309         5430 :       DO iset = 1, tau_cache%nset
    4310        17822 :          DO ipgf = 1, tau_cache%npgf(iset)
    4311              :             starti = (iset - 1)*tau_cache%maxso + &
    4312        12392 :                      (ipgf - 1)*nsoset(tau_cache%lmax(iset))
    4313              :             gexp(1:tau_cache%nr) = EXP(-tau_cache%zet(ipgf, iset)* &
    4314       644992 :                                        grid_atom%rad2(1:tau_cache%nr))
    4315        53500 :             DO iso = nsoset(tau_cache%lmin(iset) - 1) + 1, nsoset(tau_cache%lmax(iset))
    4316        37010 :                ip = tau_cache%o2nindex(starti + iso)
    4317        37010 :                IF (ip == 0) CYCLE
    4318        37010 :                l = indso(1, iso)
    4319              : 
    4320      1923910 :                r1(1:tau_cache%nr) = grid_atom%rad(1:tau_cache%nr)**(l - 1)*gexp(1:tau_cache%nr)
    4321              :                r2(1:tau_cache%nr) = -2.0_dp*tau_cache%zet(ipgf, iset)* &
    4322      1923910 :                                     grid_atom%rad2(1:tau_cache%nr)*r1(1:tau_cache%nr)
    4323              : 
    4324       160432 :                DO dir = 1, 3
    4325      5741154 :                   a1(1:tau_cache%na) = dslm_dxyz(dir, 1:tau_cache%na, iso)
    4326      5741154 :                   a2(1:tau_cache%na) = harmonics%a(dir, 1:tau_cache%na)*slm(1:tau_cache%na, iso)
    4327      5808740 :                   DO ir = 1, tau_cache%nr
    4328    296669130 :                      DO ia = 1, tau_cache%na
    4329    290897400 :                         igrid = ia + (ir - 1)*tau_cache%na
    4330    296558100 :                         tau_cache%grad(igrid, ip, dir) = r1(ir)*a1(ia) + r2(ir)*a2(ia)
    4331              :                      END DO
    4332              :                   END DO
    4333              :                END DO
    4334              :             END DO
    4335              :          END DO
    4336              :       END DO
    4337              : 
    4338         1332 :       DEALLOCATE (a1, a2, gexp, r1, r2)
    4339              : 
    4340         1332 :    END SUBROUTINE create_tau_basis_cache
    4341              : 
    4342              : ! **************************************************************************************************
    4343              : !> \brief Release precomputed GAPW meta-GGA tau factors
    4344              : !> \param tau_cache precomputed compact one-center gradient basis
    4345              : ! **************************************************************************************************
    4346         2664 :    SUBROUTINE release_tau_basis_cache(tau_cache)
    4347              : 
    4348              :       TYPE(tau_basis_cache_type), INTENT(INOUT)          :: tau_cache
    4349              : 
    4350         2664 :       IF (ALLOCATED(tau_cache%grad)) DEALLOCATE (tau_cache%grad)
    4351         2664 :       IF (ASSOCIATED(tau_cache%n2oindex)) DEALLOCATE (tau_cache%n2oindex)
    4352         2664 :       IF (ASSOCIATED(tau_cache%o2nindex)) DEALLOCATE (tau_cache%o2nindex)
    4353         2664 :       NULLIFY (tau_cache%lmax, tau_cache%lmin, tau_cache%n2oindex, tau_cache%npgf, &
    4354         2664 :                tau_cache%zet, tau_cache%o2nindex)
    4355         2664 :       tau_cache%maxso = 0
    4356         2664 :       tau_cache%na = 0
    4357         2664 :       tau_cache%nr = 0
    4358         2664 :       tau_cache%nsatbas = 0
    4359         2664 :       tau_cache%nset = 0
    4360              : 
    4361         2664 :    END SUBROUTINE release_tau_basis_cache
    4362              : 
    4363              : ! **************************************************************************************************
    4364              : !> \brief Computes tau hard and soft on the atomic grids for meta-GGA calculations
    4365              : !> \param tau_h the hard part of tau
    4366              : !> \param tau_s the soft part of tau
    4367              : !> \param rho_atom atom-centered density matrices
    4368              : !> \param tau_cache precomputed compact one-center gradient basis
    4369              : !> \param nspins number of spin channels
    4370              : !> \note This is a rewrite to correct a meta-GGA GAPW bug. This is more brute force than the original,
    4371              : !>       which was done along in qs_rho_atom_methods.F, but makes sure that no corner is cut in
    4372              : !>       terms of accuracy (A. Bussy)
    4373              : ! **************************************************************************************************
    4374          979 :    SUBROUTINE calc_tau_atom(tau_h, tau_s, rho_atom, tau_cache, nspins)
    4375              : 
    4376              :       REAL(dp), DIMENSION(:, :, :), INTENT(INOUT)        :: tau_h, tau_s
    4377              :       TYPE(rho_atom_type), POINTER                       :: rho_atom
    4378              :       TYPE(tau_basis_cache_type), INTENT(IN)             :: tau_cache
    4379              :       INTEGER, INTENT(IN)                                :: nspins
    4380              : 
    4381              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'calc_tau_atom'
    4382              : 
    4383              :       INTEGER                                            :: dir, handle, ia, ibas, igrid, ir, ispin, &
    4384              :                                                             na, nbas, ngrid, nr
    4385          979 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: work
    4386              : 
    4387          979 :       CALL timeset(routineN, handle)
    4388              : 
    4389          979 :       CPASSERT(ALLOCATED(tau_cache%grad))
    4390              : 
    4391              :       !zeroing tau, assuming it is already allocated
    4392      2678716 :       tau_h = 0.0_dp
    4393      2678716 :       tau_s = 0.0_dp
    4394              : 
    4395          979 :       nr = tau_cache%nr
    4396          979 :       na = tau_cache%na
    4397          979 :       nbas = tau_cache%nsatbas
    4398          979 :       ngrid = na*nr
    4399         3916 :       ALLOCATE (work(ngrid, nbas))
    4400              : 
    4401         1966 :       DO ispin = 1, nspins
    4402         4927 :          DO dir = 1, 3
    4403              :             CALL dgemm('N', 'T', ngrid, nbas, nbas, 0.5_dp, tau_cache%grad(:, :, dir), &
    4404         2961 :                        ngrid, rho_atom%cpc_h(ispin)%r_coef, nbas, 0.0_dp, work, ngrid)
    4405        76200 :             DO ibas = 1, nbas
    4406      3792750 :                DO ir = 1, nr
    4407    193548489 :                   DO ia = 1, na
    4408    189758700 :                      igrid = ia + (ir - 1)*na
    4409              :                      tau_h(ia, ir, ispin) = tau_h(ia, ir, ispin) + &
    4410    193475250 :                                             tau_cache%grad(igrid, ibas, dir)*work(igrid, ibas)
    4411              :                   END DO
    4412              :                END DO
    4413              :             END DO
    4414              : 
    4415              :             CALL dgemm('N', 'T', ngrid, nbas, nbas, 0.5_dp, tau_cache%grad(:, :, dir), &
    4416         2961 :                        ngrid, rho_atom%cpc_s(ispin)%r_coef, nbas, 0.0_dp, work, ngrid)
    4417        77187 :             DO ibas = 1, nbas
    4418      3792750 :                DO ir = 1, nr
    4419    193548489 :                   DO ia = 1, na
    4420    189758700 :                      igrid = ia + (ir - 1)*na
    4421              :                      tau_s(ia, ir, ispin) = tau_s(ia, ir, ispin) + &
    4422    193475250 :                                             tau_cache%grad(igrid, ibas, dir)*work(igrid, ibas)
    4423              :                   END DO
    4424              :                END DO
    4425              :             END DO
    4426              :          END DO
    4427              :       END DO
    4428              : 
    4429          979 :       DEALLOCATE (work)
    4430              : 
    4431          979 :       CALL timestop(handle)
    4432              : 
    4433          979 :    END SUBROUTINE calc_tau_atom
    4434              : 
    4435              : ! **************************************************************************************************
    4436              : !> \brief ...
    4437              : !> \param grid_atom ...
    4438              : !> \param nspins ...
    4439              : !> \param grad_func ...
    4440              : !> \param ir ...
    4441              : !> \param rho_nlcc ...
    4442              : !> \param rho_h ...
    4443              : !> \param rho_s ...
    4444              : !> \param drho_nlcc ...
    4445              : !> \param drho_h ...
    4446              : !> \param drho_s ...
    4447              : ! **************************************************************************************************
    4448         8700 :    SUBROUTINE calc_rho_nlcc(grid_atom, nspins, grad_func, &
    4449         8700 :                             ir, rho_nlcc, rho_h, rho_s, drho_nlcc, drho_h, drho_s)
    4450              : 
    4451              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    4452              :       INTEGER, INTENT(IN)                                :: nspins
    4453              :       LOGICAL, INTENT(IN)                                :: grad_func
    4454              :       INTEGER, INTENT(IN)                                :: ir
    4455              :       REAL(KIND=dp), DIMENSION(:)                        :: rho_nlcc
    4456              :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: rho_h, rho_s
    4457              :       REAL(KIND=dp), DIMENSION(:)                        :: drho_nlcc
    4458              :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: drho_h, drho_s
    4459              : 
    4460              :       INTEGER                                            :: ia, ispin, na
    4461              :       REAL(KIND=dp)                                      :: drho, dx, dy, dz, rad, rho, urad, xsp
    4462              : 
    4463         8700 :       CPASSERT(ASSOCIATED(rho_h))
    4464         8700 :       CPASSERT(ASSOCIATED(rho_s))
    4465         8700 :       IF (grad_func) THEN
    4466         8700 :          CPASSERT(ASSOCIATED(drho_h))
    4467         8700 :          CPASSERT(ASSOCIATED(drho_s))
    4468              :       END IF
    4469              : 
    4470         8700 :       na = grid_atom%ng_sphere
    4471         8700 :       rad = grid_atom%rad(ir)
    4472         8700 :       urad = grid_atom%oorad2l(ir, 1)
    4473              : 
    4474         8700 :       xsp = REAL(nspins, KIND=dp)
    4475         8700 :       rho = rho_nlcc(ir)/xsp
    4476        17400 :       DO ispin = 1, nspins
    4477       443700 :          rho_h(1:na, ir, ispin) = rho_h(1:na, ir, ispin) + rho
    4478       452400 :          rho_s(1:na, ir, ispin) = rho_s(1:na, ir, ispin) + rho
    4479              :       END DO ! ispin
    4480              : 
    4481         8700 :       IF (grad_func) THEN
    4482         8700 :          drho = drho_nlcc(ir)/xsp
    4483        17400 :          DO ispin = 1, nspins
    4484       452400 :             DO ia = 1, na
    4485       435000 :                IF (grid_atom%azi(ia) == 0.0_dp) THEN
    4486              :                   dx = 0.0_dp
    4487              :                   dy = 0.0_dp
    4488              :                ELSE
    4489       391500 :                   dx = grid_atom%sin_pol(ia)*grid_atom%sin_azi(ia)
    4490       391500 :                   dy = grid_atom%sin_pol(ia)*grid_atom%cos_azi(ia)
    4491              :                END IF
    4492       435000 :                dz = grid_atom%cos_pol(ia)
    4493              :                ! components of the gradient of rho1 hard
    4494       435000 :                drho_h(1, ia, ir, ispin) = drho_h(1, ia, ir, ispin) + drho*dx
    4495       435000 :                drho_h(2, ia, ir, ispin) = drho_h(2, ia, ir, ispin) + drho*dy
    4496       435000 :                drho_h(3, ia, ir, ispin) = drho_h(3, ia, ir, ispin) + drho*dz
    4497              :                ! components of the gradient of rho1 soft
    4498       435000 :                drho_s(1, ia, ir, ispin) = drho_s(1, ia, ir, ispin) + drho*dx
    4499       435000 :                drho_s(2, ia, ir, ispin) = drho_s(2, ia, ir, ispin) + drho*dy
    4500       435000 :                drho_s(3, ia, ir, ispin) = drho_s(3, ia, ir, ispin) + drho*dz
    4501              :                ! norm of gradient
    4502              :                drho_h(4, ia, ir, ispin) = SQRT( &
    4503              :                                           drho_h(1, ia, ir, ispin)*drho_h(1, ia, ir, ispin) + &
    4504              :                                           drho_h(2, ia, ir, ispin)*drho_h(2, ia, ir, ispin) + &
    4505       435000 :                                           drho_h(3, ia, ir, ispin)*drho_h(3, ia, ir, ispin))
    4506              : 
    4507              :                drho_s(4, ia, ir, ispin) = SQRT( &
    4508              :                                           drho_s(1, ia, ir, ispin)*drho_s(1, ia, ir, ispin) + &
    4509              :                                           drho_s(2, ia, ir, ispin)*drho_s(2, ia, ir, ispin) + &
    4510       443700 :                                           drho_s(3, ia, ir, ispin)*drho_s(3, ia, ir, ispin))
    4511              :             END DO ! ia
    4512              :          END DO ! ispin
    4513              :       END IF
    4514              : 
    4515         8700 :    END SUBROUTINE calc_rho_nlcc
    4516              : 
    4517              : ! **************************************************************************************************
    4518              : !> \brief ...
    4519              : !> \param vxc_h ...
    4520              : !> \param vxc_s ...
    4521              : !> \param int_hh ...
    4522              : !> \param int_ss ...
    4523              : !> \param grid_atom ...
    4524              : !> \param basis_1c ...
    4525              : !> \param harmonics ...
    4526              : !> \param nspins ...
    4527              : ! **************************************************************************************************
    4528        16436 :    SUBROUTINE gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, grid_atom, basis_1c, harmonics, nspins)
    4529              : 
    4530              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vxc_h, vxc_s
    4531              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: int_hh, int_ss
    4532              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    4533              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    4534              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    4535              :       INTEGER, INTENT(IN)                                :: nspins
    4536              : 
    4537              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'gaVxcgb_noGC'
    4538              : 
    4539              :       INTEGER :: handle, ia, ic, icg, ipgf1, ipgf2, ir, iset1, iset2, iso, iso1, iso2, ispin, l, &
    4540              :          ld, lmax12, lmax_expansion, lmin12, m1, m2, max_iso_not0, max_iso_not0_local, max_s_harm, &
    4541              :          maxl, maxso, n1, n2, na, ngau1, ngau2, nngau1, nr, nset, size1
    4542              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: cg_n_list
    4543              :       INTEGER, ALLOCATABLE, DIMENSION(:, :, :)           :: cg_list
    4544        16436 :       INTEGER, DIMENSION(:), POINTER                     :: lmax, lmin, npgf
    4545        16436 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: g1, g2
    4546        16436 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: gg, gVg_h, gVg_s, matso_h, matso_s, vx
    4547        16436 :       REAL(dp), DIMENSION(:, :), POINTER                 :: zet
    4548              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: my_CG
    4549              : 
    4550        16436 :       CALL timeset(routineN, handle)
    4551              : 
    4552        16436 :       NULLIFY (lmin, lmax, npgf, zet, my_CG)
    4553              : 
    4554              :       CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=lmax, lmin=lmin, &
    4555              :                              maxso=maxso, maxl=maxl, npgf=npgf, &
    4556        16436 :                              nset=nset, zet=zet)
    4557              : 
    4558        16436 :       nr = grid_atom%nr
    4559        16436 :       na = grid_atom%ng_sphere
    4560        16436 :       my_CG => harmonics%my_CG
    4561        16436 :       max_iso_not0 = harmonics%max_iso_not0
    4562        16436 :       lmax_expansion = indso(1, max_iso_not0)
    4563        16436 :       max_s_harm = harmonics%max_s_harm
    4564              : 
    4565       115052 :       ALLOCATE (g1(nr), g2(nr), gg(nr, 0:2*maxl))
    4566        98616 :       ALLOCATE (gVg_h(na, 0:2*maxl), gVg_s(na, 0:2*maxl))
    4567              :       ALLOCATE (matso_h(nsoset(maxl), nsoset(maxl)), &
    4568        98616 :                 matso_s(nsoset(maxl), nsoset(maxl)))
    4569        65744 :       ALLOCATE (vx(na, nr))
    4570        98616 :       ALLOCATE (cg_list(2, nsoset(maxl)**2, max_s_harm), cg_n_list(max_s_harm))
    4571              : 
    4572        16436 :       g1 = 0.0_dp
    4573        16436 :       g2 = 0.0_dp
    4574        16436 :       m1 = 0
    4575        55936 :       DO iset1 = 1, nset
    4576        39500 :          n1 = nsoset(lmax(iset1))
    4577        39500 :          m2 = 0
    4578       163574 :          DO iset2 = 1, nset
    4579              :             CALL get_none0_cg_list(my_CG, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
    4580       124074 :                                    max_s_harm, lmax_expansion, cg_list, cg_n_list, max_iso_not0_local)
    4581       124074 :             CPASSERT(max_iso_not0_local <= max_iso_not0)
    4582              : 
    4583       124074 :             n2 = nsoset(lmax(iset2))
    4584       454473 :             DO ipgf1 = 1, npgf(iset1)
    4585       330399 :                ngau1 = n1*(ipgf1 - 1) + m1
    4586       330399 :                size1 = nsoset(lmax(iset1)) - nsoset(lmin(iset1) - 1)
    4587       330399 :                nngau1 = nsoset(lmin(iset1) - 1) + ngau1
    4588              : 
    4589     18974349 :                g1(1:nr) = EXP(-zet(ipgf1, iset1)*grid_atom%rad2(1:nr))
    4590      1532742 :                DO ipgf2 = 1, npgf(iset2)
    4591      1078269 :                   ngau2 = n2*(ipgf2 - 1) + m2
    4592              : 
    4593     61482419 :                   g2(1:nr) = EXP(-zet(ipgf2, iset2)*grid_atom%rad2(1:nr))
    4594      1078269 :                   lmin12 = lmin(iset1) + lmin(iset2)
    4595      1078269 :                   lmax12 = lmax(iset1) + lmax(iset2)
    4596              : 
    4597              :                   ! reduce expansion local densities
    4598      1408668 :                   IF (lmin12 <= lmax_expansion) THEN
    4599              : 
    4600      1077324 :                      gg = 0.0_dp
    4601      1077324 :                      IF (lmin12 == 0) THEN
    4602     34361520 :                         gg(1:nr, lmin12) = g1(1:nr)*g2(1:nr)
    4603              :                      ELSE
    4604     27072704 :                         gg(1:nr, lmin12) = grid_atom%rad2l(1:nr, lmin12)*g1(1:nr)*g2(1:nr)
    4605              :                      END IF
    4606              : 
    4607              :                      ! limit the expansion of the local densities to a max L
    4608      1077324 :                      IF (lmax12 > lmax_expansion) lmax12 = lmax_expansion
    4609              : 
    4610      1571084 :                      DO l = lmin12 + 1, lmax12
    4611     30759884 :                         gg(1:nr, l) = grid_atom%rad(1:nr)*gg(:, l - 1)
    4612              :                      END DO
    4613              : 
    4614      2331201 :                      DO ispin = 1, nspins
    4615      1253877 :                         ld = lmax12 + 1
    4616     75450727 :                         DO ir = 1, nr
    4617   3785293227 :                            vx(1:na, ir) = vxc_h(1:na, ir, ispin)
    4618              :                         END DO
    4619              :                         CALL dgemm('N', 'N', na, ld, nr, 1.0_dp, vx(1:na, 1:nr), na, &
    4620      1253877 :                                    gg(1:nr, 0:lmax12), nr, 0.0_dp, gVg_h(1:na, 0:lmax12), na)
    4621     75450727 :                         DO ir = 1, nr
    4622   3785293227 :                            vx(1:na, ir) = vxc_s(1:na, ir, ispin)
    4623              :                         END DO
    4624              :                         CALL dgemm('N', 'N', na, ld, nr, 1.0_dp, vx(1:na, 1:nr), na, &
    4625      1253877 :                                    gg(1:nr, 0:lmax12), nr, 0.0_dp, gVg_s(1:na, 0:lmax12), na)
    4626              : 
    4627      1253877 :                         matso_h = 0.0_dp
    4628      1253877 :                         matso_s = 0.0_dp
    4629      9755902 :                         DO iso = 1, max_iso_not0_local
    4630     26785106 :                            DO icg = 1, cg_n_list(iso)
    4631     17029204 :                               iso1 = cg_list(1, icg, iso)
    4632     17029204 :                               iso2 = cg_list(2, icg, iso)
    4633     17029204 :                               l = indso(1, iso1) + indso(1, iso2)
    4634              : 
    4635     17029204 :                               CPASSERT(l <= lmax_expansion)
    4636    876991429 :                               DO ia = 1, na
    4637              :                                  matso_h(iso1, iso2) = matso_h(iso1, iso2) + &
    4638              :                                                        gVg_h(ia, l)* &
    4639              :                                                        my_CG(iso1, iso2, iso)* &
    4640    851460200 :                                                        harmonics%slm(ia, iso)
    4641              :                                  matso_s(iso1, iso2) = matso_s(iso1, iso2) + &
    4642              :                                                        gVg_s(ia, l)* &
    4643              :                                                        my_CG(iso1, iso2, iso)* &
    4644    868489404 :                                                        harmonics%slm(ia, iso)
    4645              :                               END DO
    4646              :                            END DO
    4647              :                         END DO
    4648              : 
    4649              :                         ! Write in the global matrix
    4650      5596448 :                         DO ic = nsoset(lmin(iset2) - 1) + 1, nsoset(lmax(iset2))
    4651      3265247 :                            iso1 = nsoset(lmin(iset1) - 1) + 1
    4652      3265247 :                            iso2 = ngau2 + ic
    4653              :                            CALL daxpy(size1, 1.0_dp, matso_h(iso1, ic), 1, &
    4654      3265247 :                                       int_hh(ispin)%r_coef(nngau1 + 1, iso2), 1)
    4655              :                            CALL daxpy(size1, 1.0_dp, matso_s(iso1, ic), 1, &
    4656      4519124 :                                       int_ss(ispin)%r_coef(nngau1 + 1, iso2), 1)
    4657              :                         END DO
    4658              : 
    4659              :                      END DO ! ispin
    4660              : 
    4661              :                   END IF ! lmax_expansion
    4662              : 
    4663              :                END DO ! ipfg2
    4664              :             END DO ! ipfg1
    4665       287648 :             m2 = m2 + maxso
    4666              :          END DO ! iset2
    4667        55936 :          m1 = m1 + maxso
    4668              :       END DO ! iset1
    4669              : 
    4670        16436 :       DEALLOCATE (g1, g2, gg, matso_h, matso_s, gVg_s, gVg_h, vx)
    4671              : 
    4672        16436 :       DEALLOCATE (cg_list, cg_n_list)
    4673              : 
    4674        16436 :       CALL timestop(handle)
    4675              : 
    4676        16436 :    END SUBROUTINE gaVxcgb_noGC
    4677              : 
    4678              : ! **************************************************************************************************
    4679              : !> \brief ...
    4680              : !> \param vxc_h ...
    4681              : !> \param vxc_s ...
    4682              : !> \param vxg_h ...
    4683              : !> \param vxg_s ...
    4684              : !> \param int_hh ...
    4685              : !> \param int_ss ...
    4686              : !> \param grid_atom ...
    4687              : !> \param basis_1c ...
    4688              : !> \param harmonics ...
    4689              : !> \param nspins ...
    4690              : ! **************************************************************************************************
    4691        30820 :    SUBROUTINE gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    4692              :                          grid_atom, basis_1c, harmonics, nspins)
    4693              : 
    4694              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vxc_h, vxc_s
    4695              :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: vxg_h, vxg_s
    4696              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: int_hh, int_ss
    4697              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    4698              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    4699              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    4700              :       INTEGER, INTENT(IN)                                :: nspins
    4701              : 
    4702              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'gaVxcgb_GC'
    4703              : 
    4704              :       INTEGER :: dmax_iso_not0_local, handle, ia, ic, icg, ipgf1, ipgf2, ir, iset1, iset2, iso, &
    4705              :          iso1, iso2, ispin, l, lmax12, lmax_expansion, lmin12, m1, m2, max_iso_not0, &
    4706              :          max_iso_not0_local, max_s_harm, maxl, maxso, n1, n2, na, ngau1, ngau2, nngau1, nr, nset, &
    4707              :          size1
    4708              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: cg_n_list, dcg_n_list
    4709              :       INTEGER, ALLOCATABLE, DIMENSION(:, :, :)           :: cg_list, dcg_list
    4710        30820 :       INTEGER, DIMENSION(:), POINTER                     :: lmax, lmin, npgf
    4711              :       REAL(dp)                                           :: urad
    4712        30820 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: g1, g2
    4713        30820 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: dgg, gg, gVXCg_h, gVXCg_s, matso_h, &
    4714        30820 :                                                             matso_s
    4715        30820 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: gVXGg_h, gVXGg_s
    4716        30820 :       REAL(dp), DIMENSION(:, :), POINTER                 :: zet
    4717              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: my_CG
    4718              :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: my_CG_dxyz
    4719              : 
    4720        30820 :       CALL timeset(routineN, handle)
    4721              : 
    4722        30820 :       NULLIFY (lmin, lmax, npgf, zet, my_CG, my_CG_dxyz)
    4723              : 
    4724              :       CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=lmax, lmin=lmin, &
    4725              :                              maxso=maxso, maxl=maxl, npgf=npgf, &
    4726        30820 :                              nset=nset, zet=zet)
    4727              : 
    4728        30820 :       nr = grid_atom%nr
    4729        30820 :       na = grid_atom%ng_sphere
    4730        30820 :       my_CG => harmonics%my_CG
    4731        30820 :       my_CG_dxyz => harmonics%my_CG_dxyz
    4732        30820 :       max_iso_not0 = harmonics%max_iso_not0
    4733        30820 :       lmax_expansion = indso(1, max_iso_not0)
    4734        30820 :       max_s_harm = harmonics%max_s_harm
    4735              : 
    4736       277380 :       ALLOCATE (g1(nr), g2(nr), gg(nr, 0:2*maxl), dgg(nr, 0:2*maxl))
    4737       184920 :       ALLOCATE (gVXCg_h(na, 0:2*maxl), gVXCg_s(na, 0:2*maxl))
    4738       184920 :       ALLOCATE (gVXGg_h(3, na, 0:2*maxl), gVXGg_s(3, na, 0:2*maxl))
    4739              :       ALLOCATE (cg_list(2, nsoset(maxl)**2, max_s_harm), cg_n_list(max_s_harm), &
    4740       277380 :                 dcg_list(2, nsoset(maxl)**2, max_s_harm), dcg_n_list(max_s_harm))
    4741              : 
    4742              :       ALLOCATE (matso_h(nsoset(maxl), nsoset(maxl)), &
    4743       184920 :                 matso_s(nsoset(maxl), nsoset(maxl)))
    4744              : 
    4745        64953 :       DO ispin = 1, nspins
    4746              : 
    4747        34133 :          g1 = 0.0_dp
    4748        34133 :          g2 = 0.0_dp
    4749        34133 :          m1 = 0
    4750       151639 :          DO iset1 = 1, nset
    4751        86686 :             n1 = nsoset(lmax(iset1))
    4752        86686 :             m2 = 0
    4753       383074 :             DO iset2 = 1, nset
    4754              :                CALL get_none0_cg_list(my_CG, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
    4755       296388 :                                       max_s_harm, lmax_expansion, cg_list, cg_n_list, max_iso_not0_local)
    4756       296388 :                CPASSERT(max_iso_not0_local <= max_iso_not0)
    4757              :                CALL get_none0_cg_list(my_CG_dxyz, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
    4758       296388 :                                       max_s_harm, lmax_expansion, dcg_list, dcg_n_list, dmax_iso_not0_local)
    4759              : 
    4760       296388 :                n2 = nsoset(lmax(iset2))
    4761       956987 :                DO ipgf1 = 1, npgf(iset1)
    4762       660599 :                   ngau1 = n1*(ipgf1 - 1) + m1
    4763       660599 :                   size1 = nsoset(lmax(iset1)) - nsoset(lmin(iset1) - 1)
    4764       660599 :                   nngau1 = nsoset(lmin(iset1) - 1) + ngau1
    4765              : 
    4766     34402829 :                   g1(1:nr) = EXP(-zet(ipgf1, iset1)*grid_atom%rad2(1:nr))
    4767      2615934 :                   DO ipgf2 = 1, npgf(iset2)
    4768      1658947 :                      ngau2 = n2*(ipgf2 - 1) + m2
    4769              : 
    4770     86608777 :                      g2(1:nr) = EXP(-zet(ipgf2, iset2)*grid_atom%rad2(1:nr))
    4771      1658947 :                      lmin12 = lmin(iset1) + lmin(iset2)
    4772      1658947 :                      lmax12 = lmax(iset1) + lmax(iset2)
    4773              : 
    4774              :                      !test reduce expansion local densities
    4775      1658947 :                      IF (lmin12 <= lmax_expansion) THEN
    4776              : 
    4777      1658347 :                         gg = 0.0_dp
    4778      1658347 :                         dgg = 0.0_dp
    4779              : 
    4780      1658347 :                         IF (lmin12 == 0) THEN
    4781     51877675 :                            gg(1:nr, lmin12) = g1(1:nr)*g2(1:nr)
    4782              :                         ELSE
    4783     34700502 :                            gg(1:nr, lmin12) = grid_atom%rad2l(1:nr, lmin12)*g1(1:nr)*g2(1:nr)
    4784              :                         END IF
    4785              : 
    4786              :                         !test reduce expansion local densities
    4787      1658347 :                         IF (lmax12 > lmax_expansion) lmax12 = lmax_expansion
    4788              : 
    4789      2547073 :                         DO l = lmin12 + 1, lmax12
    4790     46766226 :                            gg(1:nr, l) = grid_atom%rad(1:nr)*gg(:, l - 1)
    4791              :                            dgg(1:nr, l - 1) = dgg(1:nr, l - 1) - 2.0_dp*(zet(ipgf1, iset1) + &
    4792     48424573 :                                                                          zet(ipgf2, iset2))*gg(1:nr, l)
    4793              :                         END DO
    4794              :                         dgg(1:nr, lmax12) = dgg(1:nr, lmax12) - 2.0_dp*(zet(ipgf1, iset1) + &
    4795              :                                                                         zet(ipgf2, iset2))*grid_atom%rad(1:nr)* &
    4796     86578177 :                                             gg(1:nr, lmax12)
    4797              : 
    4798      1658347 :                         gVXCg_h = 0.0_dp
    4799      1658347 :                         gVXCg_s = 0.0_dp
    4800      1658347 :                         gVXGg_h = 0.0_dp
    4801      1658347 :                         gVXGg_s = 0.0_dp
    4802              : 
    4803              :                         ! Cross Term
    4804      4205420 :                         DO l = lmin12, lmax12
    4805    131510302 :                            DO ia = 1, na
    4806   6673260855 :                               DO ir = 1, nr
    4807              :                                  gVXCg_h(ia, l) = gVXCg_h(ia, l) + &
    4808              :                                                   gg(ir, l)*vxc_h(ia, ir, ispin) + &
    4809              :                                                   dgg(ir, l)* &
    4810              :                                                   (vxg_h(1, ia, ir, ispin)*harmonics%a(1, ia) + &
    4811              :                                                    vxg_h(2, ia, ir, ispin)*harmonics%a(2, ia) + &
    4812   6543408900 :                                                    vxg_h(3, ia, ir, ispin)*harmonics%a(3, ia))
    4813              : 
    4814              :                                  gVXCg_s(ia, l) = gVXCg_s(ia, l) + &
    4815              :                                                   gg(ir, l)*vxc_s(ia, ir, ispin) + &
    4816              :                                                   dgg(ir, l)* &
    4817              :                                                   (vxg_s(1, ia, ir, ispin)*harmonics%a(1, ia) + &
    4818              :                                                    vxg_s(2, ia, ir, ispin)*harmonics%a(2, ia) + &
    4819   6543408900 :                                                    vxg_s(3, ia, ir, ispin)*harmonics%a(3, ia))
    4820              : 
    4821   6543408900 :                                  urad = grid_atom%oorad2l(ir, 1)
    4822              : 
    4823              :                                  gVXGg_h(1, ia, l) = gVXGg_h(1, ia, l) + &
    4824              :                                                      vxg_h(1, ia, ir, ispin)* &
    4825   6543408900 :                                                      gg(ir, l)*urad
    4826              : 
    4827              :                                  gVXGg_h(2, ia, l) = gVXGg_h(2, ia, l) + &
    4828              :                                                      vxg_h(2, ia, ir, ispin)* &
    4829   6543408900 :                                                      gg(ir, l)*urad
    4830              : 
    4831              :                                  gVXGg_h(3, ia, l) = gVXGg_h(3, ia, l) + &
    4832              :                                                      vxg_h(3, ia, ir, ispin)* &
    4833   6543408900 :                                                      gg(ir, l)*urad
    4834              : 
    4835              :                                  gVXGg_s(1, ia, l) = gVXGg_s(1, ia, l) + &
    4836              :                                                      vxg_s(1, ia, ir, ispin)* &
    4837   6543408900 :                                                      gg(ir, l)*urad
    4838              : 
    4839              :                                  gVXGg_s(2, ia, l) = gVXGg_s(2, ia, l) + &
    4840              :                                                      vxg_s(2, ia, ir, ispin)* &
    4841   6543408900 :                                                      gg(ir, l)*urad
    4842              : 
    4843              :                                  gVXGg_s(3, ia, l) = gVXGg_s(3, ia, l) + &
    4844              :                                                      vxg_s(3, ia, ir, ispin)* &
    4845   6670713782 :                                                      gg(ir, l)*urad
    4846              : 
    4847              :                               END DO ! ir
    4848              :                            END DO ! ia
    4849              :                         END DO ! l
    4850              : 
    4851      1658347 :                         matso_h = 0.0_dp
    4852      1658347 :                         matso_s = 0.0_dp
    4853     11991674 :                         DO iso = 1, max_iso_not0_local
    4854     33967015 :                            DO icg = 1, cg_n_list(iso)
    4855     21975341 :                               iso1 = cg_list(1, icg, iso)
    4856     21975341 :                               iso2 = cg_list(2, icg, iso)
    4857              : 
    4858     21975341 :                               l = indso(1, iso1) + indso(1, iso2)
    4859              : 
    4860              :                               !test reduce expansion local densities
    4861     21975341 :                               CPASSERT(l <= lmax_expansion)
    4862   1130827378 :                               DO ia = 1, na
    4863              :                                  matso_h(iso1, iso2) = matso_h(iso1, iso2) + &
    4864              :                                                        gVXCg_h(ia, l)* &
    4865              :                                                        harmonics%slm(ia, iso)* &
    4866   1098518710 :                                                        my_CG(iso1, iso2, iso)
    4867              :                                  matso_s(iso1, iso2) = matso_s(iso1, iso2) + &
    4868              :                                                        gVXCg_s(ia, l)* &
    4869              :                                                        harmonics%slm(ia, iso)* &
    4870   1120494051 :                                                        my_CG(iso1, iso2, iso)
    4871              :                               END DO ! ia
    4872              : 
    4873              :                               !test reduce expansion local densities
    4874              : 
    4875              :                            END DO
    4876              : 
    4877              :                         END DO ! iso
    4878              : 
    4879      6395507 :                         DO iso = 1, dmax_iso_not0_local
    4880     42235433 :                            DO icg = 1, dcg_n_list(iso)
    4881     35839926 :                               iso1 = dcg_list(1, icg, iso)
    4882     35839926 :                               iso2 = dcg_list(2, icg, iso)
    4883              : 
    4884     35839926 :                               l = indso(1, iso1) + indso(1, iso2)
    4885              :                               !test reduce expansion local densities
    4886     35839926 :                               CPASSERT(l <= lmax_expansion)
    4887   1831834054 :                               DO ia = 1, na
    4888              :                                  matso_h(iso1, iso2) = matso_h(iso1, iso2) + &
    4889              :                                                        (gVXGg_h(1, ia, l)*my_CG_dxyz(1, iso1, iso2, iso) + &
    4890              :                                                         gVXGg_h(2, ia, l)*my_CG_dxyz(2, iso1, iso2, iso) + &
    4891              :                                                         gVXGg_h(3, ia, l)*my_CG_dxyz(3, iso1, iso2, iso))* &
    4892   1791256968 :                                                        harmonics%slm(ia, iso)
    4893              : 
    4894              :                                  matso_s(iso1, iso2) = matso_s(iso1, iso2) + &
    4895              :                                                        (gVXGg_s(1, ia, l)*my_CG_dxyz(1, iso1, iso2, iso) + &
    4896              :                                                         gVXGg_s(2, ia, l)*my_CG_dxyz(2, iso1, iso2, iso) + &
    4897              :                                                         gVXGg_s(3, ia, l)*my_CG_dxyz(3, iso1, iso2, iso))* &
    4898   1827096894 :                                                        harmonics%slm(ia, iso)
    4899              : 
    4900              :                               END DO ! ia
    4901              : 
    4902              :                               !test reduce expansion local densities
    4903              : 
    4904              :                            END DO ! icg
    4905              :                         END DO ! iso
    4906              :                         !test reduce expansion local densities
    4907              :                      END IF ! lmax_expansion
    4908              : 
    4909              :                      !  Write in the global matrix
    4910      6551864 :                      DO ic = nsoset(lmin(iset2) - 1) + 1, nsoset(lmax(iset2))
    4911      4232318 :                         iso1 = nsoset(lmin(iset1) - 1) + 1
    4912      4232318 :                         iso2 = ngau2 + ic
    4913              :                         CALL daxpy(size1, 1.0_dp, matso_h(iso1, ic), 1, &
    4914      4232318 :                                    int_hh(ispin)%r_coef(nngau1 + 1, iso2), 1)
    4915              :                         CALL daxpy(size1, 1.0_dp, matso_s(iso1, ic), 1, &
    4916      5891265 :                                    int_ss(ispin)%r_coef(nngau1 + 1, iso2), 1)
    4917              :                      END DO
    4918              : 
    4919              :                   END DO ! ipfg2
    4920              :                END DO ! ipfg1
    4921       975850 :                m2 = m2 + maxso
    4922              :             END DO ! iset2
    4923       120819 :             m1 = m1 + maxso
    4924              :          END DO ! iset1
    4925              :       END DO ! ispin
    4926              : 
    4927        30820 :       DEALLOCATE (g1, g2, gg, dgg, matso_h, matso_s, gVXCg_h, gVXCg_s, gVXGg_h, gVXGg_s)
    4928        30820 :       DEALLOCATE (cg_list, cg_n_list, dcg_list, dcg_n_list)
    4929              : 
    4930        30820 :       CALL timestop(handle)
    4931              : 
    4932        30820 :    END SUBROUTINE gaVxcgb_GC
    4933              : 
    4934              : ! **************************************************************************************************
    4935              : !> \brief Integrates 0.5 * grad_ga .dot. (V_tau * grad_gb) on the atomic grid for meta-GGA
    4936              : !> \param vtau_h the hard tau potential
    4937              : !> \param vtau_s the soft tau potential
    4938              : !> \param int_hh hard one-center matrix contribution
    4939              : !> \param int_ss soft one-center matrix contribution
    4940              : !> \param tau_cache precomputed compact one-center gradient basis
    4941              : !> \param nspins number of spin channels
    4942              : !> \note This is a rewrite to correct meta-GGA GAPW bug. This is more brute force than the original
    4943              : !>       but makes sure that no corner is cut in terms of accuracy (A. Bussy)
    4944              : ! **************************************************************************************************
    4945          923 :    SUBROUTINE dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
    4946              :                          tau_cache, nspins)
    4947              : 
    4948              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vtau_h, vtau_s
    4949              :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: int_hh, int_ss
    4950              :       TYPE(tau_basis_cache_type), INTENT(IN)             :: tau_cache
    4951              :       INTEGER, INTENT(IN)                                :: nspins
    4952              : 
    4953              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'dgaVtaudgb'
    4954              : 
    4955              :       INTEGER                                            :: dir, handle, ia, ibas, igrid, iold, ir, &
    4956              :                                                             ispin, jbas, jold, max_old_basis, na, &
    4957              :                                                             nbas, ngrid, nr
    4958          923 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: int_h, int_s, weighted_grad
    4959              : 
    4960          923 :       CALL timeset(routineN, handle)
    4961              : 
    4962          923 :       CPASSERT(ALLOCATED(tau_cache%grad))
    4963          923 :       CPASSERT(ASSOCIATED(tau_cache%n2oindex))
    4964              : 
    4965          923 :       nr = tau_cache%nr
    4966          923 :       na = tau_cache%na
    4967          923 :       nbas = tau_cache%nsatbas
    4968          923 :       ngrid = na*nr
    4969        67728 :       max_old_basis = MAXVAL(tau_cache%n2oindex)
    4970         8307 :       ALLOCATE (int_h(nbas, nbas), int_s(nbas, nbas), weighted_grad(ngrid, nbas))
    4971              : 
    4972         1854 :       DO ispin = 1, nspins
    4973          931 :          CPASSERT(SIZE(int_hh(ispin)%r_coef, 1) >= max_old_basis)
    4974          931 :          CPASSERT(SIZE(int_hh(ispin)%r_coef, 2) >= max_old_basis)
    4975          931 :          CPASSERT(SIZE(int_ss(ispin)%r_coef, 1) >= max_old_basis)
    4976          931 :          CPASSERT(SIZE(int_ss(ispin)%r_coef, 2) >= max_old_basis)
    4977          931 :          int_h = 0.0_dp
    4978          931 :          int_s = 0.0_dp
    4979         3724 :          DO dir = 1, 3
    4980        74556 :             DO ibas = 1, nbas
    4981      3717306 :                DO ir = 1, nr
    4982    189783213 :                   DO ia = 1, na
    4983    186068700 :                      igrid = ia + (ir - 1)*na
    4984              :                      weighted_grad(igrid, ibas) = vtau_h(ia, ir, ispin)* &
    4985    189711450 :                                                   tau_cache%grad(igrid, ibas, dir)
    4986              :                   END DO
    4987              :                END DO
    4988              :             END DO
    4989              :             CALL dgemm('T', 'N', nbas, nbas, ngrid, 0.5_dp, tau_cache%grad(:, :, dir), &
    4990         2793 :                        ngrid, weighted_grad, ngrid, 1.0_dp, int_h, nbas)
    4991              : 
    4992        74556 :             DO ibas = 1, nbas
    4993      3717306 :                DO ir = 1, nr
    4994    189783213 :                   DO ia = 1, na
    4995    186068700 :                      igrid = ia + (ir - 1)*na
    4996              :                      weighted_grad(igrid, ibas) = vtau_s(ia, ir, ispin)* &
    4997    189711450 :                                                   tau_cache%grad(igrid, ibas, dir)
    4998              :                   END DO
    4999              :                END DO
    5000              :             END DO
    5001              :             CALL dgemm('T', 'N', nbas, nbas, ngrid, 0.5_dp, tau_cache%grad(:, :, dir), &
    5002         3724 :                        ngrid, weighted_grad, ngrid, 1.0_dp, int_s, nbas)
    5003              :          END DO
    5004              : 
    5005        25775 :          DO jbas = 1, nbas
    5006        23921 :             jold = tau_cache%n2oindex(jbas)
    5007       959307 :             DO ibas = 1, nbas
    5008       934455 :                iold = tau_cache%n2oindex(ibas)
    5009              :                int_hh(ispin)%r_coef(iold, jold) = int_hh(ispin)%r_coef(iold, jold) + &
    5010       934455 :                                                   int_h(ibas, jbas)
    5011              :                int_ss(ispin)%r_coef(iold, jold) = int_ss(ispin)%r_coef(iold, jold) + &
    5012       958376 :                                                   int_s(ibas, jbas)
    5013              :             END DO
    5014              :          END DO
    5015              :       END DO
    5016              : 
    5017          923 :       DEALLOCATE (int_h, int_s, weighted_grad)
    5018              : 
    5019          923 :       CALL timestop(handle)
    5020              : 
    5021          923 :    END SUBROUTINE dgaVtaudgb
    5022              : 
    5023            0 : END MODULE qs_vxc_atom
        

Generated by: LCOV version 2.0-1