LCOV - code coverage report
Current view: top level - src - qs_vxc_atom.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:24d69ee) Lines: 89.3 % 1690 1510
Test Date: 2026-09-03 07:32:15 Functions: 95.2 % 21 20

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief 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: gto_basis_set_type
      16              :    USE cell_types,                      ONLY: cell_type
      17              :    USE cp_array_utils,                  ONLY: cp_3d_r_cp_type
      18              :    USE cp_control_types,                ONLY: dft_control_type
      19              :    USE cp_log_handling,                 ONLY: cp_logger_get_default_io_unit
      20              :    USE external_potential_types,        ONLY: gth_potential_type,&
      21              :                                               sgp_potential_type
      22              :    USE input_constants,                 ONLY: cdft_alpha_constraint,&
      23              :                                               cdft_beta_constraint,&
      24              :                                               cdft_charge_constraint,&
      25              :                                               cdft_magnetization_constraint,&
      26              :                                               xc_none
      27              :    USE input_section_types,             ONLY: section_get_rval,&
      28              :                                               section_vals_get_subs_vals,&
      29              :                                               section_vals_type,&
      30              :                                               section_vals_val_get
      31              :    USE kinds,                           ONLY: dp,&
      32              :                                               int_8
      33              :    USE lebedev,                         ONLY: deallocate_lebedev_grids,&
      34              :                                               get_number_of_lebedev_grid,&
      35              :                                               init_lebedev_grids,&
      36              :                                               lebedev_grid
      37              :    USE memory_utilities,                ONLY: reallocate
      38              :    USE message_passing,                 ONLY: mp_para_env_type
      39              :    USE orbital_pointers,                ONLY: indco,&
      40              :                                               indso,&
      41              :                                               nco,&
      42              :                                               ncoset,&
      43              :                                               nsoset
      44              :    USE orbital_transformation_matrices, ONLY: orbtramat
      45              :    USE particle_types,                  ONLY: particle_type
      46              :    USE pw_env_types,                    ONLY: pw_env_get,&
      47              :                                               pw_env_type
      48              :    USE pw_grid_types,                   ONLY: pw_grid_type
      49              :    USE pw_methods,                      ONLY: pw_axpy
      50              :    USE pw_pool_types,                   ONLY: pw_pool_type
      51              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      52              :                                               pw_r3d_rs_type
      53              :    USE qs_cdft_grid,                    ONLY: cdft_point_context_create,&
      54              :                                               cdft_point_context_release,&
      55              :                                               cdft_point_context_type,&
      56              :                                               cdft_point_weights
      57              :    USE qs_cdft_types,                   ONLY: cdft_control_type
      58              :    USE qs_environment_types,            ONLY: get_qs_env,&
      59              :                                               qs_environment_type
      60              :    USE qs_force_types,                  ONLY: qs_force_type
      61              :    USE qs_grid_atom,                    ONLY: allocate_grid_atom,&
      62              :                                               create_grid_atom,&
      63              :                                               grid_atom_type
      64              :    USE qs_harmonics_atom,               ONLY: harmonics_atom_type
      65              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      66              :                                               has_nlcc,&
      67              :                                               qs_kind_type
      68              :    USE qs_linres_types,                 ONLY: nablavks_atom_type
      69              :    USE qs_rho_atom_methods,             ONLY: replicate_rho_atom_radial
      70              :    USE qs_rho_atom_types,               ONLY: get_rho_atom,&
      71              :                                               rho_atom_coeff,&
      72              :                                               rho_atom_type
      73              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      74              :                                               qs_rho_type
      75              :    USE qs_vxc_atom_utils,               ONLY: &
      76              :         calc_rho_angular, calc_rho_nlcc, calc_tau_atom, create_tau_basis_cache, dgaVtaudgb, &
      77              :         evaluate_nlcc_primitive_fields, gaVxcgb_GC, gaVxcgb_noGC, gapw_atom_grid_support_radius, &
      78              :         release_tau_basis_cache, tau_basis_cache_type
      79              :    USE skala_gpw_features,              ONLY: build_periodic_atom_image_layout,&
      80              :                                               periodic_atom_image_partition,&
      81              :                                               periodic_atom_image_partition_from_layout,&
      82              :                                               skala_gpw_smooth_partition_derivatives,&
      83              :                                               smooth_atom_partition,&
      84              :                                               smooth_partition_atomic_weight_scale,&
      85              :                                               smooth_partition_atomic_weight_scale_derivative
      86              :    USE skala_gpw_functional,            ONLY: &
      87              :         build_vxc_from_feature_grads, get_gauxc_section, native_skala_gapw_density_partition, &
      88              :         skala_gapw_atom_composite_energy, skala_gapw_atom_vxc_of_r, &
      89              :         skala_gapw_density_partition_hard_minus_soft, skala_gapw_density_partition_hard_only, &
      90              :         skala_gapw_density_partition_none, skala_gapw_density_partition_soft_only, &
      91              :         xc_section_uses_gauxc_model, xc_section_uses_native_skala_evaluator
      92              :    USE spherical_harmonics,             ONLY: y_lm
      93              :    USE util,                            ONLY: get_limit
      94              :    USE virial_types,                    ONLY: virial_type
      95              :    USE xc_atom,                         ONLY: fill_rho_set,&
      96              :                                               vxc_of_r_epr,&
      97              :                                               vxc_of_r_new,&
      98              :                                               xc_rho_set_atom_update
      99              :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
     100              :                                               xc_dset_create,&
     101              :                                               xc_dset_release,&
     102              :                                               xc_dset_zero_all
     103              :    USE xc_derivatives,                  ONLY: xc_functionals_get_needs
     104              :    USE xc_input_constants,              ONLY: skala_gapw_cp2k_default,&
     105              :                                               skala_gapw_direct_valence,&
     106              :                                               skala_gapw_paw_one_center,&
     107              :                                               skala_gapw_paw_one_center_split
     108              :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
     109              :    USE xc_rho_set_types,                ONLY: xc_rho_set_create,&
     110              :                                               xc_rho_set_get,&
     111              :                                               xc_rho_set_release,&
     112              :                                               xc_rho_set_type,&
     113              :                                               xc_rho_set_update
     114              : #include "./base/base_uses.f90"
     115              : 
     116              :    IMPLICIT NONE
     117              : 
     118              :    PRIVATE
     119              : 
     120              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_vxc_atom'
     121              : 
     122              :    ! The wider stencil suppresses mixed-kind eggbox forces while preserving an exact transpose.
     123              :    INTEGER, PARAMETER, PRIVATE :: native_grid_interp_offset_min = -5, &
     124              :                                   native_grid_interp_offset_max = 6, &
     125              :                                   native_grid_interp_npts = &
     126              :                                   native_grid_interp_offset_max - &
     127              :                                   native_grid_interp_offset_min + 1
     128              :    ! A wrapped stencil can touch both end tiles and one adjacent interior tile when the final
     129              :    ! tile is shorter than the stencil. Three tiles per direction are therefore sufficient.
     130              :    INTEGER, PARAMETER, PRIVATE :: native_grid_adjoint_tile_edge = 64, &
     131              :                                   native_grid_adjoint_max_tiles_per_direction = 3, &
     132              :                                   native_grid_adjoint_max_bins_per_row = &
     133              :                                   native_grid_adjoint_max_tiles_per_direction**3
     134              : 
     135              :    TYPE native_grid_interpolation_stencil_type
     136              :       INTEGER, DIMENSION(native_grid_interp_npts, 3)     :: relative_index = 0
     137              :       REAL(KIND=dp), DIMENSION(native_grid_interp_npts, 3) :: weight = 0.0_dp
     138              :       LOGICAL, DIMENSION(native_grid_interp_npts, 3)     :: valid = .FALSE.
     139              :       LOGICAL                                            :: active = .FALSE.
     140              :    END TYPE native_grid_interpolation_stencil_type
     141              : 
     142              :    PUBLIC :: calculate_vxc_atom, &
     143              :              calculate_vxc_atom_epr, &
     144              :              gapw_cdft_one_center
     145              : 
     146              : ! **************************************************************************************************
     147              : 
     148              : CONTAINS
     149              : 
     150              : ! **************************************************************************************************
     151              : !> \brief Initialize atom-centered quadrature for native Skala layouts.
     152              : !> \param kind_set quantum kinds
     153              : !> \param dft_control DFT controls supplying the radial quadrature
     154              : ! **************************************************************************************************
     155          264 :    SUBROUTINE ensure_native_skala_atom_grids(kind_set, dft_control)
     156              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: kind_set
     157              :       TYPE(dft_control_type), POINTER                    :: dft_control
     158              : 
     159              :       INTEGER                                            :: ikind, ll, na, nr, quadrature
     160              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
     161              : 
     162          264 :       quadrature = dft_control%qs_control%gapw_control%quadrature
     163          264 :       CALL init_lebedev_grids()
     164          574 :       DO ikind = 1, SIZE(kind_set)
     165          310 :          NULLIFY (grid_atom)
     166          310 :          CALL get_qs_kind(kind_set(ikind), grid_atom=grid_atom, ngrid_ang=na, ngrid_rad=nr)
     167          310 :          IF (ASSOCIATED(grid_atom)) THEN
     168          284 :             IF (ASSOCIATED(grid_atom%weight) .AND. grid_atom%nr == nr) CYCLE
     169              :          ELSE
     170           26 :             CALL allocate_grid_atom(kind_set(ikind)%grid_atom)
     171           26 :             grid_atom => kind_set(ikind)%grid_atom
     172              :          END IF
     173           26 :          ll = get_number_of_lebedev_grid(n=na)
     174           26 :          na = lebedev_grid(ll)%n
     175           26 :          grid_atom%ng_sphere = na
     176           26 :          grid_atom%nr = nr
     177          600 :          CALL create_grid_atom(grid_atom, nr, na, 0, ll, quadrature)
     178              :       END DO
     179          264 :       CALL deallocate_lebedev_grids()
     180              : 
     181          264 :    END SUBROUTINE ensure_native_skala_atom_grids
     182              : 
     183              : ! **************************************************************************************************
     184              : !> \brief Decide whether a kind contributes hard-minus-soft primitive fields.
     185              : !> \param paw_atom whether CP2K constructed a one-center representation for the kind
     186              : !> \param gapw_representation requested Skala pseudopotential GAPW representation
     187              : !> \param has_pseudopotential whether the kind uses a GTH or semi-global pseudopotential
     188              : !> \param zeff valence charge of the potential
     189              : !> \param zatom atomic number
     190              : !> \return true when hard-minus-soft fields contribute for this kind
     191              : ! **************************************************************************************************
     192          564 :    PURE FUNCTION native_skala_uses_one_center_kind( &
     193              :       paw_atom, gapw_representation, has_pseudopotential, zeff, zatom) RESULT(use_one_center)
     194              :       LOGICAL, INTENT(IN)                                :: paw_atom
     195              :       INTEGER, INTENT(IN)                                :: gapw_representation
     196              :       LOGICAL, INTENT(IN)                                :: has_pseudopotential
     197              :       REAL(dp), INTENT(IN)                               :: zeff
     198              :       INTEGER, INTENT(IN)                                :: zatom
     199              :       LOGICAL                                            :: use_one_center
     200              : 
     201          564 :       use_one_center = paw_atom
     202          564 :       IF (.NOT. use_one_center) RETURN
     203              : 
     204          620 :       SELECT CASE (gapw_representation)
     205              :       CASE (skala_gapw_direct_valence)
     206           70 :          use_one_center = .NOT. has_pseudopotential
     207              :       CASE (skala_gapw_paw_one_center, skala_gapw_paw_one_center_split)
     208           16 :          CONTINUE
     209              :       CASE (skala_gapw_cp2k_default)
     210           16 :          IF (has_pseudopotential .AND. &
     211          566 :              ABS(zeff - REAL(zatom, dp)) <= 1.0E-10_dp) use_one_center = .FALSE.
     212              :       END SELECT
     213              : 
     214              :    END FUNCTION native_skala_uses_one_center_kind
     215              : 
     216              : ! **************************************************************************************************
     217              : !> \brief ...
     218              : !> \param qs_env ...
     219              : !> \param energy_only ...
     220              : !> \param exc1 the on-body ex energy contribution
     221              : !> \param adiabatic_rescale_factor ...
     222              : !> \param kind_set_external provides a non-default kind_set to use
     223              : !> \param rho_atom_set_external provides a non-default atomic density set to use
     224              : !> \param xc_section_external provides an external non-default XC
     225              : !> \param calculate_forces ...
     226              : !> \param composite_vxc_rho ...
     227              : !> \param composite_vxc_tau ...
     228              : !> \param composite_reference_active ...
     229              : !> \param direct_valence_atom_grid evaluate the smooth valence fields on atom-centered grids
     230              : !> \param atom_composite_grid evaluate GAPW primitive fields on atom-centered composite grids
     231              : ! **************************************************************************************************
     232        32842 :    SUBROUTINE calculate_vxc_atom(qs_env, energy_only, exc1, &
     233              :                                  adiabatic_rescale_factor, kind_set_external, &
     234              :                                  rho_atom_set_external, xc_section_external, calculate_forces, &
     235              :                                  composite_vxc_rho, composite_vxc_tau, composite_reference_active, &
     236              :                                  direct_valence_atom_grid, atom_composite_grid)
     237              : 
     238              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     239              :       LOGICAL, INTENT(IN)                                :: energy_only
     240              :       REAL(dp), INTENT(INOUT)                            :: exc1
     241              :       REAL(dp), INTENT(IN), OPTIONAL                     :: adiabatic_rescale_factor
     242              :       TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
     243              :          POINTER                                         :: kind_set_external
     244              :       TYPE(rho_atom_type), DIMENSION(:), OPTIONAL, &
     245              :          POINTER                                         :: rho_atom_set_external
     246              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: xc_section_external
     247              :       LOGICAL, INTENT(IN), OPTIONAL                      :: calculate_forces
     248              :       TYPE(pw_r3d_rs_type), DIMENSION(:), OPTIONAL, &
     249              :          POINTER                                         :: composite_vxc_rho, composite_vxc_tau
     250              :       LOGICAL, INTENT(OUT), OPTIONAL                     :: composite_reference_active
     251              :       LOGICAL, INTENT(IN), OPTIONAL                      :: direct_valence_atom_grid, &
     252              :                                                             atom_composite_grid
     253              : 
     254              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_vxc_atom'
     255              : 
     256              :       INTEGER :: adjoint_bin, adjoint_entry, adjoint_nbins, adjoint_nchannels, &
     257              :          adjoint_tile_count(3), adjoint_tile_lower(3), adjoint_tile_upper(3), &
     258              :          atom_composite_components, base_shift(3), bo(2), composite_descriptor_target_image, &
     259              :          composite_image_periodicity(3), composite_local_atom, composite_local_natom, &
     260              :          composite_nflat, composite_partition_target_image, composite_pw_nflat, composite_row, &
     261              :          gapw_density_partition, gapw_representation, handle, ia, iat, iatom, icomponent, idir, &
     262              :          ikind, image_i1, image_i2, image_i3, image_shell(3), image_shift(3), ir, ispin, iw, jdir, &
     263              :          myfun, na, natom, nr, nspins
     264              :       INTEGER :: num_pe, source_atom, target_atom, xc_deriv_method_id, xc_rho_smooth_id, zatom
     265        32842 :       INTEGER(KIND=int_8), ALLOCATABLE, DIMENSION(:)     :: composite_atomic_grid_sizes, &
     266        32842 :                                                             composite_local_grid_sizes
     267        32842 :       INTEGER, ALLOCATABLE, DIMENSION(:) :: adjoint_bin_offsets, adjoint_bin_rows, &
     268        32842 :          composite_atom_end, composite_atom_kind, composite_atom_kind_index, composite_atom_start, &
     269        32842 :          composite_grid_atom, composite_local_atoms
     270              :       INTEGER, DIMENSION(2, 3)                           :: bounds
     271        32842 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     272              :       LOGICAL :: accint, atom_composite_active, atom_composite_diagnostic, &
     273              :          atom_composite_reference, direct_valence_atom_composite, donlcc, evaluate_hard, &
     274              :          evaluate_soft, gradient_f, image_partition_atom_composite, lsd, my_calculate_forces, &
     275              :          native_grid_diagnostics, nlcc, one_center_kind, paw_atom, paw_pseudopotentials, &
     276              :          requested_atom_composite_grid, rho_g_valid, skala_atom_grid, source_matrix_local, tau_f, &
     277              :          tau_r_valid, use_atom_composite_density, use_atom_composite_gradient, &
     278              :          use_atom_composite_tau, use_virial
     279        32842 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: composite_partition_included
     280              :       REAL(dp) :: agr, alpha, atom_composite_exc, atom_composite_nelec, &
     281              :          composite_cross_cutoff_max, composite_cross_density_max, composite_cross_grad_max, &
     282              :          composite_cross_kin_max, composite_density_max, composite_density_min, &
     283              :          composite_grad_max, composite_kin_max, composite_kin_min, composite_tau_integral, &
     284              :          cross_cutoff, density_cut, descriptor_window_adjoint, descriptor_window_weight, exc_h, &
     285              :          exc_s, feature_vxc_analytic, feature_vxc_fd, feature_vxc_minus, feature_vxc_plus, &
     286              :          feature_vxc_step, gradient_cut, local_partition_weight, my_adiabatic_rescale_factor, &
     287              :          nlcc_density, nlcc_spin_factor
     288              :       REAL(dp) :: one_center_density_field_contraction, one_center_density_matrix_contraction, &
     289              :          one_center_field_contraction, one_center_gradient_field_contraction, &
     290              :          one_center_gradient_matrix_contraction, one_center_matrix_contraction, &
     291              :          one_center_rho_grad_field_contraction, one_center_rho_grad_matrix_contraction, &
     292              :          one_center_tau_field_contraction, one_center_tau_matrix_contraction, &
     293              :          one_center_tensor_contraction, partition_adjoint, partition_scale, partition_weight, &
     294              :          smooth_grid_contraction, smooth_input_contraction, target_partition_adjoint, tau_cut, zeff
     295        32842 :       REAL(dp), ALLOCATABLE, DIMENSION(:) :: composite_atomic_grid_weight_grad, &
     296        32842 :          composite_atomic_grid_weights, composite_base_grid_weights, composite_distances, &
     297        32842 :          composite_grid_weight_grad, composite_grid_weights, composite_partition_weights
     298        32842 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: composite_atom_coord_grad, composite_atom_coords, &
     299        32842 :          composite_cross_density, composite_cross_force, composite_cross_force_local, &
     300        32842 :          composite_cross_kin, composite_density, composite_density_grad, &
     301        32842 :          composite_descriptor_image_coords, composite_explicit_force, composite_grid_coord_force, &
     302        32842 :          composite_grid_coord_grad, composite_grid_coords, composite_kin, composite_kin_grad, &
     303        32842 :          composite_local_atom_coords, composite_model_atom_force, composite_moving_smooth_force, &
     304        32842 :          composite_nlcc_center_force, composite_nlcc_center_force_local, &
     305        32842 :          composite_nlcc_target_force
     306        32842 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: composite_partition_atom_coords, &
     307        32842 :          composite_partition_force, composite_partition_force_local, &
     308        32842 :          composite_partition_image_coords, composite_smooth_density_cache, &
     309        65684 :          composite_smooth_kin_cache, local_partition_datom
     310        32842 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :), TARGET     :: smooth_density_adjoint_storage, &
     311        32842 :                                                             smooth_kin_adjoint_storage
     312        32842 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :) :: composite_cross_grad, composite_grad, &
     313        32842 :          composite_grad_grad, composite_int_h, composite_int_s, composite_partition_datom, &
     314        65684 :          composite_partition_dstrain, composite_smooth_gradient_cache
     315        32842 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :), TARGET  :: smooth_grad_adjoint_storage
     316              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
     317              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
     318              :       REAL(dp), DIMENSION(2) :: composite_smooth_density_adjoint_value, &
     319              :          composite_smooth_density_value, composite_smooth_kin_adjoint_value, &
     320              :          composite_smooth_kin_value, cross_density, cross_density_adjoint, cross_kin, &
     321              :          cross_kin_adjoint
     322              :       REAL(dp), DIMENSION(3) :: composite_point, cross_displacement, cross_spatial_derivative, &
     323              :          fractional, image_translation, nlcc_gradient, nlcc_spatial_derivative, &
     324              :          skala_atom_force_h, skala_atom_force_s, spatial_derivative
     325              :       REAL(dp), DIMENSION(3, 1)                          :: local_descriptor_datom
     326              :       REAL(dp), DIMENSION(3, 2) :: composite_smooth_gradient_adjoint_value, &
     327              :          composite_smooth_gradient_value, cross_density_spatial, cross_grad, cross_grad_adjoint, &
     328              :          cross_kin_spatial
     329              :       REAL(dp), DIMENSION(3, 3) :: composite_cross_image_virial, &
     330              :          composite_cross_image_virial_local, composite_explicit_virial, composite_feature_virial, &
     331              :          composite_interpolation_virial, composite_partition_strain_virial, &
     332              :          local_descriptor_dstrain, local_partition_dstrain, nlcc_hessian, skala_atom_virial, &
     333              :          skala_atom_virial_h, skala_atom_virial_s
     334              :       REAL(dp), DIMENSION(3, 3, 2)                       :: cross_grad_spatial
     335              :       REAL(dp), DIMENSION(4)                             :: feature_component_analytic, &
     336              :                                                             feature_component_fd
     337        65684 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, smooth_density_adjoint, &
     338        65684 :                                                             smooth_kin_adjoint, weight_h, weight_s
     339        32842 :       REAL(dp), DIMENSION(:, :, :), POINTER :: composite_smooth_rho, composite_smooth_rhoa, &
     340        32842 :          composite_smooth_rhob, composite_smooth_tau, composite_smooth_tau_a, &
     341       131368 :          composite_smooth_tau_b, rho_h, rho_s, smooth_grad_adjoint, smooth_rho, smooth_rhoa, &
     342        32842 :          smooth_rhob, smooth_tau, smooth_tau_a, smooth_tau_b, tau_h, tau_s, vtau_h, vtau_s, vxc_h, &
     343        32842 :          vxc_s
     344        65684 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho_h, drho_s, vxg_h, vxg_s
     345        32842 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     346              :       TYPE(cell_type), POINTER                           :: cell
     347       229894 :       TYPE(cp_3d_r_cp_type), DIMENSION(3) :: composite_smooth_drho, composite_smooth_drhoa, &
     348       459788 :          composite_smooth_drhob, smooth_drho, smooth_drhoa, smooth_drhob
     349              :       TYPE(dft_control_type), POINTER                    :: dft_control
     350              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
     351              :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     352              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
     353              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
     354              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     355              :       TYPE(native_grid_interpolation_stencil_type)       :: interpolation_stencil
     356        32842 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     357        32842 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: smooth_rho_g
     358              :       TYPE(pw_env_type), POINTER                         :: pw_env
     359              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     360        65684 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: smooth_rho_r, smooth_tau_r, &
     361        32842 :                                                             smooth_vxc_rho, smooth_vxc_tau
     362        32842 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     363        32842 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: my_kind_set
     364              :       TYPE(qs_rho_type), POINTER                         :: rho_struct
     365        32842 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: cpc_h, cpc_s, dr_h, dr_s, int_hh, &
     366        65684 :                                                             int_ss, r_h, r_s
     367        32842 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
     368        32842 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: my_rho_atom_set
     369              :       TYPE(rho_atom_type), POINTER                       :: rho_atom
     370              :       TYPE(section_vals_type), POINTER                   :: gauxc_section, input, my_xc_section, &
     371              :                                                             xc_fun_section
     372              :       TYPE(sgp_potential_type), POINTER                  :: sgp_potential
     373        32842 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
     374              :       TYPE(virial_type), POINTER                         :: virial
     375              :       TYPE(xc_derivative_set_type)                       :: deriv_set
     376              :       TYPE(xc_rho_cflags_type)                           :: needs
     377              :       TYPE(xc_rho_set_type)                              :: rho_set_h, rho_set_s, smooth_rho_set
     378              : 
     379              : ! -------------------------------------------------------------------------
     380              : 
     381        32842 :       CALL timeset(routineN, handle)
     382              : 
     383        32842 :       NULLIFY (atom_list)
     384        32842 :       NULLIFY (auxbas_pw_pool)
     385        32842 :       NULLIFY (my_kind_set)
     386        32842 :       NULLIFY (atomic_kind_set)
     387        32842 :       NULLIFY (cell)
     388        32842 :       NULLIFY (grid_atom)
     389        32842 :       NULLIFY (gth_potential)
     390        32842 :       NULLIFY (force)
     391        32842 :       NULLIFY (harmonics)
     392        32842 :       NULLIFY (input)
     393        32842 :       NULLIFY (para_env)
     394        32842 :       NULLIFY (particle_set)
     395        32842 :       NULLIFY (pw_env)
     396        32842 :       NULLIFY (rho_atom)
     397        32842 :       NULLIFY (rho_struct)
     398        32842 :       NULLIFY (my_rho_atom_set)
     399        32842 :       NULLIFY (rho_nlcc)
     400        32842 :       NULLIFY (smooth_rho, smooth_rhoa, smooth_rhob, smooth_tau, smooth_tau_a, smooth_tau_b)
     401        32842 :       NULLIFY (composite_smooth_rho, composite_smooth_rhoa, composite_smooth_rhob, &
     402        32842 :                composite_smooth_tau, composite_smooth_tau_a, composite_smooth_tau_b)
     403        32842 :       NULLIFY (smooth_rho_g, smooth_rho_r, smooth_tau_r)
     404        32842 :       NULLIFY (smooth_vxc_rho, smooth_vxc_tau)
     405       131368 :       DO idir = 1, 3
     406        98526 :          NULLIFY (smooth_drho(idir)%array, smooth_drhoa(idir)%array, smooth_drhob(idir)%array)
     407              :          NULLIFY (composite_smooth_drho(idir)%array, &
     408        98526 :                   composite_smooth_drhoa(idir)%array, &
     409       131368 :                   composite_smooth_drhob(idir)%array)
     410              :       END DO
     411        32842 :       NULLIFY (sgp_potential)
     412        32842 :       NULLIFY (virial)
     413        32842 :       my_calculate_forces = .FALSE.
     414        32842 :       IF (PRESENT(calculate_forces)) my_calculate_forces = calculate_forces
     415        32842 :       IF (PRESENT(composite_reference_active)) composite_reference_active = .FALSE.
     416        32842 :       direct_valence_atom_composite = .FALSE.
     417        32842 :       IF (PRESENT(direct_valence_atom_grid)) THEN
     418          136 :          direct_valence_atom_composite = direct_valence_atom_grid
     419              :       END IF
     420        32842 :       requested_atom_composite_grid = .FALSE.
     421        32842 :       IF (PRESENT(atom_composite_grid)) requested_atom_composite_grid = atom_composite_grid
     422              : 
     423        32842 :       IF (PRESENT(adiabatic_rescale_factor)) THEN
     424           44 :          my_adiabatic_rescale_factor = adiabatic_rescale_factor
     425              :       ELSE
     426        32798 :          my_adiabatic_rescale_factor = 1.0_dp
     427              :       END IF
     428              : 
     429              :       CALL get_qs_env(qs_env=qs_env, &
     430              :                       dft_control=dft_control, &
     431              :                       cell=cell, &
     432              :                       para_env=para_env, &
     433              :                       atomic_kind_set=atomic_kind_set, &
     434              :                       qs_kind_set=my_kind_set, &
     435              :                       input=input, &
     436              :                       particle_set=particle_set, &
     437              :                       pw_env=pw_env, &
     438              :                       virial=virial, &
     439              :                       rho_atom_set=my_rho_atom_set, &
     440        32842 :                       force=force)
     441              : 
     442        32842 :       IF (dft_control%qs_control%gapw_xc) THEN
     443         5428 :          CALL get_qs_env(qs_env=qs_env, rho_xc=rho_struct)
     444              :       ELSE
     445        27414 :          CALL get_qs_env(qs_env=qs_env, rho=rho_struct)
     446              :       END IF
     447              : 
     448        32842 :       IF (PRESENT(kind_set_external)) my_kind_set => kind_set_external
     449        32842 :       IF (PRESENT(rho_atom_set_external)) my_rho_atom_set => rho_atom_set_external
     450              : 
     451        32842 :       nlcc = has_nlcc(my_kind_set)
     452        32842 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
     453              : 
     454        32842 :       my_xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     455              : 
     456        32842 :       IF (PRESENT(xc_section_external)) my_xc_section => xc_section_external
     457              : 
     458        32842 :       xc_fun_section => section_vals_get_subs_vals(my_xc_section, "XC_FUNCTIONAL")
     459              :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", &
     460        32842 :                                 i_val=myfun)
     461        32842 :       skala_atom_grid = xc_section_uses_gauxc_model(my_xc_section)
     462        32842 :       gapw_representation = skala_gapw_cp2k_default
     463        32842 :       atom_composite_diagnostic = .FALSE.
     464        32842 :       atom_composite_reference = .FALSE.
     465        32842 :       paw_pseudopotentials = .FALSE.
     466        32842 :       native_grid_diagnostics = .FALSE.
     467        32842 :       atom_composite_components = 1
     468        32842 :       feature_vxc_step = 3.0E-3_dp
     469        32842 :       IF (skala_atom_grid) THEN
     470          282 :          gauxc_section => get_gauxc_section(my_xc_section)
     471          282 :          CPASSERT(ASSOCIATED(gauxc_section))
     472              :          CALL section_vals_val_get(gauxc_section, "PSEUDOPOTENTIAL_GAPW_REPRESENTATION", &
     473          282 :                                    i_val=gapw_representation)
     474              :          CALL section_vals_val_get(gauxc_section, "NATIVE_GRID_DIAGNOSTICS", &
     475          282 :                                    l_val=native_grid_diagnostics)
     476              :       END IF
     477              :       IF (skala_atom_grid) THEN
     478          610 :          DO ikind = 1, SIZE(my_kind_set)
     479          328 :             NULLIFY (gth_potential, sgp_potential)
     480              :             CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     481          328 :                              gth_potential=gth_potential, sgp_potential=sgp_potential)
     482              :             paw_pseudopotentials = paw_pseudopotentials .OR. &
     483              :                                    (paw_atom .AND. (ASSOCIATED(gth_potential) .OR. &
     484          784 :                                                     ASSOCIATED(sgp_potential)))
     485              :          END DO
     486              :       END IF
     487        32842 :       IF (skala_atom_grid .AND. xc_section_uses_native_skala_evaluator(my_xc_section)) THEN
     488              :          CALL section_vals_val_get(gauxc_section, &
     489              :                                    "NATIVE_GRID_GAPW_ATOM_COMPOSITE_DIAGNOSTIC", &
     490          280 :                                    l_val=atom_composite_diagnostic)
     491              :          CALL section_vals_val_get(gauxc_section, &
     492              :                                    "NATIVE_GRID_GAPW_ATOM_COMPOSITE_REFERENCE", &
     493          280 :                                    l_val=atom_composite_reference)
     494              :          CALL section_vals_val_get(gauxc_section, &
     495              :                                    "NATIVE_GRID_GAPW_ATOM_COMPOSITE_COMPONENTS", &
     496          280 :                                    i_val=atom_composite_components)
     497              :          CALL section_vals_val_get(gauxc_section, &
     498              :                                    "NATIVE_GRID_GAPW_ATOM_COMPOSITE_FD_STEP", &
     499          280 :                                    r_val=feature_vxc_step)
     500              :       END IF
     501              :       atom_composite_reference = atom_composite_reference .OR. &
     502              :                                  (gapw_representation == skala_gapw_paw_one_center .AND. &
     503        32842 :                                   paw_pseudopotentials)
     504        32842 :       atom_composite_reference = atom_composite_reference .OR. requested_atom_composite_grid
     505        32842 :       atom_composite_reference = atom_composite_reference .OR. direct_valence_atom_composite
     506        32842 :       atom_composite_active = atom_composite_diagnostic .OR. atom_composite_reference
     507        32842 :       use_atom_composite_density = atom_composite_components <= 2
     508        32842 :       use_atom_composite_gradient = atom_composite_components <= 2
     509              :       use_atom_composite_tau = atom_composite_components == 1 .OR. &
     510        32842 :                                atom_composite_components == 3
     511        32842 :       IF (atom_composite_active) THEN
     512          264 :          CALL ensure_native_skala_atom_grids(my_kind_set, dft_control)
     513              :       END IF
     514        32842 :       IF (direct_valence_atom_composite) THEN
     515          136 :          use_atom_composite_density = .FALSE.
     516          136 :          use_atom_composite_gradient = .FALSE.
     517          136 :          use_atom_composite_tau = .FALSE.
     518              :       END IF
     519              :       ! CP2K's auxiliary PW fields are represented on one index-periodic cell even
     520              :       ! when the physical Poisson problem is isolated or partially periodic.
     521        32842 :       image_partition_atom_composite = atom_composite_active
     522       131368 :       composite_image_periodicity = 1
     523        32842 :       IF (PRESENT(composite_reference_active)) composite_reference_active = atom_composite_reference
     524        32842 :       gapw_density_partition = skala_gapw_density_partition_hard_minus_soft
     525        32842 :       IF (skala_atom_grid) THEN
     526          282 :          gapw_density_partition = native_skala_gapw_density_partition(my_xc_section)
     527              :       END IF
     528        32842 :       use_virial = ASSOCIATED(virial)
     529        32842 :       IF (use_virial) use_virial = my_calculate_forces .AND. &
     530        32842 :                                    virial%pv_calculate .AND. (.NOT. virial%pv_numer)
     531              : 
     532        32842 :       IF (myfun == xc_none) THEN
     533         4212 :          exc1 = 0.0_dp
     534        16474 :          my_rho_atom_set(:)%exc_h = 0.0_dp
     535        16474 :          my_rho_atom_set(:)%exc_s = 0.0_dp
     536              :       ELSE
     537              :          CALL section_vals_val_get(my_xc_section, "DENSITY_CUTOFF", &
     538        28630 :                                    r_val=density_cut)
     539              :          CALL section_vals_val_get(my_xc_section, "GRADIENT_CUTOFF", &
     540        28630 :                                    r_val=gradient_cut)
     541              :          CALL section_vals_val_get(my_xc_section, "TAU_CUTOFF", &
     542        28630 :                                    r_val=tau_cut)
     543              : 
     544        28630 :          lsd = dft_control%lsd
     545        28630 :          nspins = dft_control%nspins
     546              :          needs = xc_functionals_get_needs(xc_fun_section, &
     547              :                                           lsd=lsd, &
     548        28630 :                                           calc_potential=.TRUE.)
     549              : 
     550        28630 :          gradient_f = (needs%drho .OR. needs%drho_spin) .OR. skala_atom_grid
     551        28630 :          tau_f = (needs%tau .OR. needs%tau_spin) .OR. skala_atom_grid
     552              : 
     553        28630 :          IF (atom_composite_active) THEN
     554          264 :             IF (lsd) THEN
     555           42 :                needs%rho_spin = .TRUE.
     556           42 :                needs%drho_spin = .TRUE.
     557           42 :                needs%tau_spin = .TRUE.
     558              :             ELSE
     559          222 :                needs%rho = .TRUE.
     560          222 :                needs%drho = .TRUE.
     561          222 :                needs%tau = .TRUE.
     562              :             END IF
     563              : 
     564              :             ALLOCATE (composite_atomic_grid_sizes(SIZE(particle_set)), &
     565            0 :                       composite_atom_kind(SIZE(particle_set)), &
     566              :                       composite_atom_kind_index(SIZE(particle_set)), &
     567            0 :                       composite_atom_start(SIZE(particle_set)), &
     568            0 :                       composite_atom_end(SIZE(particle_set)), &
     569            0 :                       composite_atom_coords(3, SIZE(particle_set)), &
     570            0 :                       composite_partition_weights(SIZE(particle_set)), &
     571            0 :                       composite_partition_atom_coords(3, SIZE(particle_set)), &
     572         3432 :                       composite_distances(SIZE(particle_set)))
     573          264 :             composite_atomic_grid_sizes = 0_int_8
     574          264 :             composite_atom_kind = 0
     575          264 :             composite_atom_kind_index = 0
     576          264 :             composite_atom_start = 0
     577          264 :             composite_atom_end = 0
     578          794 :             DO iatom = 1, SIZE(particle_set)
     579         2384 :                composite_atom_coords(:, iatom) = particle_set(iatom)%r
     580              :             END DO
     581          574 :             DO ikind = 1, SIZE(atomic_kind_set)
     582          310 :                CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     583          310 :                NULLIFY (gth_potential, sgp_potential)
     584              :                CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     585              :                                 gth_potential=gth_potential, grid_atom=grid_atom, &
     586          310 :                                 sgp_potential=sgp_potential, zatom=zatom, zeff=zeff)
     587         1104 :                DO iat = 1, natom
     588          530 :                   iatom = atom_list(iat)
     589          530 :                   composite_atomic_grid_sizes(iatom) = INT(grid_atom%nr*grid_atom%ng_sphere, KIND=int_8)
     590          530 :                   composite_atom_kind(iatom) = ikind
     591          840 :                   composite_atom_kind_index(iatom) = iat
     592              :                END DO
     593              :             END DO
     594          794 :             IF (ANY(composite_atomic_grid_sizes <= 0_int_8)) THEN
     595              :                CALL cp_abort(__LOCATION__, &
     596            0 :                              "The atom-composite diagnostic requires a GAPW one-center grid for every atom.")
     597              :             END IF
     598              : 
     599          264 :             composite_local_natom = 0
     600          574 :             DO ikind = 1, SIZE(atomic_kind_set)
     601          310 :                CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     602          310 :                NULLIFY (gth_potential, sgp_potential)
     603              :                CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     604              :                                 gth_potential=gth_potential, sgp_potential=sgp_potential, &
     605          310 :                                 zatom=zatom, zeff=zeff)
     606          310 :                bo = get_limit(natom, para_env%num_pe, para_env%mepos)
     607          884 :                composite_local_natom = composite_local_natom + MAX(0, bo(2) - bo(1) + 1)
     608              :             END DO
     609            0 :             ALLOCATE (composite_local_atoms(composite_local_natom), &
     610              :                       composite_local_grid_sizes(composite_local_natom), &
     611         1782 :                       composite_local_atom_coords(3, composite_local_natom))
     612          264 :             composite_local_atom = 0
     613          264 :             composite_nflat = 0
     614          574 :             DO ikind = 1, SIZE(atomic_kind_set)
     615          310 :                CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     616          310 :                NULLIFY (gth_potential, sgp_potential)
     617              :                CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     618              :                                 gth_potential=gth_potential, sgp_potential=sgp_potential, &
     619          310 :                                 zatom=zatom, zeff=zeff)
     620          310 :                bo = get_limit(natom, para_env%num_pe, para_env%mepos)
     621         1149 :                DO iat = bo(1), bo(2)
     622          265 :                   iatom = atom_list(iat)
     623          265 :                   composite_local_atom = composite_local_atom + 1
     624          265 :                   composite_local_atoms(composite_local_atom) = iatom
     625              :                   composite_local_grid_sizes(composite_local_atom) = &
     626          265 :                      composite_atomic_grid_sizes(iatom)
     627              :                   composite_local_atom_coords(:, composite_local_atom) = &
     628         1060 :                      composite_atom_coords(:, iatom)
     629          265 :                   composite_atom_start(iatom) = composite_nflat + 1
     630          265 :                   composite_nflat = composite_nflat + INT(composite_atomic_grid_sizes(iatom))
     631          575 :                   composite_atom_end(iatom) = composite_nflat
     632              :                END DO
     633              :             END DO
     634          264 :             CPASSERT(composite_local_atom == composite_local_natom)
     635            0 :             ALLOCATE (composite_density(composite_nflat, 2), &
     636            0 :                       composite_grad(composite_nflat, 3, 2), &
     637            0 :                       composite_kin(composite_nflat, 2), &
     638            0 :                       composite_grid_atom(composite_nflat), &
     639            0 :                       composite_smooth_density_cache(composite_nflat, 2), &
     640            0 :                       composite_smooth_gradient_cache(composite_nflat, 3, 2), &
     641            0 :                       composite_smooth_kin_cache(composite_nflat, 2), &
     642            0 :                       composite_grid_coords(3, composite_nflat), &
     643            0 :                       composite_grid_weights(composite_nflat), &
     644            0 :                       composite_base_grid_weights(composite_nflat), &
     645         4510 :                       composite_atomic_grid_weights(composite_nflat))
     646          264 :             composite_density = 0.0_dp
     647          264 :             composite_grad = 0.0_dp
     648          264 :             composite_kin = 0.0_dp
     649          529 :             DO composite_local_atom = 1, composite_local_natom
     650          265 :                iatom = composite_local_atoms(composite_local_atom)
     651       458789 :                composite_grid_atom(composite_atom_start(iatom):composite_atom_end(iatom)) = iatom
     652              :             END DO
     653          264 :             composite_smooth_density_cache = 0.0_dp
     654          264 :             composite_smooth_gradient_cache = 0.0_dp
     655          264 :             composite_smooth_kin_cache = 0.0_dp
     656          264 :             composite_grid_coords = 0.0_dp
     657          264 :             composite_grid_weights = 0.0_dp
     658          264 :             composite_base_grid_weights = 0.0_dp
     659          264 :             composite_atomic_grid_weights = 0.0_dp
     660              : 
     661              :             CALL qs_rho_get(rho_struct, rho_r=smooth_rho_r, rho_g=smooth_rho_g, &
     662              :                             tau_r=smooth_tau_r, rho_g_valid=rho_g_valid, &
     663          264 :                             tau_r_valid=tau_r_valid)
     664          264 :             CPASSERT(rho_g_valid)
     665          264 :             CPASSERT(tau_r_valid)
     666          264 :             CPASSERT(ASSOCIATED(smooth_rho_r))
     667          264 :             CPASSERT(ASSOCIATED(smooth_rho_g))
     668          264 :             CPASSERT(ASSOCIATED(smooth_tau_r))
     669          264 :             CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     670              :             CALL section_vals_val_get(my_xc_section, "XC_GRID%XC_DERIV", &
     671          264 :                                       i_val=xc_deriv_method_id)
     672              :             CALL section_vals_val_get(my_xc_section, "XC_GRID%XC_SMOOTH_RHO", &
     673          264 :                                       i_val=xc_rho_smooth_id)
     674              :             CALL xc_rho_set_create(smooth_rho_set, smooth_rho_r(1)%pw_grid%bounds_local, &
     675              :                                    rho_cutoff=section_get_rval(my_xc_section, "density_cutoff"), &
     676              :                                    drho_cutoff=section_get_rval(my_xc_section, "gradient_cutoff"), &
     677          264 :                                    tau_cutoff=section_get_rval(my_xc_section, "tau_cutoff"))
     678              :             CALL xc_rho_set_update(smooth_rho_set, smooth_rho_r, smooth_rho_g, smooth_tau_r, needs, &
     679          264 :                                    xc_deriv_method_id, xc_rho_smooth_id, auxbas_pw_pool)
     680          792 :             IF (lsd) THEN
     681              :                CALL xc_rho_set_get(smooth_rho_set, rhoa=smooth_rhoa, rhob=smooth_rhob, &
     682              :                                    drhoa=smooth_drhoa, drhob=smooth_drhob, &
     683           42 :                                    tau_a=smooth_tau_a, tau_b=smooth_tau_b)
     684              :                CALL gather_native_grid_field(smooth_rhoa, smooth_rho_r(1)%pw_grid, para_env, &
     685           42 :                                              composite_smooth_rhoa)
     686              :                CALL gather_native_grid_field(smooth_rhob, smooth_rho_r(1)%pw_grid, para_env, &
     687           42 :                                              composite_smooth_rhob)
     688              :                CALL gather_native_grid_field(smooth_tau_a, smooth_rho_r(1)%pw_grid, para_env, &
     689           42 :                                              composite_smooth_tau_a)
     690              :                CALL gather_native_grid_field(smooth_tau_b, smooth_rho_r(1)%pw_grid, para_env, &
     691           42 :                                              composite_smooth_tau_b)
     692          168 :                DO idir = 1, 3
     693              :                   CALL gather_native_grid_field(smooth_drhoa(idir)%array, &
     694              :                                                 smooth_rho_r(1)%pw_grid, para_env, &
     695          126 :                                                 composite_smooth_drhoa(idir)%array)
     696              :                   CALL gather_native_grid_field(smooth_drhob(idir)%array, &
     697              :                                                 smooth_rho_r(1)%pw_grid, para_env, &
     698          168 :                                                 composite_smooth_drhob(idir)%array)
     699              :                END DO
     700              :             ELSE
     701              :                CALL xc_rho_set_get(smooth_rho_set, rho=smooth_rho, drho=smooth_drho, &
     702          222 :                                    tau=smooth_tau)
     703              :                CALL gather_native_grid_field(smooth_rho, smooth_rho_r(1)%pw_grid, para_env, &
     704          222 :                                              composite_smooth_rho)
     705              :                CALL gather_native_grid_field(smooth_tau, smooth_rho_r(1)%pw_grid, para_env, &
     706          222 :                                              composite_smooth_tau)
     707          888 :                DO idir = 1, 3
     708              :                   CALL gather_native_grid_field(smooth_drho(idir)%array, &
     709              :                                                 smooth_rho_r(1)%pw_grid, para_env, &
     710          888 :                                                 composite_smooth_drho(idir)%array)
     711              :                END DO
     712              :             END IF
     713              :          END IF
     714              : 
     715              :          ! Initialize energy contribution from the one center XC terms to zero
     716        28630 :          exc1 = 0.0_dp
     717              : 
     718              :          ! Nullify some pointers for work-arrays
     719        28630 :          NULLIFY (rho_h, drho_h, rho_s, drho_s, weight_h, weight_s)
     720        28630 :          NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
     721        28630 :          NULLIFY (tau_h, tau_s)
     722        28630 :          NULLIFY (vtau_h, vtau_s)
     723              : 
     724              :          ! Here starts the loop over all the atoms
     725              : 
     726        83994 :          DO ikind = 1, SIZE(atomic_kind_set)
     727        55364 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     728        55364 :             NULLIFY (gth_potential, sgp_potential)
     729              :             CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
     730              :                              gth_potential=gth_potential, harmonics=harmonics, &
     731              :                              grid_atom=grid_atom, sgp_potential=sgp_potential, &
     732        55364 :                              zatom=zatom, zeff=zeff)
     733        55364 :             one_center_kind = .NOT. direct_valence_atom_composite
     734        55364 :             IF (one_center_kind) THEN
     735        55218 :                CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
     736        55218 :                one_center_kind = paw_atom
     737        55218 :                IF (skala_atom_grid) THEN
     738              :                   one_center_kind = native_skala_uses_one_center_kind( &
     739              :                                     paw_atom, gapw_representation, &
     740              :                                     ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential), &
     741          206 :                                     zeff, zatom)
     742              :                END IF
     743              :             END IF
     744        55364 :             IF (.NOT. one_center_kind .AND. .NOT. atom_composite_active) CYCLE
     745              : 
     746        49948 :             nr = grid_atom%nr
     747        49948 :             na = grid_atom%ng_sphere
     748              : 
     749        49948 :             IF (one_center_kind) THEN
     750              :                ! Prepare the structures needed to calculate and store the one-center XC derivatives.
     751              : 
     752              :                ! Array dimension: here anly one dimensional arrays are used,
     753              :                ! i.e. only the first column of deriv_data is read.
     754              :                ! The other to dimensions  are set to size equal 1
     755       497980 :                bounds(1:2, 1:3) = 1
     756        49798 :                bounds(2, 1) = na
     757        49798 :                bounds(2, 2) = nr
     758              : 
     759              :                ! set integration weights
     760        49798 :                IF (accint) THEN
     761        14776 :                   weight_h => grid_atom%weight
     762        14776 :                   alpha = dft_control%qs_control%gapw_control%aw(ikind)
     763        14776 :                   IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     764        14244 :                      IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
     765              :                   END IF
     766        14776 :                   IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     767         2128 :                      ALLOCATE (grid_atom%gapw_weight_s(na, nr))
     768        26952 :                      DO ir = 1, nr
     769        26420 :                         agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
     770      1343632 :                         grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
     771              :                      END DO
     772          532 :                      grid_atom%gapw_weight_alpha = alpha
     773              :                   END IF
     774        14776 :                   weight_s => grid_atom%gapw_weight_s
     775              :                ELSE
     776        35022 :                   weight_h => grid_atom%weight
     777        35022 :                   weight_s => grid_atom%weight
     778              :                END IF
     779              : 
     780              :                ! create a place where to put the derivatives
     781        49798 :                CALL xc_dset_create(deriv_set, local_bounds=bounds)
     782              :                ! create the place where to store the argument for the functionals
     783              :                CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
     784        49798 :                                       drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     785              :                CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
     786        49798 :                                       drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     787              : 
     788              :                ! allocate the required 3d arrays where to store rho and drho
     789        49798 :                CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
     790        49798 :                CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
     791              : 
     792        49798 :                CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
     793        49798 :                CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
     794        49798 :                CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
     795        49798 :                CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
     796              :                !
     797        49798 :                IF (gradient_f) THEN
     798        33282 :                   CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
     799        33282 :                   CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
     800        33282 :                   CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
     801        33282 :                   CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
     802              :                END IF
     803              : 
     804        49798 :                IF (tau_f) THEN
     805         1328 :                   CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
     806         1328 :                   CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
     807         1328 :                   CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
     808         1328 :                   CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
     809         1328 :                   CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
     810              :                END IF
     811              : 
     812              :                ! NLCC for separate hard and soft one-center densities.
     813        49798 :                donlcc = .FALSE.
     814        49798 :                IF (nlcc) THEN
     815         1138 :                   NULLIFY (rho_nlcc)
     816         1138 :                   rho_nlcc => my_kind_set(ikind)%nlcc_pot
     817         1138 :                   IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
     818              :                END IF
     819              :             END IF
     820              : 
     821              :             ! Distribute the atoms of this kind
     822              : 
     823        49948 :             num_pe = para_env%num_pe
     824        49948 :             bo = get_limit(natom, para_env%num_pe, para_env%mepos)
     825              : 
     826        88852 :             DO iat = bo(1), bo(2)
     827        38904 :                iatom = atom_list(iat)
     828              : 
     829        38904 :                IF (one_center_kind) THEN
     830        38765 :                   my_rho_atom_set(iatom)%exc_h = 0.0_dp
     831        38765 :                   my_rho_atom_set(iatom)%exc_s = 0.0_dp
     832              : 
     833        38765 :                   rho_atom => my_rho_atom_set(iatom)
     834    125022742 :                   rho_h = 0.0_dp
     835    125022742 :                   rho_s = 0.0_dp
     836        38765 :                   IF (gradient_f) THEN
     837        25245 :                      NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
     838              :                      CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
     839              :                                        rho_rad_s=r_s, drho_rad_h=dr_h, &
     840              :                                        drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
     841        25245 :                                        rho_rad_s_d=r_s_d)
     842    368748700 :                      drho_h = 0.0_dp
     843    368748700 :                      drho_s = 0.0_dp
     844              :                   ELSE
     845        13520 :                      NULLIFY (r_h, r_s)
     846        13520 :                      CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
     847        13520 :                      rho_d = 0.0_dp
     848              :                   END IF
     849        38765 :                   IF (tau_f) THEN
     850          938 :                      CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
     851              :                   ELSE
     852        37827 :                      tau_d = 0.0_dp
     853              :                   END IF
     854              : 
     855      2144855 :                   DO ir = 1, nr
     856              :                      CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
     857              :                                            ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
     858      2106090 :                                            r_h_d, r_s_d, drho_h, drho_s)
     859      2144855 :                      IF (donlcc) THEN
     860              :                         CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
     861              :                                            ir, rho_nlcc(:, 1), rho_h, rho_s, &
     862        17150 :                                            rho_nlcc(:, 2), drho_h, drho_s)
     863              :                      END IF
     864              :                   END DO
     865              :                END IF
     866              : 
     867        38904 :                IF (atom_composite_active) THEN
     868          265 :                   IF (image_partition_atom_composite) THEN
     869              :                      CALL build_periodic_atom_image_layout( &
     870              :                         composite_atom_coords, cell, iatom, composite_image_periodicity, &
     871          265 :                         composite_partition_image_coords, composite_partition_target_image)
     872              :                      CALL build_periodic_atom_image_layout( &
     873              :                         composite_atom_coords(:, iatom:iatom), cell, 1, &
     874              :                         composite_image_periodicity, composite_descriptor_image_coords, &
     875          265 :                         composite_descriptor_target_image)
     876              :                   END IF
     877              : !$OMP PARALLEL DO COLLAPSE(2) IF (image_partition_atom_composite) SCHEDULE(STATIC) DEFAULT(NONE) &
     878              : !$OMP PRIVATE(composite_row, composite_point, composite_smooth_density_value, &
     879              : !$OMP         composite_smooth_gradient_value, composite_smooth_kin_value, &
     880              : !$OMP         descriptor_window_weight, idir, ispin, &
     881              : !$OMP         gth_potential, nlcc_density, nlcc_gradient, nlcc_hessian, nlcc_spin_factor, &
     882              : !$OMP         interpolation_stencil, partition_scale, partition_weight, sgp_potential, source_atom) &
     883              : !$OMP SHARED(atom_composite_reference, cell, composite_atom_coords, composite_atom_kind, &
     884              : !$OMP        composite_atom_start, composite_atomic_grid_weights, composite_base_grid_weights, &
     885              : !$OMP        composite_density, composite_descriptor_image_coords, &
     886              : !$OMP        composite_descriptor_target_image, composite_distances, composite_grad, &
     887              : !$OMP        composite_grid_coords, composite_grid_weights, composite_kin, &
     888              : !$OMP        composite_partition_atom_coords, composite_partition_image_coords, &
     889              : !$OMP        composite_partition_target_image, composite_partition_weights, &
     890              : !$OMP        composite_smooth_density_cache, composite_smooth_drho, composite_smooth_drhoa, &
     891              : !$OMP        composite_smooth_drhob, composite_smooth_gradient_cache, &
     892              : !$OMP        composite_smooth_kin_cache, composite_smooth_rho, composite_smooth_rhoa, &
     893              : !$OMP        composite_smooth_rhob, composite_smooth_tau, composite_smooth_tau_a, &
     894              : !$OMP        composite_smooth_tau_b, drho_h, drho_s, grid_atom, iatom, &
     895              : !$OMP        image_partition_atom_composite, lsd, my_kind_set, na, nlcc, nr, one_center_kind, &
     896              : !$OMP        particle_set, rho_h, rho_s, smooth_rho_r, tau_h, tau_s, &
     897          265 : !$OMP        use_atom_composite_density, use_atom_composite_gradient, use_atom_composite_tau)
     898              :                   DO ir = 1, nr
     899              :                      DO ia = 1, na
     900              :                         composite_row = composite_atom_start(iatom) + (ir - 1)*na + ia - 1
     901              :                         composite_point(1) = particle_set(iatom)%r(1) + grid_atom%rad(ir)* &
     902              :                                              grid_atom%sin_pol(ia)*grid_atom%cos_azi(ia)
     903              :                         composite_point(2) = particle_set(iatom)%r(2) + grid_atom%rad(ir)* &
     904              :                                              grid_atom%sin_pol(ia)*grid_atom%sin_azi(ia)
     905              :                         composite_point(3) = particle_set(iatom)%r(3) + &
     906              :                                              grid_atom%rad(ir)*grid_atom%cos_pol(ia)
     907              :                         composite_grid_coords(:, composite_row) = composite_point
     908              :                         IF (image_partition_atom_composite) THEN
     909              :                            CALL periodic_atom_image_partition_from_layout( &
     910              :                               composite_point, composite_partition_image_coords, &
     911              :                               composite_partition_target_image, partition_weight)
     912              :                            ! The self-image partition defines a smooth atom-centered periodic
     913              :                            ! descriptor domain without truncating it at neighboring atoms.
     914              :                            CALL periodic_atom_image_partition_from_layout( &
     915              :                               composite_point, composite_descriptor_image_coords, &
     916              :                               composite_descriptor_target_image, descriptor_window_weight)
     917              :                            partition_scale = smooth_partition_atomic_weight_scale( &
     918              :                                              descriptor_window_weight)
     919              :                         ELSE
     920              :                            CALL smooth_atom_partition( &
     921              :                               composite_point, composite_atom_coords, cell, &
     922              :                               composite_partition_weights, composite_partition_atom_coords, &
     923              :                               composite_distances)
     924              :                            partition_weight = composite_partition_weights(iatom)
     925              :                            partition_scale = 1.0_dp
     926              :                         END IF
     927              :                         composite_base_grid_weights(composite_row) = grid_atom%weight(ia, ir)
     928              :                         composite_atomic_grid_weights(composite_row) = &
     929              :                            composite_base_grid_weights(composite_row)*partition_scale
     930              :                         composite_grid_weights(composite_row) = &
     931              :                            composite_base_grid_weights(composite_row)* &
     932              :                            partition_weight
     933              :                         CALL create_native_grid_interpolation_stencil( &
     934              :                            interpolation_stencil, smooth_rho_r(1)%pw_grid, cell, composite_point, &
     935              :                            image_partition_atom_composite)
     936              :                         IF (lsd) THEN
     937              :                            CALL interpolate_native_grid_fields( &
     938              :                               composite_smooth_rhoa, composite_smooth_drhoa(1)%array, &
     939              :                               composite_smooth_drhoa(2)%array, composite_smooth_drhoa(3)%array, &
     940              :                               composite_smooth_tau_a, interpolation_stencil, &
     941              :                               composite_smooth_density_value(1), &
     942              :                               composite_smooth_gradient_value(:, 1), &
     943              :                               composite_smooth_kin_value(1))
     944              :                            CALL interpolate_native_grid_fields( &
     945              :                               composite_smooth_rhob, composite_smooth_drhob(1)%array, &
     946              :                               composite_smooth_drhob(2)%array, composite_smooth_drhob(3)%array, &
     947              :                               composite_smooth_tau_b, interpolation_stencil, &
     948              :                               composite_smooth_density_value(2), &
     949              :                               composite_smooth_gradient_value(:, 2), &
     950              :                               composite_smooth_kin_value(2))
     951              :                            composite_smooth_density_cache(composite_row, :) = &
     952              :                               composite_smooth_density_value
     953              :                            composite_smooth_gradient_cache(composite_row, :, :) = &
     954              :                               composite_smooth_gradient_value
     955              :                            composite_smooth_kin_cache(composite_row, :) = &
     956              :                               composite_smooth_kin_value
     957              :                            DO ispin = 1, 2
     958              :                               composite_density(composite_row, ispin) = &
     959              :                                  composite_smooth_density_value(ispin)
     960              :                               composite_grad(composite_row, :, ispin) = &
     961              :                                  composite_smooth_gradient_value(:, ispin)
     962              :                               composite_kin(composite_row, ispin) = &
     963              :                                  composite_smooth_kin_value(ispin)
     964              :                               IF (one_center_kind .AND. use_atom_composite_density) THEN
     965              :                                  composite_density(composite_row, ispin) = &
     966              :                                     composite_density(composite_row, ispin) + &
     967              :                                     rho_h(ia, ir, ispin) - rho_s(ia, ir, ispin)
     968              :                               END IF
     969              :                               IF (one_center_kind .AND. use_atom_composite_gradient) THEN
     970              :                                  DO idir = 1, 3
     971              :                                     composite_grad(composite_row, idir, ispin) = &
     972              :                                        composite_grad(composite_row, idir, ispin) + &
     973              :                                        drho_h(idir, ia, ir, ispin) - drho_s(idir, ia, ir, ispin)
     974              :                                  END DO
     975              :                               END IF
     976              :                               IF (one_center_kind .AND. use_atom_composite_tau) THEN
     977              :                                  composite_kin(composite_row, ispin) = &
     978              :                                     composite_kin(composite_row, ispin) + &
     979              :                                     tau_h(ia, ir, ispin) - tau_s(ia, ir, ispin)
     980              :                               END IF
     981              :                            END DO
     982              :                         ELSE
     983              :                            CALL interpolate_native_grid_fields( &
     984              :                               composite_smooth_rho, composite_smooth_drho(1)%array, &
     985              :                               composite_smooth_drho(2)%array, composite_smooth_drho(3)%array, &
     986              :                               composite_smooth_tau, interpolation_stencil, &
     987              :                               composite_smooth_density_value(1), &
     988              :                               composite_smooth_gradient_value(:, 1), &
     989              :                               composite_smooth_kin_value(1))
     990              :                            composite_smooth_density_cache(composite_row, 1) = &
     991              :                               composite_smooth_density_value(1)
     992              :                            composite_smooth_gradient_cache(composite_row, :, 1) = &
     993              :                               composite_smooth_gradient_value(:, 1)
     994              :                            composite_smooth_kin_cache(composite_row, 1) = &
     995              :                               composite_smooth_kin_value(1)
     996              :                            composite_density(composite_row, :) = &
     997              :                               0.5_dp*composite_smooth_density_value(1)
     998              :                            DO idir = 1, 3
     999              :                               composite_grad(composite_row, idir, :) = &
    1000              :                                  0.5_dp*composite_smooth_gradient_value(idir, 1)
    1001              :                            END DO
    1002              :                            composite_kin(composite_row, :) = &
    1003              :                               0.5_dp*composite_smooth_kin_value(1)
    1004              :                            IF (one_center_kind .AND. use_atom_composite_density) THEN
    1005              :                               composite_density(composite_row, :) = &
    1006              :                                  composite_density(composite_row, :) + &
    1007              :                                  0.5_dp*(rho_h(ia, ir, 1) - rho_s(ia, ir, 1))
    1008              :                            END IF
    1009              :                            IF (one_center_kind .AND. use_atom_composite_gradient) THEN
    1010              :                               DO idir = 1, 3
    1011              :                                  composite_grad(composite_row, idir, :) = &
    1012              :                                     composite_grad(composite_row, idir, :) + &
    1013              :                                     0.5_dp*(drho_h(idir, ia, ir, 1) - &
    1014              :                                             drho_s(idir, ia, ir, 1))
    1015              :                               END DO
    1016              :                            END IF
    1017              :                            IF (one_center_kind .AND. use_atom_composite_tau) THEN
    1018              :                               composite_kin(composite_row, :) = composite_kin(composite_row, :) + &
    1019              :                                                                 0.5_dp*(tau_h(ia, ir, 1) - &
    1020              :                                                                         tau_s(ia, ir, 1))
    1021              :                            END IF
    1022              :                         END IF
    1023              :                         IF (atom_composite_reference .AND. nlcc) THEN
    1024              :                            nlcc_spin_factor = MERGE(1.0_dp, 0.5_dp, lsd)
    1025              :                            DO source_atom = 1, SIZE(particle_set)
    1026              :                               NULLIFY (gth_potential, sgp_potential)
    1027              :                               CALL get_qs_kind(my_kind_set(composite_atom_kind(source_atom)), &
    1028              :                                                gth_potential=gth_potential, &
    1029              :                                                sgp_potential=sgp_potential)
    1030              :                               CALL evaluate_nlcc_primitive_fields( &
    1031              :                                  composite_point, particle_set(source_atom)%r, &
    1032              :                                  gth_potential, sgp_potential, nlcc_density, &
    1033              :                                  nlcc_gradient, nlcc_hessian)
    1034              :                               composite_density(composite_row, :) = &
    1035              :                                  composite_density(composite_row, :) + &
    1036              :                                  nlcc_spin_factor*nlcc_density
    1037              :                               DO idir = 1, 3
    1038              :                                  composite_grad(composite_row, idir, :) = &
    1039              :                                     composite_grad(composite_row, idir, :) + &
    1040              :                                     nlcc_spin_factor*nlcc_gradient(idir)
    1041              :                               END DO
    1042              :                            END DO
    1043              :                         END IF
    1044              :                      END DO
    1045              :                   END DO
    1046              : !$OMP END PARALLEL DO
    1047          265 :                   IF (image_partition_atom_composite) THEN
    1048          265 :                      DEALLOCATE (composite_descriptor_image_coords, composite_partition_image_coords)
    1049              :                   END IF
    1050          265 :                   CPASSERT(nr*na == composite_atom_end(iatom) - composite_atom_start(iatom) + 1)
    1051              :                END IF
    1052              : 
    1053        38904 :                IF (.NOT. one_center_kind) CYCLE
    1054              : 
    1055      2144855 :                DO ir = 1, nr
    1056      2144855 :                   IF (tau_f) THEN
    1057        45500 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
    1058        45500 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
    1059      2060590 :                   ELSE IF (gradient_f) THEN
    1060      1231490 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
    1061      1231490 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
    1062              :                   ELSE
    1063       829100 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
    1064       829100 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
    1065              :                   END IF
    1066              :                END DO
    1067              : 
    1068        38765 :                evaluate_hard = .TRUE.
    1069        38765 :                evaluate_soft = .TRUE.
    1070        38765 :                skala_atom_force_h = 0.0_dp
    1071        38765 :                skala_atom_force_s = 0.0_dp
    1072        38765 :                skala_atom_virial_h = 0.0_dp
    1073        38765 :                skala_atom_virial_s = 0.0_dp
    1074        38765 :                IF (skala_atom_grid) THEN
    1075              :                   SELECT CASE (gapw_density_partition)
    1076              :                   CASE (skala_gapw_density_partition_hard_minus_soft)
    1077            0 :                      CONTINUE
    1078              :                   CASE (skala_gapw_density_partition_hard_only)
    1079            0 :                      evaluate_soft = .FALSE.
    1080              :                   CASE (skala_gapw_density_partition_soft_only)
    1081            0 :                      evaluate_hard = .FALSE.
    1082              :                   CASE (skala_gapw_density_partition_none)
    1083            0 :                      evaluate_hard = .FALSE.
    1084            0 :                      evaluate_soft = .FALSE.
    1085              :                   CASE DEFAULT
    1086              :                      CALL cp_abort(__LOCATION__, &
    1087          128 :                                    "Unknown GAUXC%NATIVE_GRID_GAPW_DENSITY_PARTITION value.")
    1088              :                   END SELECT
    1089              :                END IF
    1090        38765 :                IF (atom_composite_reference) THEN
    1091          126 :                   evaluate_hard = .FALSE.
    1092          126 :                   evaluate_soft = .FALSE.
    1093              :                END IF
    1094              : 
    1095              :                !-------------------!
    1096              :                ! hard atom density !
    1097              :                !-------------------!
    1098        38765 :                CALL xc_dset_zero_all(deriv_set)
    1099        38765 :                IF (.NOT. evaluate_hard) THEN
    1100          126 :                   exc_h = 0.0_dp
    1101          126 :                   IF (.NOT. energy_only) THEN
    1102       119052 :                      vxc_h = 0.0_dp
    1103       464652 :                      IF (ASSOCIATED(vxg_h)) vxg_h = 0.0_dp
    1104       119052 :                      IF (ASSOCIATED(vtau_h)) vtau_h = 0.0_dp
    1105              :                   END IF
    1106        38639 :                ELSE IF (skala_atom_grid) THEN
    1107              :                   CALL skala_gapw_atom_vxc_of_r( &
    1108              :                      my_xc_section, grid_atom, para_env, particle_set(iatom)%r, &
    1109              :                      rho_h, drho_h, tau_h, weight_h, lsd, nspins, na, nr, &
    1110              :                      exc_h, vxc_h, vxg_h, vtau_h, energy_only=energy_only, &
    1111            2 :                      atom_force=skala_atom_force_h, atom_virial=skala_atom_virial_h)
    1112              :                ELSE
    1113              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_h, deriv_set, 1, needs, weight_h, &
    1114              :                                     lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h, energy_only=energy_only, &
    1115        38637 :                                     adiabatic_rescale_factor=my_adiabatic_rescale_factor)
    1116              :                END IF
    1117        38765 :                rho_atom%exc_h = rho_atom%exc_h + exc_h
    1118              : 
    1119              :                !-------------------!
    1120              :                ! soft atom density !
    1121              :                !-------------------!
    1122        38765 :                CALL xc_dset_zero_all(deriv_set)
    1123        38765 :                IF (.NOT. evaluate_soft) THEN
    1124          126 :                   exc_s = 0.0_dp
    1125          126 :                   IF (.NOT. energy_only) THEN
    1126       119052 :                      vxc_s = 0.0_dp
    1127       464652 :                      IF (ASSOCIATED(vxg_s)) vxg_s = 0.0_dp
    1128       119052 :                      IF (ASSOCIATED(vtau_s)) vtau_s = 0.0_dp
    1129              :                   END IF
    1130        38639 :                ELSE IF (skala_atom_grid) THEN
    1131              :                   CALL skala_gapw_atom_vxc_of_r( &
    1132              :                      my_xc_section, grid_atom, para_env, particle_set(iatom)%r, &
    1133              :                      rho_s, drho_s, tau_s, weight_s, lsd, nspins, na, nr, &
    1134              :                      exc_s, vxc_s, vxg_s, vtau_s, energy_only=energy_only, &
    1135            2 :                      atom_force=skala_atom_force_s, atom_virial=skala_atom_virial_s)
    1136              :                ELSE
    1137              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_s, deriv_set, 1, needs, weight_s, &
    1138              :                                     lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s, energy_only=energy_only, &
    1139        38637 :                                     adiabatic_rescale_factor=my_adiabatic_rescale_factor)
    1140              :                END IF
    1141        38765 :                rho_atom%exc_s = rho_atom%exc_s + exc_s
    1142              : 
    1143              :                ! Add contributions to the exc energy
    1144              : 
    1145        38765 :                exc1 = exc1 + rho_atom%exc_h - rho_atom%exc_s
    1146        38765 :                IF (skala_atom_grid .AND. my_calculate_forces .AND. ASSOCIATED(force)) THEN
    1147              :                   force(ikind)%rho_elec(:, iat) = force(ikind)%rho_elec(:, iat) + &
    1148          140 :                                                   skala_atom_force_h - skala_atom_force_s
    1149              :                END IF
    1150        38765 :                IF (skala_atom_grid .AND. use_virial) THEN
    1151          403 :                   skala_atom_virial = skala_atom_virial_h - skala_atom_virial_s
    1152          124 :                   DO idir = 1, 3
    1153          403 :                      DO jdir = 1, 3
    1154              :                         virial%pv_gapw(idir, jdir) = virial%pv_gapw(idir, jdir) + &
    1155          279 :                                                      skala_atom_virial(idir, jdir)
    1156              :                         virial%pv_virial(idir, jdir) = virial%pv_virial(idir, jdir) + &
    1157          372 :                                                        skala_atom_virial(idir, jdir)
    1158              :                      END DO
    1159              :                   END DO
    1160              :                END IF
    1161              : 
    1162              :                ! Integration to get the matrix elements relative to the vxc_atom
    1163              :                ! here the products with the primitives is done: gaVxcgb
    1164              :                ! internal transformation to get the integral in cartesian Gaussians
    1165              : 
    1166        38765 :                IF (.NOT. energy_only) THEN
    1167        37138 :                   NULLIFY (int_hh, int_ss)
    1168        37138 :                   CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    1169        37138 :                   IF (gradient_f) THEN
    1170              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    1171        23782 :                                      grid_atom, basis_1c, harmonics, nspins)
    1172              :                   ELSE
    1173              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
    1174        13356 :                                        grid_atom, basis_1c, harmonics, nspins)
    1175              :                   END IF
    1176        37138 :                   IF (tau_f) THEN
    1177          938 :                      CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, tau_basis_cache, nspins)
    1178              :                   END IF
    1179              :                END IF ! energy_only
    1180        88852 :                NULLIFY (r_h, r_s, dr_h, dr_s)
    1181              :             END DO ! iat
    1182              : 
    1183       133942 :             IF (one_center_kind) THEN
    1184        49798 :                IF (tau_f) CALL release_tau_basis_cache(tau_basis_cache)
    1185              : 
    1186        49798 :                CALL xc_dset_release(deriv_set)
    1187        49798 :                CALL xc_rho_set_release(rho_set_h)
    1188        49798 :                CALL xc_rho_set_release(rho_set_s)
    1189              :             END IF
    1190              :          END DO ! ikind
    1191              : 
    1192        28630 :          IF (atom_composite_active) THEN
    1193            0 :             ALLOCATE (composite_cross_density(composite_nflat, 2), &
    1194            0 :                       composite_cross_grad(composite_nflat, 3, 2), &
    1195         1782 :                       composite_cross_kin(composite_nflat, 2))
    1196          264 :             composite_cross_density = 0.0_dp
    1197          264 :             composite_cross_grad = 0.0_dp
    1198          264 :             composite_cross_kin = 0.0_dp
    1199          264 :             composite_cross_cutoff_max = 0.0_dp
    1200          264 :             IF (.NOT. direct_valence_atom_composite) THEN
    1201          292 :                DO ikind = 1, SIZE(atomic_kind_set)
    1202          164 :                   CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    1203          164 :                   NULLIFY (gth_potential, sgp_potential)
    1204              :                   CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
    1205              :                                    gth_potential=gth_potential, harmonics=harmonics, &
    1206              :                                    grid_atom=grid_atom, sgp_potential=sgp_potential, &
    1207          164 :                                    zatom=zatom, zeff=zeff)
    1208          164 :                   CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    1209          188 :                   IF (.NOT. native_skala_uses_one_center_kind( &
    1210              :                       paw_atom, gapw_representation, &
    1211              :                       ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential), &
    1212              :                       zeff, zatom)) CYCLE
    1213              : 
    1214              :                   CALL replicate_rho_atom_radial( &
    1215          160 :                      para_env, my_rho_atom_set, my_kind_set(ikind), atom_list, natom, nspins)
    1216          160 :                   nr = grid_atom%nr
    1217          160 :                   na = grid_atom%ng_sphere
    1218          160 :                   CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    1219          160 :                   CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
    1220          160 :                   CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
    1221          160 :                   CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
    1222          160 :                   CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
    1223          160 :                   CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
    1224          160 :                   CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
    1225              : 
    1226              :                   ! The one-center density matrices are already globally reduced. Distribute the
    1227              :                   ! overlap work by target atom so that every rank constructs only its model rows.
    1228          412 :                   DO iat = 1, natom
    1229          252 :                      source_atom = atom_list(iat)
    1230          252 :                      rho_atom => my_rho_atom_set(source_atom)
    1231          252 :                      NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    1232              :                      CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s, &
    1233              :                                        drho_rad_h=dr_h, drho_rad_s=dr_s, &
    1234          252 :                                        rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    1235       238104 :                      rho_h = 0.0_dp
    1236       238104 :                      rho_s = 0.0_dp
    1237      1159704 :                      drho_h = 0.0_dp
    1238      1159704 :                      drho_s = 0.0_dp
    1239          252 :                      CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
    1240         7452 :                      DO ir = 1, nr
    1241              :                         CALL calc_rho_angular(grid_atom, harmonics, nspins, .TRUE., &
    1242              :                                               ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
    1243         7452 :                                               r_h_d, r_s_d, drho_h, drho_s)
    1244              :                      END DO
    1245              : 
    1246              :                      cross_cutoff = gapw_atom_grid_support_radius( &
    1247          252 :                                     grid_atom, rho_h, rho_s, drho_h, drho_s, tau_h, tau_s)
    1248          252 :                      IF (cross_cutoff <= 0.0_dp) CYCLE
    1249          228 :                      composite_cross_cutoff_max = MAX(composite_cross_cutoff_max, cross_cutoff)
    1250          228 :                      image_shell = 0
    1251          912 :                      DO idir = 1, 3
    1252          912 :                         IF (cell%perd(idir) == 1) THEN
    1253              :                            image_shell(idir) = CEILING( &
    1254         2544 :                                                cross_cutoff*SQRT(SUM(cell%h_inv(idir, :)**2))) + 1
    1255              :                         END IF
    1256              :                      END DO
    1257              : 
    1258              : !$OMP PARALLEL DO DEFAULT(NONE) SCHEDULE(STATIC) &
    1259              : !$OMP PRIVATE(base_shift, composite_row, cross_density, cross_density_spatial, &
    1260              : !$OMP         cross_displacement, cross_grad, cross_grad_spatial, cross_kin, &
    1261              : !$OMP         cross_kin_spatial, fractional, idir, image_i1, image_i2, image_i3, jdir, &
    1262              : !$OMP         image_shift, image_translation, target_atom) &
    1263              : !$OMP SHARED(cell, composite_cross_density, composite_cross_grad, composite_cross_kin, &
    1264              : !$OMP        composite_grid_atom, composite_grid_coords, composite_nflat, cross_cutoff, &
    1265              : !$OMP        drho_h, drho_s, grid_atom, harmonics, image_shell, lsd, nspins, &
    1266              : !$OMP        particle_set, rho_h, rho_s, source_atom, tau_h, tau_s, &
    1267          412 : !$OMP        use_atom_composite_density, use_atom_composite_gradient, use_atom_composite_tau)
    1268              :                      DO composite_row = 1, composite_nflat
    1269              :                         target_atom = composite_grid_atom(composite_row)
    1270              :                         fractional = 0.0_dp
    1271              :                         DO idir = 1, 3
    1272              :                            DO jdir = 1, 3
    1273              :                               fractional(idir) = fractional(idir) + cell%h_inv(idir, jdir)* &
    1274              :                                                  (composite_grid_coords(jdir, composite_row) - &
    1275              :                                                   particle_set(source_atom)%r(jdir))
    1276              :                            END DO
    1277              :                         END DO
    1278              :                         DO idir = 1, 3
    1279              :                            base_shift(idir) = cell%perd(idir)*NINT(fractional(idir))
    1280              :                         END DO
    1281              :                         DO image_i3 = base_shift(3) - image_shell(3), &
    1282              :                            base_shift(3) + image_shell(3)
    1283              :                            DO image_i2 = base_shift(2) - image_shell(2), &
    1284              :                               base_shift(2) + image_shell(2)
    1285              :                               DO image_i1 = base_shift(1) - image_shell(1), &
    1286              :                                  base_shift(1) + image_shell(1)
    1287              :                                  image_shift = [image_i1, image_i2, image_i3]
    1288              :                                  IF (target_atom == source_atom .AND. &
    1289              :                                      ALL(image_shift == 0)) CYCLE
    1290              :                                  image_translation = MATMUL( &
    1291              :                                                      cell%hmat, REAL(image_shift, dp))
    1292              :                                  cross_displacement = composite_grid_coords(:, composite_row) - &
    1293              :                                                       particle_set(source_atom)%r - &
    1294              :                                                       image_translation
    1295              :                                  CALL interpolate_gapw_atom_grid_fields( &
    1296              :                                     grid_atom, harmonics, cross_displacement, cross_cutoff, nspins, &
    1297              :                                     rho_h, rho_s, drho_h, drho_s, tau_h, tau_s, &
    1298              :                                     cross_density, cross_grad, cross_kin, cross_density_spatial, &
    1299              :                                     cross_grad_spatial, cross_kin_spatial)
    1300              :                                  IF (lsd) THEN
    1301              :                                     IF (use_atom_composite_density) THEN
    1302              :                                        composite_cross_density(composite_row, 1:2) = &
    1303              :                                           composite_cross_density(composite_row, 1:2) + &
    1304              :                                           cross_density(1:2)
    1305              :                                     END IF
    1306              :                                     IF (use_atom_composite_gradient) THEN
    1307              :                                        composite_cross_grad(composite_row, :, 1:2) = &
    1308              :                                           composite_cross_grad(composite_row, :, 1:2) + &
    1309              :                                           cross_grad(:, 1:2)
    1310              :                                     END IF
    1311              :                                     IF (use_atom_composite_tau) THEN
    1312              :                                        composite_cross_kin(composite_row, 1:2) = &
    1313              :                                           composite_cross_kin(composite_row, 1:2) + cross_kin(1:2)
    1314              :                                     END IF
    1315              :                                  ELSE
    1316              :                                     IF (use_atom_composite_density) THEN
    1317              :                                        composite_cross_density(composite_row, :) = &
    1318              :                                           composite_cross_density(composite_row, :) + &
    1319              :                                           0.5_dp*cross_density(1)
    1320              :                                     END IF
    1321              :                                     IF (use_atom_composite_gradient) THEN
    1322              :                                        DO idir = 1, 3
    1323              :                                           composite_cross_grad(composite_row, idir, :) = &
    1324              :                                              composite_cross_grad(composite_row, idir, :) + &
    1325              :                                              0.5_dp*cross_grad(idir, 1)
    1326              :                                        END DO
    1327              :                                     END IF
    1328              :                                     IF (use_atom_composite_tau) THEN
    1329              :                                        composite_cross_kin(composite_row, :) = &
    1330              :                                           composite_cross_kin(composite_row, :) + &
    1331              :                                           0.5_dp*cross_kin(1)
    1332              :                                     END IF
    1333              :                                  END IF
    1334              :                               END DO
    1335              :                            END DO
    1336              :                         END DO
    1337              :                      END DO
    1338              : !$OMP END PARALLEL DO
    1339              :                   END DO
    1340              : 
    1341          452 :                   CALL release_tau_basis_cache(tau_basis_cache)
    1342              :                END DO
    1343              :             END IF
    1344              : 
    1345          264 :             IF (native_grid_diagnostics) THEN
    1346       119570 :                composite_cross_density_max = MAXVAL(ABS(composite_cross_density))
    1347       358710 :                composite_cross_grad_max = MAXVAL(ABS(composite_cross_grad))
    1348       119570 :                composite_cross_kin_max = MAXVAL(ABS(composite_cross_kin))
    1349           30 :                CALL para_env%max(composite_cross_cutoff_max)
    1350           30 :                CALL para_env%max(composite_cross_density_max)
    1351           30 :                CALL para_env%max(composite_cross_grad_max)
    1352           30 :                CALL para_env%max(composite_cross_kin_max)
    1353           30 :                iw = cp_logger_get_default_io_unit()
    1354           30 :                IF (iw > 0) THEN
    1355              :                   WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES20.12))") &
    1356           15 :                      "SKALA_GPW| Atom-composite cross support/maxima", &
    1357           15 :                      composite_cross_cutoff_max, composite_cross_density_max, &
    1358           30 :                      composite_cross_grad_max, composite_cross_kin_max
    1359              :                END IF
    1360              :             END IF
    1361       917312 :             composite_density(:, :) = composite_density(:, :) + composite_cross_density(:, :)
    1362      2751936 :             composite_grad(:, :, :) = composite_grad(:, :, :) + composite_cross_grad(:, :, :)
    1363       917312 :             composite_kin(:, :) = composite_kin(:, :) + composite_cross_kin(:, :)
    1364          264 :             DEALLOCATE (composite_cross_density, composite_cross_grad, composite_cross_kin)
    1365              : 
    1366       458524 :             CPASSERT(ALL(composite_grid_weights >= 0.0_dp))
    1367              :             atom_composite_nelec = SUM(composite_grid_weights* &
    1368       458524 :                                        (composite_density(:, 1) + composite_density(:, 2)))
    1369          264 :             CALL para_env%sum(atom_composite_nelec)
    1370          264 :             IF (atom_composite_reference .AND. my_calculate_forces) THEN
    1371              :                CALL skala_gapw_atom_composite_energy( &
    1372              :                   my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
    1373              :                   composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
    1374              :                   composite_local_grid_sizes, composite_local_atom_coords, atom_composite_exc, &
    1375              :                   composite_density_grad, composite_grad_grad, composite_kin_grad, &
    1376              :                   composite_grid_coord_grad, composite_grid_weight_grad, &
    1377           64 :                   composite_atomic_grid_weight_grad, composite_atom_coord_grad)
    1378            0 :                ALLOCATE (composite_cross_force(3, SIZE(particle_set)), &
    1379            0 :                          composite_explicit_force(3, SIZE(particle_set)), &
    1380            0 :                          composite_grid_coord_force(3, SIZE(particle_set)), &
    1381            0 :                          composite_model_atom_force(3, SIZE(particle_set)), &
    1382            0 :                          composite_moving_smooth_force(3, SIZE(particle_set)), &
    1383            0 :                          composite_nlcc_center_force(3, SIZE(particle_set)), &
    1384            0 :                          composite_nlcc_target_force(3, SIZE(particle_set)), &
    1385            0 :                          composite_partition_force(3, SIZE(particle_set)), &
    1386            0 :                          composite_partition_included(SIZE(particle_set)), &
    1387            0 :                          composite_partition_datom(3, SIZE(particle_set), SIZE(particle_set)), &
    1388         1088 :                          composite_partition_dstrain(3, 3, SIZE(particle_set)))
    1389           64 :                composite_cross_force = 0.0_dp
    1390           64 :                composite_cross_image_virial = 0.0_dp
    1391           64 :                composite_model_atom_force = 0.0_dp
    1392           64 :                composite_grid_coord_force = 0.0_dp
    1393           64 :                composite_moving_smooth_force = 0.0_dp
    1394           64 :                composite_nlcc_center_force = 0.0_dp
    1395           64 :                composite_nlcc_target_force = 0.0_dp
    1396           64 :                composite_partition_force = 0.0_dp
    1397           64 :                composite_explicit_virial = 0.0_dp
    1398           64 :                composite_feature_virial = 0.0_dp
    1399           64 :                composite_interpolation_virial = 0.0_dp
    1400           64 :                composite_partition_strain_virial = 0.0_dp
    1401              : !$OMP PARALLEL DO IF (image_partition_atom_composite) SCHEDULE(STATIC) DEFAULT(NONE) &
    1402              : !$OMP PRIVATE(composite_local_atom, composite_row, composite_smooth_gradient_value, &
    1403              : !$OMP         iatom, idir, ispin, jdir) &
    1404              : !$OMP SHARED(cell, composite_atom_end, composite_atom_start, composite_grad_grad, &
    1405              : !$OMP        composite_grid_coords, composite_local_atoms, composite_local_natom, &
    1406              : !$OMP        composite_smooth_drho, composite_smooth_drhoa, composite_smooth_drhob, &
    1407              : !$OMP        image_partition_atom_composite, lsd, smooth_rho_r) &
    1408           64 : !$OMP REDUCTION(+:composite_feature_virial)
    1409              :                DO composite_local_atom = 1, composite_local_natom
    1410              :                   iatom = composite_local_atoms(composite_local_atom)
    1411              :                   DO composite_row = composite_atom_start(iatom), composite_atom_end(iatom)
    1412              :                      IF (lsd) THEN
    1413              :                         DO jdir = 1, 3
    1414              :                            composite_smooth_gradient_value(jdir, 1) = &
    1415              :                               interpolate_native_grid( &
    1416              :                               composite_smooth_drhoa(jdir)%array, smooth_rho_r(1)%pw_grid, &
    1417              :                               cell, composite_grid_coords(:, composite_row), &
    1418              :                               image_partition_atom_composite)
    1419              :                            composite_smooth_gradient_value(jdir, 2) = &
    1420              :                               interpolate_native_grid( &
    1421              :                               composite_smooth_drhob(jdir)%array, smooth_rho_r(1)%pw_grid, &
    1422              :                               cell, composite_grid_coords(:, composite_row), &
    1423              :                               image_partition_atom_composite)
    1424              :                         END DO
    1425              :                      ELSE
    1426              :                         DO jdir = 1, 3
    1427              :                            composite_smooth_gradient_value(jdir, :) = 0.5_dp* &
    1428              :                                                                       interpolate_native_grid( &
    1429              :                                                                       composite_smooth_drho(jdir)%array, smooth_rho_r(1)%pw_grid, &
    1430              :                                                                       cell, composite_grid_coords(:, composite_row), &
    1431              :                                                                       image_partition_atom_composite)
    1432              :                         END DO
    1433              :                      END IF
    1434              :                      DO ispin = 1, 2
    1435              :                         DO idir = 1, 3
    1436              :                            DO jdir = 1, 3
    1437              :                               composite_feature_virial(jdir, idir) = &
    1438              :                                  composite_feature_virial(jdir, idir) - &
    1439              :                                  composite_grad_grad(composite_row, idir, ispin)* &
    1440              :                                  composite_smooth_gradient_value(jdir, ispin)
    1441              :                            END DO
    1442              :                         END DO
    1443              :                      END DO
    1444              :                   END DO
    1445              :                END DO
    1446              : !$OMP END PARALLEL DO
    1447              : !$OMP PARALLEL IF (image_partition_atom_composite) DEFAULT(NONE) &
    1448              : !$OMP PRIVATE(composite_local_atom, composite_row, descriptor_window_adjoint, &
    1449              : !$OMP         descriptor_window_weight, gth_potential, iatom, idir, ispin, jdir, &
    1450              : !$OMP         nlcc_density, nlcc_gradient, nlcc_hessian, nlcc_spatial_derivative, &
    1451              : !$OMP         nlcc_spin_factor, partition_adjoint, composite_nlcc_center_force_local, &
    1452              : !$OMP         composite_partition_force_local, local_descriptor_datom, &
    1453              : !$OMP         local_descriptor_dstrain, local_partition_datom, local_partition_dstrain, &
    1454              : !$OMP         local_partition_weight, sgp_potential, source_atom, &
    1455              : !$OMP         spatial_derivative, target_atom, target_partition_adjoint) &
    1456              : !$OMP REDUCTION(+:composite_interpolation_virial, composite_partition_strain_virial) &
    1457              : !$OMP SHARED(cell, composite_atom_coord_grad, composite_atom_coords, composite_atom_end, &
    1458              : !$OMP        composite_atom_kind, composite_atom_start, composite_atomic_grid_weight_grad, &
    1459              : !$OMP        composite_atomic_grid_weights, composite_base_grid_weights, composite_density_grad, &
    1460              : !$OMP        composite_grad_grad, composite_grid_coord_force, composite_grid_coord_grad, &
    1461              : !$OMP        composite_grid_coords, composite_grid_weight_grad, composite_image_periodicity, &
    1462              : !$OMP        composite_kin_grad, composite_local_atoms, composite_local_natom, &
    1463              : !$OMP        composite_model_atom_force, composite_moving_smooth_force, &
    1464              : !$OMP        composite_nlcc_center_force, composite_nlcc_target_force, composite_partition_datom, &
    1465              : !$OMP        composite_partition_dstrain, composite_partition_force, composite_partition_included, &
    1466              : !$OMP        composite_partition_weights, composite_smooth_drho, composite_smooth_drhoa, &
    1467              : !$OMP        composite_smooth_drhob, composite_smooth_rho, composite_smooth_rhoa, &
    1468              : !$OMP        composite_smooth_rhob, composite_smooth_tau, composite_smooth_tau_a, &
    1469              : !$OMP        composite_smooth_tau_b, image_partition_atom_composite, lsd, my_kind_set, nlcc, &
    1470           64 : !$OMP        particle_set, smooth_rho_r)
    1471              :                ALLOCATE (composite_nlcc_center_force_local(3, SIZE(particle_set)), &
    1472              :                          composite_partition_force_local(3, SIZE(particle_set)), &
    1473              :                          local_partition_datom(3, SIZE(particle_set)))
    1474              :                composite_nlcc_center_force_local = 0.0_dp
    1475              :                composite_partition_force_local = 0.0_dp
    1476              : !$OMP DO SCHEDULE(DYNAMIC)
    1477              :                DO composite_local_atom = 1, composite_local_natom
    1478              :                   iatom = composite_local_atoms(composite_local_atom)
    1479              :                   composite_model_atom_force(:, iatom) = &
    1480              :                      composite_atom_coord_grad(:, composite_local_atom)
    1481              :                   DO composite_row = composite_atom_start(iatom), composite_atom_end(iatom)
    1482              :                      composite_grid_coord_force(:, iatom) = &
    1483              :                         composite_grid_coord_force(:, iatom) + &
    1484              :                         composite_grid_coord_grad(:, composite_row)
    1485              :                      IF (lsd) THEN
    1486              :                         spatial_derivative = &
    1487              :                            composite_density_grad(composite_row, 1)* &
    1488              :                            interpolate_native_grid_gradient( &
    1489              :                            composite_smooth_rhoa, smooth_rho_r(1)%pw_grid, cell, &
    1490              :                            composite_grid_coords(:, composite_row), &
    1491              :                            image_partition_atom_composite) + &
    1492              :                            composite_density_grad(composite_row, 2)* &
    1493              :                            interpolate_native_grid_gradient( &
    1494              :                            composite_smooth_rhob, smooth_rho_r(1)%pw_grid, cell, &
    1495              :                            composite_grid_coords(:, composite_row), &
    1496              :                            image_partition_atom_composite) + &
    1497              :                            composite_kin_grad(composite_row, 1)* &
    1498              :                            interpolate_native_grid_gradient( &
    1499              :                            composite_smooth_tau_a, smooth_rho_r(1)%pw_grid, cell, &
    1500              :                            composite_grid_coords(:, composite_row), &
    1501              :                            image_partition_atom_composite) + &
    1502              :                            composite_kin_grad(composite_row, 2)* &
    1503              :                            interpolate_native_grid_gradient( &
    1504              :                            composite_smooth_tau_b, smooth_rho_r(1)%pw_grid, cell, &
    1505              :                            composite_grid_coords(:, composite_row), &
    1506              :                            image_partition_atom_composite)
    1507              :                         DO idir = 1, 3
    1508              :                            spatial_derivative = spatial_derivative + &
    1509              :                                                 composite_grad_grad(composite_row, idir, 1)* &
    1510              :                                                 interpolate_native_grid_gradient( &
    1511              :                                                 composite_smooth_drhoa(idir)%array, &
    1512              :                                                 smooth_rho_r(1)%pw_grid, cell, &
    1513              :                                                 composite_grid_coords(:, composite_row), &
    1514              :                                                 image_partition_atom_composite) + &
    1515              :                                                 composite_grad_grad(composite_row, idir, 2)* &
    1516              :                                                 interpolate_native_grid_gradient( &
    1517              :                                                 composite_smooth_drhob(idir)%array, &
    1518              :                                                 smooth_rho_r(1)%pw_grid, cell, &
    1519              :                                                 composite_grid_coords(:, composite_row), &
    1520              :                                                 image_partition_atom_composite)
    1521              :                         END DO
    1522              :                      ELSE
    1523              :                         spatial_derivative = 0.5_dp*SUM( &
    1524              :                                              composite_density_grad(composite_row, :))* &
    1525              :                                              interpolate_native_grid_gradient( &
    1526              :                                              composite_smooth_rho, smooth_rho_r(1)%pw_grid, cell, &
    1527              :                                              composite_grid_coords(:, composite_row), &
    1528              :                                              image_partition_atom_composite) + &
    1529              :                                              0.5_dp*SUM(composite_kin_grad(composite_row, :))* &
    1530              :                                              interpolate_native_grid_gradient( &
    1531              :                                              composite_smooth_tau, smooth_rho_r(1)%pw_grid, cell, &
    1532              :                                              composite_grid_coords(:, composite_row), &
    1533              :                                              image_partition_atom_composite)
    1534              :                         DO idir = 1, 3
    1535              :                            spatial_derivative = spatial_derivative + 0.5_dp*SUM( &
    1536              :                                                 composite_grad_grad(composite_row, idir, :))* &
    1537              :                                                 interpolate_native_grid_gradient( &
    1538              :                                                 composite_smooth_drho(idir)%array, &
    1539              :                                                 smooth_rho_r(1)%pw_grid, &
    1540              :                                                 cell, composite_grid_coords(:, composite_row), &
    1541              :                                                 image_partition_atom_composite)
    1542              :                         END DO
    1543              :                      END IF
    1544              :                      DO idir = 1, 3
    1545              :                         DO jdir = 1, 3
    1546              :                            composite_interpolation_virial(idir, jdir) = &
    1547              :                               composite_interpolation_virial(idir, jdir) + &
    1548              :                               spatial_derivative(idir)*( &
    1549              :                               composite_grid_coords(jdir, composite_row) - &
    1550              :                               particle_set(iatom)%r(jdir))
    1551              :                         END DO
    1552              :                      END DO
    1553              :                      composite_moving_smooth_force(:, iatom) = &
    1554              :                         composite_moving_smooth_force(:, iatom) + spatial_derivative
    1555              :                      IF (nlcc) THEN
    1556              :                         nlcc_spin_factor = MERGE(1.0_dp, 0.5_dp, lsd)
    1557              :                         DO source_atom = 1, SIZE(particle_set)
    1558              :                            NULLIFY (gth_potential, sgp_potential)
    1559              :                            CALL get_qs_kind(my_kind_set(composite_atom_kind(source_atom)), &
    1560              :                                             gth_potential=gth_potential, &
    1561              :                                             sgp_potential=sgp_potential)
    1562              :                            CALL evaluate_nlcc_primitive_fields( &
    1563              :                               composite_grid_coords(:, composite_row), &
    1564              :                               particle_set(source_atom)%r, gth_potential, sgp_potential, &
    1565              :                               nlcc_density, nlcc_gradient, nlcc_hessian)
    1566              :                            nlcc_spatial_derivative = 0.0_dp
    1567              :                            DO ispin = 1, 2
    1568              :                               nlcc_spatial_derivative = nlcc_spatial_derivative + &
    1569              :                                                         nlcc_spin_factor*composite_density_grad(composite_row, ispin)* &
    1570              :                                                         nlcc_gradient
    1571              :                               DO idir = 1, 3
    1572              :                                  DO jdir = 1, 3
    1573              :                                     nlcc_spatial_derivative(jdir) = &
    1574              :                                        nlcc_spatial_derivative(jdir) + nlcc_spin_factor* &
    1575              :                                        composite_grad_grad(composite_row, idir, ispin)* &
    1576              :                                        nlcc_hessian(idir, jdir)
    1577              :                                  END DO
    1578              :                               END DO
    1579              :                            END DO
    1580              :                            composite_nlcc_target_force(:, iatom) = &
    1581              :                               composite_nlcc_target_force(:, iatom) + nlcc_spatial_derivative
    1582              :                            composite_nlcc_center_force_local(:, source_atom) = &
    1583              :                               composite_nlcc_center_force_local(:, source_atom) - nlcc_spatial_derivative
    1584              :                         END DO
    1585              :                      END IF
    1586              :                      IF (image_partition_atom_composite) THEN
    1587              :                         CALL periodic_atom_image_partition( &
    1588              :                            composite_grid_coords(:, composite_row), composite_atom_coords, cell, &
    1589              :                            iatom, local_partition_weight, local_partition_datom, &
    1590              :                            local_partition_dstrain, composite_image_periodicity)
    1591              :                         CALL periodic_atom_image_partition( &
    1592              :                            composite_grid_coords(:, composite_row), &
    1593              :                            composite_atom_coords(:, iatom:iatom), cell, 1, &
    1594              :                            descriptor_window_weight, local_descriptor_datom, &
    1595              :                            local_descriptor_dstrain, composite_image_periodicity)
    1596              :                         ! Its atom derivative cancels against the moving target grid; periodic
    1597              :                         ! image strain remains an explicit contribution to the virial.
    1598              :                         target_partition_adjoint = composite_base_grid_weights(composite_row)* &
    1599              :                                                    composite_grid_weight_grad(composite_row)
    1600              :                         descriptor_window_adjoint = composite_base_grid_weights(composite_row)* &
    1601              :                                                     composite_atomic_grid_weight_grad(composite_row)* &
    1602              :                                                     smooth_partition_atomic_weight_scale_derivative( &
    1603              :                                                     descriptor_window_weight)
    1604              :                         DO target_atom = 1, SIZE(particle_set)
    1605              :                            composite_partition_force_local(:, target_atom) = &
    1606              :                               composite_partition_force_local(:, target_atom) + &
    1607              :                               target_partition_adjoint*local_partition_datom(:, target_atom)
    1608              :                         END DO
    1609              :                         composite_partition_force_local(:, iatom) = &
    1610              :                            composite_partition_force_local(:, iatom) - target_partition_adjoint* &
    1611              :                            SUM(local_partition_datom, DIM=2)
    1612              :                         composite_partition_strain_virial = &
    1613              :                            composite_partition_strain_virial - target_partition_adjoint* &
    1614              :                            local_partition_dstrain - descriptor_window_adjoint* &
    1615              :                            local_descriptor_dstrain
    1616              :                      ELSE
    1617              :                         CALL skala_gpw_smooth_partition_derivatives( &
    1618              :                            composite_grid_coords(:, composite_row), composite_atom_coords, cell, &
    1619              :                            composite_partition_weights, composite_partition_included, &
    1620              :                            composite_partition_datom, composite_partition_dstrain)
    1621              :                         partition_adjoint = composite_grid_weight_grad(composite_row)* &
    1622              :                                             composite_atomic_grid_weights(composite_row)
    1623              :                         DO target_atom = 1, SIZE(particle_set)
    1624              :                            composite_partition_force_local(:, target_atom) = &
    1625              :                               composite_partition_force_local(:, target_atom) + &
    1626              :                               partition_adjoint* &
    1627              :                               composite_partition_datom(:, target_atom, iatom)
    1628              :                         END DO
    1629              :                         composite_partition_force_local(:, iatom) = &
    1630              :                            composite_partition_force_local(:, iatom) - partition_adjoint* &
    1631              :                            SUM(composite_partition_datom(:, :, iatom), DIM=2)
    1632              :                      END IF
    1633              :                   END DO
    1634              :                END DO
    1635              : !$OMP END DO
    1636              : !$OMP CRITICAL(skala_atom_composite_force_reduction)
    1637              :                composite_nlcc_center_force(:, :) = composite_nlcc_center_force(:, :) + &
    1638              :                                                    composite_nlcc_center_force_local
    1639              :                composite_partition_force(:, :) = composite_partition_force(:, :) + &
    1640              :                                                  composite_partition_force_local
    1641              : !$OMP END CRITICAL(skala_atom_composite_force_reduction)
    1642              :                DEALLOCATE (composite_nlcc_center_force_local, composite_partition_force_local, &
    1643           64 :                            local_partition_datom)
    1644              : !$OMP END PARALLEL
    1645              :                ! The target atom grids can overlap augmentation regions of other atoms
    1646              :                ! and periodic images. Differentiate the same discrete interpolation used
    1647              :                ! in the forward composite fields, including the explicit image strain.
    1648           64 :                IF (.NOT. direct_valence_atom_composite) THEN
    1649           90 :                   DO ikind = 1, SIZE(atomic_kind_set)
    1650           54 :                      CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    1651           54 :                      NULLIFY (gth_potential, sgp_potential)
    1652              :                      CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
    1653              :                                       gth_potential=gth_potential, harmonics=harmonics, &
    1654              :                                       grid_atom=grid_atom, sgp_potential=sgp_potential, &
    1655           54 :                                       zatom=zatom, zeff=zeff)
    1656           54 :                      CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    1657           66 :                      IF (.NOT. native_skala_uses_one_center_kind( &
    1658              :                          paw_atom, gapw_representation, &
    1659              :                          ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential), &
    1660              :                          zeff, zatom)) CYCLE
    1661              : 
    1662           52 :                      nr = grid_atom%nr
    1663           52 :                      na = grid_atom%ng_sphere
    1664           52 :                      CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    1665           52 :                      CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
    1666           52 :                      CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
    1667           52 :                      CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
    1668           52 :                      CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
    1669           52 :                      CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
    1670           52 :                      CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
    1671              : 
    1672          122 :                      DO iat = 1, natom
    1673           70 :                         source_atom = atom_list(iat)
    1674           70 :                         rho_atom => my_rho_atom_set(source_atom)
    1675           70 :                         NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    1676              :                         CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s, &
    1677              :                                           drho_rad_h=dr_h, drho_rad_s=dr_s, &
    1678           70 :                                           rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
    1679       102140 :                         rho_h = 0.0_dp
    1680       102140 :                         rho_s = 0.0_dp
    1681       500220 :                         drho_h = 0.0_dp
    1682       500220 :                         drho_s = 0.0_dp
    1683           70 :                         CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
    1684         2550 :                         DO ir = 1, nr
    1685              :                            CALL calc_rho_angular(grid_atom, harmonics, nspins, .TRUE., &
    1686              :                                                  ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
    1687         2550 :                                                  r_h_d, r_s_d, drho_h, drho_s)
    1688              :                         END DO
    1689              : 
    1690              :                         cross_cutoff = gapw_atom_grid_support_radius( &
    1691           70 :                                        grid_atom, rho_h, rho_s, drho_h, drho_s, tau_h, tau_s)
    1692           70 :                         IF (cross_cutoff <= 0.0_dp) CYCLE
    1693           58 :                         image_shell = 0
    1694          232 :                         DO idir = 1, 3
    1695          232 :                            IF (cell%perd(idir) == 1) THEN
    1696              :                               image_shell(idir) = CEILING( &
    1697          600 :                                                   cross_cutoff*SQRT(SUM(cell%h_inv(idir, :)**2))) + 1
    1698              :                            END IF
    1699              :                         END DO
    1700              : 
    1701              : !$OMP PARALLEL DEFAULT(NONE) &
    1702              : !$OMP PRIVATE(base_shift, composite_cross_force_local, composite_cross_image_virial_local, &
    1703              : !$OMP         composite_row, cross_density, cross_density_adjoint, cross_density_spatial, &
    1704              : !$OMP         cross_displacement, cross_grad, cross_grad_adjoint, cross_grad_spatial, &
    1705              : !$OMP         cross_kin, cross_kin_adjoint, cross_kin_spatial, cross_spatial_derivative, &
    1706              : !$OMP         fractional, idir, image_i1, image_i2, image_i3, image_shift, image_translation, &
    1707              : !$OMP         ispin, jdir, target_atom) &
    1708              : !$OMP SHARED(cell, composite_cross_force, composite_cross_image_virial, &
    1709              : !$OMP        composite_density_grad, composite_grad_grad, composite_grid_atom, &
    1710              : !$OMP        composite_grid_coords, composite_kin_grad, composite_nflat, cross_cutoff, &
    1711              : !$OMP        drho_h, drho_s, grid_atom, harmonics, image_shell, lsd, nspins, &
    1712              : !$OMP        particle_set, rho_h, rho_s, source_atom, tau_h, tau_s, &
    1713          122 : !$OMP        use_atom_composite_density, use_atom_composite_gradient, use_atom_composite_tau)
    1714              :                         ALLOCATE (composite_cross_force_local(3, SIZE(particle_set)))
    1715              :                         composite_cross_force_local = 0.0_dp
    1716              :                         composite_cross_image_virial_local = 0.0_dp
    1717              : !$OMP DO SCHEDULE(STATIC)
    1718              :                         DO composite_row = 1, composite_nflat
    1719              :                            target_atom = composite_grid_atom(composite_row)
    1720              :                            IF (lsd) THEN
    1721              :                               cross_density_adjoint = 0.0_dp
    1722              :                               cross_grad_adjoint = 0.0_dp
    1723              :                               cross_kin_adjoint = 0.0_dp
    1724              :                               IF (use_atom_composite_density) THEN
    1725              :                                  cross_density_adjoint(1:2) = &
    1726              :                                     composite_density_grad(composite_row, 1:2)
    1727              :                               END IF
    1728              :                               IF (use_atom_composite_gradient) THEN
    1729              :                                  cross_grad_adjoint(:, 1:2) = &
    1730              :                                     composite_grad_grad(composite_row, :, 1:2)
    1731              :                               END IF
    1732              :                               IF (use_atom_composite_tau) THEN
    1733              :                                  cross_kin_adjoint(1:2) = &
    1734              :                                     composite_kin_grad(composite_row, 1:2)
    1735              :                               END IF
    1736              :                            ELSE
    1737              :                               cross_density_adjoint = 0.0_dp
    1738              :                               cross_grad_adjoint = 0.0_dp
    1739              :                               cross_kin_adjoint = 0.0_dp
    1740              :                               IF (use_atom_composite_density) THEN
    1741              :                                  cross_density_adjoint(1) = 0.5_dp* &
    1742              :                                                             SUM(composite_density_grad(composite_row, :))
    1743              :                               END IF
    1744              :                               IF (use_atom_composite_gradient) THEN
    1745              :                                  DO idir = 1, 3
    1746              :                                     cross_grad_adjoint(idir, 1) = 0.5_dp* &
    1747              :                                                                   SUM(composite_grad_grad(composite_row, idir, :))
    1748              :                                  END DO
    1749              :                               END IF
    1750              :                               IF (use_atom_composite_tau) THEN
    1751              :                                  cross_kin_adjoint(1) = 0.5_dp* &
    1752              :                                                         SUM(composite_kin_grad(composite_row, :))
    1753              :                               END IF
    1754              :                            END IF
    1755              : 
    1756              :                            fractional = 0.0_dp
    1757              :                            DO idir = 1, 3
    1758              :                               DO jdir = 1, 3
    1759              :                                  fractional(idir) = fractional(idir) + cell%h_inv(idir, jdir)* &
    1760              :                                                     (composite_grid_coords(jdir, composite_row) - &
    1761              :                                                      particle_set(source_atom)%r(jdir))
    1762              :                               END DO
    1763              :                            END DO
    1764              :                            DO idir = 1, 3
    1765              :                               base_shift(idir) = cell%perd(idir)*NINT(fractional(idir))
    1766              :                            END DO
    1767              :                            DO image_i3 = base_shift(3) - image_shell(3), &
    1768              :                               base_shift(3) + image_shell(3)
    1769              :                               DO image_i2 = base_shift(2) - image_shell(2), &
    1770              :                                  base_shift(2) + image_shell(2)
    1771              :                                  DO image_i1 = base_shift(1) - image_shell(1), &
    1772              :                                     base_shift(1) + image_shell(1)
    1773              :                                     image_shift = [image_i1, image_i2, image_i3]
    1774              :                                     IF (target_atom == source_atom .AND. &
    1775              :                                         ALL(image_shift == 0)) CYCLE
    1776              :                                     image_translation = MATMUL( &
    1777              :                                                         cell%hmat, REAL(image_shift, dp))
    1778              :                                     cross_displacement = &
    1779              :                                        composite_grid_coords(:, composite_row) - &
    1780              :                                        particle_set(source_atom)%r - image_translation
    1781              :                                     CALL interpolate_gapw_atom_grid_fields( &
    1782              :                                        grid_atom, harmonics, cross_displacement, cross_cutoff, &
    1783              :                                        nspins, rho_h, rho_s, drho_h, drho_s, tau_h, tau_s, &
    1784              :                                        cross_density, cross_grad, cross_kin, cross_density_spatial, &
    1785              :                                        cross_grad_spatial, cross_kin_spatial)
    1786              :                                     cross_spatial_derivative = 0.0_dp
    1787              :                                     DO ispin = 1, nspins
    1788              :                                        DO idir = 1, 3
    1789              :                                           cross_spatial_derivative(idir) = &
    1790              :                                              cross_spatial_derivative(idir) + &
    1791              :                                              cross_density_adjoint(ispin)* &
    1792              :                                              cross_density_spatial(idir, ispin) + &
    1793              :                                              cross_kin_adjoint(ispin)* &
    1794              :                                              cross_kin_spatial(idir, ispin)
    1795              :                                           DO jdir = 1, 3
    1796              :                                              cross_spatial_derivative(idir) = &
    1797              :                                                 cross_spatial_derivative(idir) + &
    1798              :                                                 cross_grad_adjoint(jdir, ispin)* &
    1799              :                                                 cross_grad_spatial(jdir, idir, ispin)
    1800              :                                           END DO
    1801              :                                        END DO
    1802              :                                     END DO
    1803              :                                     composite_cross_force_local(:, target_atom) = &
    1804              :                                        composite_cross_force_local(:, target_atom) + &
    1805              :                                        cross_spatial_derivative
    1806              :                                     composite_cross_force_local(:, source_atom) = &
    1807              :                                        composite_cross_force_local(:, source_atom) - &
    1808              :                                        cross_spatial_derivative
    1809              :                                     DO idir = 1, 3
    1810              :                                        DO jdir = 1, 3
    1811              :                                           composite_cross_image_virial_local(idir, jdir) = &
    1812              :                                              composite_cross_image_virial_local(idir, jdir) + &
    1813              :                                              cross_spatial_derivative(idir)*image_translation(jdir)
    1814              :                                        END DO
    1815              :                                     END DO
    1816              :                                  END DO
    1817              :                               END DO
    1818              :                            END DO
    1819              :                         END DO
    1820              : !$OMP END DO
    1821              : !$OMP CRITICAL(skala_atom_composite_cross_reduction)
    1822              :                         composite_cross_force(:, :) = &
    1823              :                            composite_cross_force(:, :) + composite_cross_force_local(:, :)
    1824              :                         composite_cross_image_virial = composite_cross_image_virial + &
    1825              :                                                        composite_cross_image_virial_local
    1826              : !$OMP END CRITICAL(skala_atom_composite_cross_reduction)
    1827              :                         DEALLOCATE (composite_cross_force_local)
    1828              : !$OMP END PARALLEL
    1829              :                      END DO
    1830          142 :                      CALL release_tau_basis_cache(tau_basis_cache)
    1831              :                   END DO
    1832              :                END IF
    1833              : 
    1834              :                composite_explicit_force(:, :) = composite_model_atom_force(:, :) + &
    1835              :                                                 composite_grid_coord_force(:, :) + &
    1836              :                                                 composite_moving_smooth_force(:, :) + &
    1837              :                                                 composite_cross_force(:, :) + &
    1838              :                                                 composite_nlcc_center_force(:, :) + &
    1839              :                                                 composite_nlcc_target_force(:, :) + &
    1840          576 :                                                 composite_partition_force(:, :)
    1841              :                ! CP2K stores +dE/dR in the electronic force components, while the
    1842              :                ! virial is -dE/dstrain. Model coordinates, atom-grid centers,
    1843              :                ! NLCC centers, and partition centers move affinely with their atoms.
    1844              :                ! The smooth-field interpolation force is excluded here: its affine
    1845              :                ! response is already in the PW stress and its non-affine local-grid
    1846              :                ! correction is composite_interpolation_virial.
    1847          192 :                DO iatom = 1, SIZE(particle_set)
    1848          576 :                   DO idir = 1, 3
    1849         1664 :                      DO jdir = 1, 3
    1850              :                         composite_explicit_virial(idir, jdir) = &
    1851              :                            composite_explicit_virial(idir, jdir) - ( &
    1852              :                            composite_model_atom_force(idir, iatom) + &
    1853              :                            composite_grid_coord_force(idir, iatom) + &
    1854              :                            composite_cross_force(idir, iatom) + &
    1855              :                            composite_nlcc_center_force(idir, iatom) + &
    1856              :                            composite_nlcc_target_force(idir, iatom) + &
    1857         1536 :                            composite_partition_force(idir, iatom))*particle_set(iatom)%r(jdir)
    1858              :                      END DO
    1859              :                   END DO
    1860              :                END DO
    1861              :                composite_explicit_virial = composite_explicit_virial + &
    1862              :                                            composite_partition_strain_virial + &
    1863          832 :                                            composite_cross_image_virial
    1864           64 :                IF (ASSOCIATED(force)) THEN
    1865          192 :                   DO iatom = 1, SIZE(particle_set)
    1866          128 :                      ikind = composite_atom_kind(iatom)
    1867          128 :                      iat = composite_atom_kind_index(iatom)
    1868          128 :                      CPASSERT(ikind > 0 .AND. iat > 0)
    1869              :                      force(ikind)%rho_elec(:, iat) = force(ikind)%rho_elec(:, iat) + &
    1870          576 :                                                      composite_explicit_force(:, iatom)
    1871              :                   END DO
    1872              :                END IF
    1873           64 :                IF (use_virial) THEN
    1874              :                   ! The local radial vectors of the atom-centered quadrature do not
    1875              :                   ! deform with the periodic cell. Correct the standard PW response,
    1876              :                   ! which follows fixed fractional coordinates, by the corresponding
    1877              :                   ! non-affine interpolation derivative.
    1878          702 :                   virial%pv_xc = composite_feature_virial - composite_interpolation_virial
    1879          702 :                   virial%pv_gapw = virial%pv_gapw + composite_explicit_virial
    1880          702 :                   virial%pv_virial = virial%pv_virial + composite_explicit_virial
    1881              :                END IF
    1882           64 :                IF (native_grid_diagnostics) THEN
    1883           14 :                   CALL para_env%sum(composite_cross_force)
    1884           14 :                   CALL para_env%sum(composite_cross_image_virial)
    1885           14 :                   CALL para_env%sum(composite_model_atom_force)
    1886           14 :                   CALL para_env%sum(composite_grid_coord_force)
    1887           14 :                   CALL para_env%sum(composite_moving_smooth_force)
    1888           14 :                   CALL para_env%sum(composite_nlcc_center_force)
    1889           14 :                   CALL para_env%sum(composite_nlcc_target_force)
    1890           14 :                   CALL para_env%sum(composite_partition_force)
    1891           14 :                   CALL para_env%sum(composite_explicit_force)
    1892           14 :                   CALL para_env%sum(composite_explicit_virial)
    1893           14 :                   CALL para_env%sum(composite_feature_virial)
    1894           14 :                   CALL para_env%sum(composite_interpolation_virial)
    1895           14 :                   iw = cp_logger_get_default_io_unit()
    1896           14 :                   IF (iw > 0) THEN
    1897           21 :                      DO iatom = 1, SIZE(particle_set)
    1898              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1899           14 :                            "SKALA_GPW| Atom-composite model-atom force", iatom, &
    1900           28 :                            composite_model_atom_force(:, iatom)
    1901              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1902           14 :                            "SKALA_GPW| Atom-composite grid-coordinate force", iatom, &
    1903           28 :                            composite_grid_coord_force(:, iatom)
    1904              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1905           14 :                            "SKALA_GPW| Atom-composite moving-smooth force", iatom, &
    1906           28 :                            composite_moving_smooth_force(:, iatom)
    1907              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1908           14 :                            "SKALA_GPW| Atom-composite cross-region force", iatom, &
    1909           28 :                            composite_cross_force(:, iatom)
    1910              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1911           14 :                            "SKALA_GPW| Atom-composite NLCC-center force", iatom, &
    1912           28 :                            composite_nlcc_center_force(:, iatom)
    1913              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1914           14 :                            "SKALA_GPW| Atom-composite NLCC-target force", iatom, &
    1915           28 :                            composite_nlcc_target_force(:, iatom)
    1916              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1917           14 :                            "SKALA_GPW| Atom-composite partition force", iatom, &
    1918           28 :                            composite_partition_force(:, iatom)
    1919              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
    1920           14 :                            "SKALA_GPW| Atom-composite explicit force", iatom, &
    1921           35 :                            composite_explicit_force(:, iatom)
    1922              :                      END DO
    1923              :                      WRITE (UNIT=iw, FMT="(T2,A)") &
    1924            7 :                         "SKALA_GPW| Atom-composite explicit virial"
    1925           28 :                      DO idir = 1, 3
    1926              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,3ES20.10)") &
    1927           28 :                            "SKALA_GPW|", composite_explicit_virial(idir, :)
    1928              :                      END DO
    1929              :                      WRITE (UNIT=iw, FMT="(T2,A)") &
    1930            7 :                         "SKALA_GPW| Atom-composite cross-image virial"
    1931           28 :                      DO idir = 1, 3
    1932              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,3ES20.10)") &
    1933           28 :                            "SKALA_GPW|", composite_cross_image_virial(idir, :)
    1934              :                      END DO
    1935              :                      WRITE (UNIT=iw, FMT="(T2,A)") &
    1936            7 :                         "SKALA_GPW| Atom-composite feature virial"
    1937           28 :                      DO idir = 1, 3
    1938              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,3ES20.10)") &
    1939           28 :                            "SKALA_GPW|", composite_feature_virial(idir, :)
    1940              :                      END DO
    1941              :                      WRITE (UNIT=iw, FMT="(T2,A)") &
    1942            7 :                         "SKALA_GPW| Atom-composite interpolation virial"
    1943           28 :                      DO idir = 1, 3
    1944              :                         WRITE (UNIT=iw, FMT="(T2,A,1X,3ES20.10)") &
    1945           28 :                            "SKALA_GPW|", composite_interpolation_virial(idir, :)
    1946              :                      END DO
    1947              :                   END IF
    1948              :                END IF
    1949            0 :                DEALLOCATE (composite_atom_coord_grad, composite_atomic_grid_weight_grad, &
    1950            0 :                            composite_cross_force, &
    1951            0 :                            composite_explicit_force, composite_grid_coord_force, &
    1952            0 :                            composite_grid_coord_grad, composite_grid_weight_grad, &
    1953            0 :                            composite_model_atom_force, composite_moving_smooth_force, &
    1954            0 :                            composite_nlcc_center_force, &
    1955            0 :                            composite_nlcc_target_force, &
    1956            0 :                            composite_partition_datom, composite_partition_dstrain, &
    1957           64 :                            composite_partition_force, composite_partition_included)
    1958              :             ELSE
    1959              :                CALL skala_gapw_atom_composite_energy( &
    1960              :                   my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
    1961              :                   composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
    1962              :                   composite_local_grid_sizes, composite_local_atom_coords, atom_composite_exc, &
    1963          200 :                   composite_density_grad, composite_grad_grad, composite_kin_grad)
    1964              :             END IF
    1965         1056 :             composite_pw_nflat = PRODUCT(smooth_rho_r(1)%pw_grid%npts)
    1966          264 :             adjoint_nchannels = MERGE(2, 1, lsd)
    1967            0 :             ALLOCATE (smooth_density_adjoint_storage(composite_pw_nflat, adjoint_nchannels), &
    1968            0 :                       smooth_grad_adjoint_storage(composite_pw_nflat, 3, adjoint_nchannels), &
    1969         2376 :                       smooth_kin_adjoint_storage(composite_pw_nflat, adjoint_nchannels))
    1970          264 :             smooth_density_adjoint_storage = 0.0_dp
    1971          264 :             smooth_grad_adjoint_storage = 0.0_dp
    1972          264 :             smooth_kin_adjoint_storage = 0.0_dp
    1973              :             CALL build_native_grid_adjoint_bins( &
    1974              :                smooth_rho_r(1)%pw_grid, cell, composite_grid_coords, &
    1975              :                image_partition_atom_composite, adjoint_tile_count, adjoint_bin_offsets, &
    1976          264 :                adjoint_bin_rows)
    1977          264 :             adjoint_nbins = SIZE(adjoint_bin_offsets) - 1
    1978              : !$OMP PARALLEL DO SCHEDULE(DYNAMIC) DEFAULT(NONE) &
    1979              : !$OMP PRIVATE(adjoint_entry, composite_row, composite_smooth_density_adjoint_value, &
    1980              : !$OMP         composite_smooth_gradient_adjoint_value, composite_smooth_kin_adjoint_value, &
    1981              : !$OMP         adjoint_tile_lower, adjoint_tile_upper, interpolation_stencil) &
    1982              : !$OMP SHARED(adjoint_bin_offsets, adjoint_bin_rows, adjoint_nbins, adjoint_nchannels, &
    1983              : !$OMP        adjoint_tile_count, cell, composite_density_grad, composite_grad_grad, &
    1984              : !$OMP        composite_grid_coords, composite_kin_grad, image_partition_atom_composite, lsd, &
    1985              : !$OMP        smooth_density_adjoint_storage, smooth_grad_adjoint_storage, &
    1986          264 : !$OMP        smooth_kin_adjoint_storage, smooth_rho_r)
    1987              :             DO adjoint_bin = 1, adjoint_nbins
    1988              :                CALL native_grid_adjoint_tile_bounds( &
    1989              :                   smooth_rho_r(1)%pw_grid, adjoint_bin, adjoint_tile_count, &
    1990              :                   adjoint_tile_lower, adjoint_tile_upper)
    1991              :                DO adjoint_entry = adjoint_bin_offsets(adjoint_bin), &
    1992              :                   adjoint_bin_offsets(adjoint_bin + 1) - 1
    1993              :                   composite_row = adjoint_bin_rows(adjoint_entry)
    1994              :                   CALL create_native_grid_interpolation_stencil( &
    1995              :                      interpolation_stencil, smooth_rho_r(1)%pw_grid, cell, &
    1996              :                      composite_grid_coords(:, composite_row), image_partition_atom_composite)
    1997              :                   IF (lsd) THEN
    1998              :                      composite_smooth_density_adjoint_value = &
    1999              :                         composite_density_grad(composite_row, :)
    2000              :                      composite_smooth_gradient_adjoint_value = &
    2001              :                         composite_grad_grad(composite_row, :, :)
    2002              :                      composite_smooth_kin_adjoint_value = composite_kin_grad(composite_row, :)
    2003              :                   ELSE
    2004              :                      composite_smooth_density_adjoint_value = 0.0_dp
    2005              :                      composite_smooth_gradient_adjoint_value = 0.0_dp
    2006              :                      composite_smooth_kin_adjoint_value = 0.0_dp
    2007              :                      composite_smooth_density_adjoint_value(1) = &
    2008              :                         SUM(composite_density_grad(composite_row, :))
    2009              :                      composite_smooth_gradient_adjoint_value(:, 1) = &
    2010              :                         SUM(composite_grad_grad(composite_row, :, :), DIM=2)
    2011              :                      composite_smooth_kin_adjoint_value(1) = &
    2012              :                         SUM(composite_kin_grad(composite_row, :))
    2013              :                   END IF
    2014              :                   CALL add_native_grid_fields_adjoint_tile( &
    2015              :                      smooth_density_adjoint_storage, smooth_grad_adjoint_storage, &
    2016              :                      smooth_kin_adjoint_storage, smooth_rho_r(1)%pw_grid, interpolation_stencil, &
    2017              :                      composite_smooth_density_adjoint_value, &
    2018              :                      composite_smooth_gradient_adjoint_value, &
    2019              :                      composite_smooth_kin_adjoint_value, adjoint_nchannels, &
    2020              :                      adjoint_tile_lower, adjoint_tile_upper)
    2021              :                END DO
    2022              :             END DO
    2023              : !$OMP END PARALLEL DO
    2024          264 :             DEALLOCATE (adjoint_bin_offsets, adjoint_bin_rows)
    2025              :             smooth_input_contraction = 0.0_dp
    2026              : !$OMP PARALLEL DO SCHEDULE(STATIC) REDUCTION(+:smooth_input_contraction) DEFAULT(NONE) &
    2027              : !$OMP PRIVATE(composite_smooth_density_value, composite_smooth_gradient_value, &
    2028              : !$OMP         composite_smooth_kin_value, idir, ispin) &
    2029              : !$OMP SHARED(composite_density_grad, composite_grad_grad, composite_kin_grad, composite_nflat, &
    2030              : !$OMP        composite_smooth_density_cache, composite_smooth_gradient_cache, &
    2031          264 : !$OMP        composite_smooth_kin_cache, lsd)
    2032              :             DO composite_row = 1, composite_nflat
    2033              :                composite_smooth_density_value = composite_smooth_density_cache(composite_row, :)
    2034              :                composite_smooth_gradient_value = &
    2035              :                   composite_smooth_gradient_cache(composite_row, :, :)
    2036              :                composite_smooth_kin_value = composite_smooth_kin_cache(composite_row, :)
    2037              :                DO ispin = 1, 2
    2038              :                   IF (lsd) THEN
    2039              :                      smooth_input_contraction = smooth_input_contraction + &
    2040              :                                                 composite_density_grad(composite_row, ispin)* &
    2041              :                                                 composite_smooth_density_value(ispin) + &
    2042              :                                                 composite_kin_grad(composite_row, ispin)* &
    2043              :                                                 composite_smooth_kin_value(ispin)
    2044              :                      DO idir = 1, 3
    2045              :                         smooth_input_contraction = smooth_input_contraction + &
    2046              :                                                    composite_grad_grad(composite_row, idir, ispin)* &
    2047              :                                                    composite_smooth_gradient_value(idir, ispin)
    2048              :                      END DO
    2049              :                   ELSE
    2050              :                      smooth_input_contraction = smooth_input_contraction + 0.5_dp*( &
    2051              :                                                 composite_density_grad(composite_row, ispin)* &
    2052              :                                                 composite_smooth_density_value(1) + &
    2053              :                                                 composite_kin_grad(composite_row, ispin)* &
    2054              :                                                 composite_smooth_kin_value(1))
    2055              :                      DO idir = 1, 3
    2056              :                         smooth_input_contraction = smooth_input_contraction + 0.5_dp* &
    2057              :                                                    composite_grad_grad(composite_row, idir, ispin)* &
    2058              :                                                    composite_smooth_gradient_value(idir, 1)
    2059              :                      END DO
    2060              :                   END IF
    2061              :                END DO
    2062              :             END DO
    2063              : !$OMP END PARALLEL DO
    2064          264 :             smooth_density_adjoint => smooth_density_adjoint_storage
    2065          264 :             smooth_grad_adjoint => smooth_grad_adjoint_storage
    2066          264 :             smooth_kin_adjoint => smooth_kin_adjoint_storage
    2067              :             ! The interpolation transpose still uses CP2K's global FFT-grid layout. Reduce only
    2068              :             ! this PW adjoint; atom-grid feature rows and their model derivatives stay rank-local.
    2069      4735008 :             CALL para_env%sum(smooth_density_adjoint)
    2070     14205108 :             CALL para_env%sum(smooth_grad_adjoint)
    2071      4735008 :             CALL para_env%sum(smooth_kin_adjoint)
    2072          264 :             CALL para_env%sum(smooth_input_contraction)
    2073              :             CALL build_vxc_from_feature_grads( &
    2074              :                smooth_vxc_rho, smooth_vxc_tau, smooth_rho_r, auxbas_pw_pool, &
    2075              :                smooth_density_adjoint, smooth_grad_adjoint, smooth_kin_adjoint, &
    2076          264 :                xc_deriv_method_id, global_grid_layout=.TRUE.)
    2077          264 :             NULLIFY (smooth_density_adjoint, smooth_grad_adjoint, smooth_kin_adjoint)
    2078            0 :             DEALLOCATE (smooth_density_adjoint_storage, smooth_grad_adjoint_storage, &
    2079          264 :                         smooth_kin_adjoint_storage)
    2080          264 :             smooth_grid_contraction = 0.0_dp
    2081          570 :             DO ispin = 1, nspins
    2082              :                smooth_grid_contraction = smooth_grid_contraction + smooth_rho_r(1)%pw_grid%dvol* &
    2083              :                                          (SUM(smooth_vxc_rho(ispin)%array* &
    2084              :                                               smooth_rho_r(ispin)%array) + &
    2085              :                                           SUM(smooth_vxc_tau(ispin)%array* &
    2086      2597028 :                                               smooth_tau_r(ispin)%array))
    2087          306 :                IF (atom_composite_reference) THEN
    2088          306 :                   CPASSERT(PRESENT(composite_vxc_rho))
    2089          306 :                   CPASSERT(PRESENT(composite_vxc_tau))
    2090          306 :                   CPASSERT(ASSOCIATED(composite_vxc_rho))
    2091          306 :                   CPASSERT(ASSOCIATED(composite_vxc_tau))
    2092          306 :                   CPASSERT(SIZE(composite_vxc_rho) == nspins)
    2093          306 :                   CPASSERT(SIZE(composite_vxc_tau) == nspins)
    2094          306 :                   CALL pw_axpy(smooth_vxc_rho(ispin), composite_vxc_rho(ispin), 1.0_dp)
    2095          306 :                   CALL pw_axpy(smooth_vxc_tau(ispin), composite_vxc_tau(ispin), 1.0_dp)
    2096              :                END IF
    2097          306 :                CALL auxbas_pw_pool%give_back_pw(smooth_vxc_rho(ispin))
    2098          570 :                CALL auxbas_pw_pool%give_back_pw(smooth_vxc_tau(ispin))
    2099              :             END DO
    2100          264 :             CALL para_env%sum(smooth_grid_contraction)
    2101          264 :             DEALLOCATE (smooth_vxc_rho, smooth_vxc_tau)
    2102              : 
    2103          264 :             one_center_field_contraction = 0.0_dp
    2104          264 :             one_center_matrix_contraction = 0.0_dp
    2105          264 :             one_center_density_field_contraction = 0.0_dp
    2106          264 :             one_center_density_matrix_contraction = 0.0_dp
    2107          264 :             one_center_gradient_field_contraction = 0.0_dp
    2108          264 :             one_center_gradient_matrix_contraction = 0.0_dp
    2109          264 :             one_center_rho_grad_field_contraction = 0.0_dp
    2110          264 :             one_center_rho_grad_matrix_contraction = 0.0_dp
    2111          264 :             one_center_tau_field_contraction = 0.0_dp
    2112          264 :             one_center_tau_matrix_contraction = 0.0_dp
    2113          264 :             IF (.NOT. direct_valence_atom_composite) THEN
    2114          292 :                DO ikind = 1, SIZE(atomic_kind_set)
    2115          164 :                   CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    2116          164 :                   NULLIFY (gth_potential, sgp_potential)
    2117              :                   CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
    2118              :                                    gth_potential=gth_potential, harmonics=harmonics, &
    2119              :                                    grid_atom=grid_atom, sgp_potential=sgp_potential, &
    2120          164 :                                    zatom=zatom, zeff=zeff)
    2121          164 :                   CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    2122          188 :                   IF (.NOT. native_skala_uses_one_center_kind( &
    2123              :                       paw_atom, gapw_representation, &
    2124              :                       ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential), &
    2125              :                       zeff, zatom)) CYCLE
    2126              : 
    2127          160 :                   nr = grid_atom%nr
    2128          160 :                   na = grid_atom%ng_sphere
    2129          160 :                   CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
    2130          160 :                   CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
    2131          160 :                   CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
    2132          160 :                   CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
    2133          160 :                   CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
    2134          160 :                   CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
    2135          160 :                   CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
    2136          160 :                   CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
    2137          160 :                   CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
    2138          160 :                   CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
    2139          160 :                   CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
    2140          160 :                   CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
    2141          160 :                   CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    2142              : 
    2143          160 :                   bo = get_limit(natom, para_env%num_pe, para_env%mepos)
    2144          412 :                   DO iat = 1, natom
    2145          252 :                      iatom = atom_list(iat)
    2146          252 :                      source_matrix_local = iat >= bo(1) .AND. iat <= bo(2)
    2147          252 :                      rho_atom => my_rho_atom_set(iatom)
    2148          252 :                      NULLIFY (cpc_h, cpc_s, r_h, r_s, dr_h, dr_s, r_h_d, r_s_d, int_hh, int_ss)
    2149              :                      CALL get_rho_atom(rho_atom=rho_atom, cpc_h=cpc_h, cpc_s=cpc_s, &
    2150              :                                        rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
    2151              :                                        drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d, &
    2152          252 :                                        ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    2153       238104 :                      rho_h = 0.0_dp
    2154       238104 :                      rho_s = 0.0_dp
    2155      1159704 :                      drho_h = 0.0_dp
    2156      1159704 :                      drho_s = 0.0_dp
    2157          252 :                      CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
    2158         7452 :                      DO ir = 1, nr
    2159              :                         CALL calc_rho_angular(grid_atom, harmonics, nspins, .TRUE., &
    2160              :                                               ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
    2161         7452 :                                               r_h_d, r_s_d, drho_h, drho_s)
    2162              :                      END DO
    2163              : 
    2164       238104 :                      vxc_h = 0.0_dp
    2165       238104 :                      vxc_s = 0.0_dp
    2166       929304 :                      vxg_h = 0.0_dp
    2167       929304 :                      vxg_s = 0.0_dp
    2168       238104 :                      vtau_h = 0.0_dp
    2169       238104 :                      vtau_s = 0.0_dp
    2170          252 :                      IF (source_matrix_local) THEN
    2171          126 :                         composite_row = composite_atom_start(iatom) - 1
    2172         3726 :                         DO ir = 1, nr
    2173       118926 :                            DO ia = 1, na
    2174       115200 :                               composite_row = composite_row + 1
    2175       118800 :                               IF (lsd) THEN
    2176            0 :                                  IF (use_atom_composite_density) THEN
    2177            0 :                                     vxc_h(ia, ir, 1:2) = composite_density_grad(composite_row, 1:2)
    2178            0 :                                     vxc_s(ia, ir, 1:2) = composite_density_grad(composite_row, 1:2)
    2179              :                                  END IF
    2180            0 :                                  IF (use_atom_composite_gradient) THEN
    2181            0 :                                     DO idir = 1, 3
    2182              :                                        vxg_h(idir, ia, ir, 1:2) = &
    2183            0 :                                           composite_grad_grad(composite_row, idir, 1:2)
    2184              :                                        vxg_s(idir, ia, ir, 1:2) = &
    2185            0 :                                           composite_grad_grad(composite_row, idir, 1:2)
    2186              :                                     END DO
    2187              :                                  END IF
    2188            0 :                                  IF (use_atom_composite_tau) THEN
    2189            0 :                                     vtau_h(ia, ir, 1:2) = composite_kin_grad(composite_row, 1:2)
    2190            0 :                                     vtau_s(ia, ir, 1:2) = composite_kin_grad(composite_row, 1:2)
    2191              :                                  END IF
    2192              :                               ELSE
    2193       115200 :                                  IF (use_atom_composite_density) THEN
    2194              :                                     vxc_h(ia, ir, 1) = 0.5_dp* &
    2195       345600 :                                                        SUM(composite_density_grad(composite_row, :))
    2196       115200 :                                     vxc_s(ia, ir, 1) = vxc_h(ia, ir, 1)
    2197              :                                  END IF
    2198       115200 :                                  IF (use_atom_composite_gradient) THEN
    2199       460800 :                                     DO idir = 1, 3
    2200              :                                        vxg_h(idir, ia, ir, 1) = 0.5_dp* &
    2201              :                                                                 SUM(composite_grad_grad( &
    2202      1036800 :                                                                     composite_row, idir, :))
    2203       460800 :                                        vxg_s(idir, ia, ir, 1) = vxg_h(idir, ia, ir, 1)
    2204              :                                     END DO
    2205              :                                  END IF
    2206       115200 :                                  IF (use_atom_composite_tau) THEN
    2207              :                                     vtau_h(ia, ir, 1) = 0.5_dp* &
    2208       345600 :                                                         SUM(composite_kin_grad(composite_row, :))
    2209       115200 :                                     vtau_s(ia, ir, 1) = vtau_h(ia, ir, 1)
    2210              :                                  END IF
    2211              :                               END IF
    2212              :                            END DO
    2213              :                         END DO
    2214          126 :                         CPASSERT(composite_row == composite_atom_end(iatom))
    2215              :                      END IF
    2216              : 
    2217              :                      cross_cutoff = gapw_atom_grid_support_radius( &
    2218          252 :                                     grid_atom, rho_h, rho_s, drho_h, drho_s, tau_h, tau_s)
    2219          252 :                      IF (cross_cutoff > 0.0_dp) THEN
    2220          228 :                         image_shell = 0
    2221          912 :                         DO idir = 1, 3
    2222          912 :                            IF (cell%perd(idir) == 1) THEN
    2223              :                               image_shell(idir) = CEILING( &
    2224         2544 :                                                   cross_cutoff*SQRT(SUM(cell%h_inv(idir, :)**2))) + 1
    2225              :                            END IF
    2226              :                         END DO
    2227          456 :                         DO composite_local_atom = 1, composite_local_natom
    2228          228 :                            target_atom = composite_local_atoms(composite_local_atom)
    2229       223908 :                            DO composite_row = composite_atom_start(target_atom), &
    2230          456 :                               composite_atom_end(target_atom)
    2231       223680 :                               cross_density_adjoint = 0.0_dp
    2232       223680 :                               cross_grad_adjoint = 0.0_dp
    2233       223680 :                               cross_kin_adjoint = 0.0_dp
    2234       223680 :                               IF (lsd) THEN
    2235            0 :                                  IF (use_atom_composite_density) THEN
    2236              :                                     cross_density_adjoint(1:2) = &
    2237            0 :                                        composite_density_grad(composite_row, 1:2)
    2238              :                                  END IF
    2239            0 :                                  IF (use_atom_composite_gradient) THEN
    2240              :                                     cross_grad_adjoint(:, 1:2) = &
    2241            0 :                                        composite_grad_grad(composite_row, :, 1:2)
    2242              :                                  END IF
    2243            0 :                                  IF (use_atom_composite_tau) THEN
    2244              :                                     cross_kin_adjoint(1:2) = &
    2245            0 :                                        composite_kin_grad(composite_row, 1:2)
    2246              :                                  END IF
    2247              :                               ELSE
    2248       223680 :                                  IF (use_atom_composite_density) THEN
    2249              :                                     cross_density_adjoint(1) = 0.5_dp* &
    2250       671040 :                                                                SUM(composite_density_grad(composite_row, :))
    2251              :                                  END IF
    2252       223680 :                                  IF (use_atom_composite_gradient) THEN
    2253       894720 :                                     DO idir = 1, 3
    2254              :                                        cross_grad_adjoint(idir, 1) = 0.5_dp* &
    2255      2236800 :                                                                      SUM(composite_grad_grad(composite_row, idir, :))
    2256              :                                     END DO
    2257              :                                  END IF
    2258       223680 :                                  IF (use_atom_composite_tau) THEN
    2259              :                                     cross_kin_adjoint(1) = 0.5_dp* &
    2260       671040 :                                                            SUM(composite_kin_grad(composite_row, :))
    2261              :                                  END IF
    2262              :                               END IF
    2263       223680 :                               fractional = 0.0_dp
    2264       894720 :                               DO idir = 1, 3
    2265      2907840 :                                  DO jdir = 1, 3
    2266              :                                     fractional(idir) = fractional(idir) + cell%h_inv(idir, jdir)* &
    2267              :                                                        (composite_grid_coords(jdir, composite_row) - &
    2268      2684160 :                                                         particle_set(iatom)%r(jdir))
    2269              :                                  END DO
    2270              :                               END DO
    2271       894720 :                               DO idir = 1, 3
    2272       894720 :                                  base_shift(idir) = cell%perd(idir)*NINT(fractional(idir))
    2273              :                               END DO
    2274      1182080 :                               DO image_i3 = base_shift(3) - image_shell(3), &
    2275       223908 :                                  base_shift(3) + image_shell(3)
    2276      5590400 :                                  DO image_i2 = base_shift(2) - image_shell(2), &
    2277      1182080 :                                     base_shift(2) + image_shell(2)
    2278     27632000 :                                     DO image_i1 = base_shift(1) - image_shell(1), &
    2279      5590400 :                                        base_shift(1) + image_shell(1)
    2280     92000000 :                                        image_shift = [image_i1, image_i2, image_i3]
    2281     28786920 :                                        IF (target_atom == iatom .AND. ALL(image_shift == 0)) CYCLE
    2282              :                                        image_translation = MATMUL( &
    2283    366227072 :                                                            cell%hmat, REAL(image_shift, dp))
    2284              :                                        cross_displacement = &
    2285              :                                           composite_grid_coords(:, composite_row) - &
    2286     91556768 :                                           particle_set(iatom)%r - image_translation
    2287              :                                        CALL add_gapw_atom_grid_interpolation_adjoint( &
    2288              :                                           grid_atom, harmonics, cross_displacement, cross_cutoff, &
    2289              :                                           nspins, cross_density_adjoint, cross_grad_adjoint, &
    2290              :                                           cross_kin_adjoint, vxc_h, vxc_s, vxg_h, vxg_s, &
    2291     27521192 :                                           vtau_h, vtau_s)
    2292              :                                     END DO
    2293              :                                  END DO
    2294              :                               END DO
    2295              :                            END DO
    2296              :                         END DO
    2297              :                      END IF
    2298              : 
    2299              :                      ! Model rows are distributed by target atom, while CP2K stores each
    2300              :                      ! one-center matrix on the rank owning its source atom. Sum the exact
    2301              :                      ! interpolation transpose before forming that matrix.
    2302       475956 :                      CALL para_env%sum(vxc_h)
    2303       475956 :                      CALL para_env%sum(vxc_s)
    2304      1858356 :                      CALL para_env%sum(vxg_h)
    2305      1858356 :                      CALL para_env%sum(vxg_s)
    2306       475956 :                      CALL para_env%sum(vtau_h)
    2307       475956 :                      CALL para_env%sum(vtau_s)
    2308          252 :                      IF (.NOT. source_matrix_local) CYCLE
    2309              : 
    2310              :                      one_center_rho_grad_field_contraction = &
    2311              :                         one_center_rho_grad_field_contraction + SUM(vxc_h*(rho_h - rho_s)) + &
    2312       583578 :                         SUM(vxg_h*(drho_h(1:3, :, :, :) - drho_s(1:3, :, :, :)))
    2313              :                      one_center_density_field_contraction = one_center_density_field_contraction + &
    2314       119052 :                                                             SUM(vxc_h*(rho_h - rho_s))
    2315              :                      one_center_gradient_field_contraction = one_center_gradient_field_contraction + &
    2316              :                                                              SUM(vxg_h*(drho_h(1:3, :, :, :) - &
    2317       464652 :                                                                         drho_s(1:3, :, :, :)))
    2318              :                      one_center_tau_field_contraction = one_center_tau_field_contraction + &
    2319       119052 :                                                         SUM(vtau_h*(tau_h - tau_s))
    2320              : 
    2321            0 :                      ALLOCATE (composite_int_h(SIZE(int_hh(1)%r_coef, 1), &
    2322              :                                                SIZE(int_hh(1)%r_coef, 2), nspins), &
    2323            0 :                                composite_int_s(SIZE(int_ss(1)%r_coef, 1), &
    2324         1134 :                                                SIZE(int_ss(1)%r_coef, 2), nspins))
    2325          252 :                      DO ispin = 1, nspins
    2326        29358 :                         composite_int_h(:, :, ispin) = int_hh(ispin)%r_coef
    2327        29358 :                         composite_int_s(:, :, ispin) = int_ss(ispin)%r_coef
    2328        29358 :                         int_hh(ispin)%r_coef = 0.0_dp
    2329        29484 :                         int_ss(ispin)%r_coef = 0.0_dp
    2330              :                      END DO
    2331              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
    2332          126 :                                        grid_atom, basis_1c, harmonics, nspins)
    2333          252 :                      DO ispin = 1, nspins
    2334              :                         one_center_density_matrix_contraction = &
    2335              :                            one_center_density_matrix_contraction + &
    2336              :                            contract_one_center_matrix(cpc_h(ispin)%r_coef, &
    2337              :                                                       int_hh(ispin)%r_coef, &
    2338              :                                                       tau_basis_cache%n2oindex) - &
    2339              :                            contract_one_center_matrix(cpc_s(ispin)%r_coef, &
    2340              :                                                       int_ss(ispin)%r_coef, &
    2341          126 :                                                       tau_basis_cache%n2oindex)
    2342        29358 :                         int_hh(ispin)%r_coef = 0.0_dp
    2343        29484 :                         int_ss(ispin)%r_coef = 0.0_dp
    2344              :                      END DO
    2345              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    2346          126 :                                      grid_atom, basis_1c, harmonics, nspins)
    2347          252 :                      DO ispin = 1, nspins
    2348              :                         one_center_rho_grad_matrix_contraction = &
    2349              :                            one_center_rho_grad_matrix_contraction + &
    2350              :                            contract_one_center_matrix(cpc_h(ispin)%r_coef, &
    2351              :                                                       int_hh(ispin)%r_coef, &
    2352              :                                                       tau_basis_cache%n2oindex) - &
    2353              :                            contract_one_center_matrix(cpc_s(ispin)%r_coef, &
    2354              :                                                       int_ss(ispin)%r_coef, &
    2355          252 :                                                       tau_basis_cache%n2oindex)
    2356              :                      END DO
    2357          126 :                      CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, tau_basis_cache, nspins)
    2358          252 :                      DO ispin = 1, nspins
    2359              :                         one_center_matrix_contraction = one_center_matrix_contraction + &
    2360              :                                                         contract_one_center_matrix(cpc_h(ispin)%r_coef, &
    2361              :                                                                                    int_hh(ispin)%r_coef, &
    2362              :                                                                                    tau_basis_cache%n2oindex) - &
    2363              :                                                         contract_one_center_matrix(cpc_s(ispin)%r_coef, &
    2364              :                                                                                    int_ss(ispin)%r_coef, &
    2365          126 :                                                                                    tau_basis_cache%n2oindex)
    2366          252 :                         IF (.NOT. atom_composite_reference) THEN
    2367            0 :                            int_hh(ispin)%r_coef = composite_int_h(:, :, ispin)
    2368            0 :                            int_ss(ispin)%r_coef = composite_int_s(:, :, ispin)
    2369              :                         END IF
    2370              :                      END DO
    2371          412 :                      DEALLOCATE (composite_int_h, composite_int_s)
    2372              :                   END DO
    2373          452 :                   CALL release_tau_basis_cache(tau_basis_cache)
    2374              :                END DO
    2375              :             END IF
    2376          264 :             CALL para_env%sum(one_center_density_field_contraction)
    2377          264 :             CALL para_env%sum(one_center_density_matrix_contraction)
    2378          264 :             CALL para_env%sum(one_center_gradient_field_contraction)
    2379          264 :             CALL para_env%sum(one_center_matrix_contraction)
    2380          264 :             CALL para_env%sum(one_center_rho_grad_field_contraction)
    2381          264 :             CALL para_env%sum(one_center_rho_grad_matrix_contraction)
    2382          264 :             CALL para_env%sum(one_center_tau_field_contraction)
    2383              :             one_center_field_contraction = one_center_rho_grad_field_contraction + &
    2384          264 :                                            one_center_tau_field_contraction
    2385              :             one_center_gradient_matrix_contraction = one_center_rho_grad_matrix_contraction - &
    2386          264 :                                                      one_center_density_matrix_contraction
    2387              :             one_center_tau_matrix_contraction = one_center_matrix_contraction - &
    2388          264 :                                                 one_center_rho_grad_matrix_contraction
    2389       917312 :             feature_component_analytic(1) = SUM(composite_density_grad*composite_density)
    2390      2751936 :             feature_component_analytic(2) = SUM(composite_grad_grad*composite_grad)
    2391       917312 :             feature_component_analytic(3) = SUM(composite_kin_grad*composite_kin)
    2392         1056 :             feature_component_analytic(4) = SUM(feature_component_analytic(1:3))
    2393          264 :             CALL para_env%sum(feature_component_analytic)
    2394              :             one_center_tensor_contraction = feature_component_analytic(4) - &
    2395          264 :                                             smooth_input_contraction
    2396          264 :             IF (atom_composite_diagnostic) THEN
    2397            0 :                DO icomponent = 1, 4
    2398            0 :                   SELECT CASE (icomponent)
    2399              :                   CASE (1)
    2400            0 :                      composite_density = (1.0_dp + feature_vxc_step)*composite_density
    2401              :                   CASE (2)
    2402            0 :                      composite_grad = (1.0_dp + feature_vxc_step)*composite_grad
    2403              :                   CASE (3)
    2404            0 :                      composite_kin = (1.0_dp + feature_vxc_step)*composite_kin
    2405              :                   CASE (4)
    2406            0 :                      composite_density = (1.0_dp + feature_vxc_step)*composite_density
    2407            0 :                      composite_grad = (1.0_dp + feature_vxc_step)*composite_grad
    2408            0 :                      composite_kin = (1.0_dp + feature_vxc_step)*composite_kin
    2409              :                   END SELECT
    2410              :                   CALL skala_gapw_atom_composite_energy( &
    2411              :                      my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
    2412              :                      composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
    2413            0 :                      composite_local_grid_sizes, composite_local_atom_coords, feature_vxc_plus)
    2414            0 :                   SELECT CASE (icomponent)
    2415              :                   CASE (1)
    2416              :                      composite_density = ((1.0_dp - feature_vxc_step)/ &
    2417            0 :                                           (1.0_dp + feature_vxc_step))*composite_density
    2418              :                   CASE (2)
    2419              :                      composite_grad = ((1.0_dp - feature_vxc_step)/ &
    2420            0 :                                        (1.0_dp + feature_vxc_step))*composite_grad
    2421              :                   CASE (3)
    2422              :                      composite_kin = ((1.0_dp - feature_vxc_step)/ &
    2423            0 :                                       (1.0_dp + feature_vxc_step))*composite_kin
    2424              :                   CASE (4)
    2425              :                      composite_density = ((1.0_dp - feature_vxc_step)/ &
    2426            0 :                                           (1.0_dp + feature_vxc_step))*composite_density
    2427              :                      composite_grad = ((1.0_dp - feature_vxc_step)/ &
    2428            0 :                                        (1.0_dp + feature_vxc_step))*composite_grad
    2429              :                      composite_kin = ((1.0_dp - feature_vxc_step)/ &
    2430            0 :                                       (1.0_dp + feature_vxc_step))*composite_kin
    2431              :                   END SELECT
    2432              :                   CALL skala_gapw_atom_composite_energy( &
    2433              :                      my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
    2434              :                      composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
    2435            0 :                      composite_local_grid_sizes, composite_local_atom_coords, feature_vxc_minus)
    2436            0 :                   SELECT CASE (icomponent)
    2437              :                   CASE (1)
    2438            0 :                      composite_density = composite_density/(1.0_dp - feature_vxc_step)
    2439              :                   CASE (2)
    2440            0 :                      composite_grad = composite_grad/(1.0_dp - feature_vxc_step)
    2441              :                   CASE (3)
    2442            0 :                      composite_kin = composite_kin/(1.0_dp - feature_vxc_step)
    2443              :                   CASE (4)
    2444            0 :                      composite_density = composite_density/(1.0_dp - feature_vxc_step)
    2445            0 :                      composite_grad = composite_grad/(1.0_dp - feature_vxc_step)
    2446            0 :                      composite_kin = composite_kin/(1.0_dp - feature_vxc_step)
    2447              :                   END SELECT
    2448              :                   feature_component_fd(icomponent) = &
    2449            0 :                      (feature_vxc_plus - feature_vxc_minus)/(2.0_dp*feature_vxc_step)
    2450              :                END DO
    2451            0 :                feature_vxc_analytic = feature_component_analytic(4)
    2452            0 :                feature_vxc_fd = feature_component_fd(4)
    2453            0 :                iw = cp_logger_get_default_io_unit()
    2454            0 :                IF (iw > 0) THEN
    2455              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,I0)") &
    2456            0 :                      "SKALA_GPW| Atom-composite reference components", atom_composite_components
    2457              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    2458            0 :                      "SKALA_GPW| Atom-composite reference electrons", atom_composite_nelec
    2459              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    2460            0 :                      "SKALA_GPW| Atom-composite reference XC energy", atom_composite_exc
    2461              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    2462            0 :                      "SKALA_GPW| Atom-composite feature VXC contraction", feature_vxc_analytic
    2463              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    2464            0 :                      "SKALA_GPW| Atom-composite feature finite difference", feature_vxc_fd
    2465              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    2466            0 :                      "SKALA_GPW| Atom-composite feature VXC error", &
    2467            0 :                      feature_vxc_analytic - feature_vxc_fd
    2468              :                   WRITE (UNIT=iw, FMT="(T2,A,3(1X,ES24.16))") &
    2469            0 :                      "SKALA_GPW| Atom-composite smooth PW adjoint", smooth_input_contraction, &
    2470            0 :                      smooth_grid_contraction, smooth_grid_contraction - smooth_input_contraction
    2471              :                   WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES24.16))") &
    2472            0 :                      "SKALA_GPW| Atom-composite one-center adjoint", one_center_tensor_contraction, &
    2473            0 :                      one_center_field_contraction, one_center_matrix_contraction, &
    2474            0 :                      one_center_matrix_contraction - one_center_tensor_contraction
    2475              :                   WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES24.16))") &
    2476            0 :                      "SKALA_GPW| Atom-composite one-center channels", &
    2477            0 :                      one_center_rho_grad_field_contraction, one_center_rho_grad_matrix_contraction, &
    2478            0 :                      one_center_tau_field_contraction, one_center_tau_matrix_contraction
    2479              :                   WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES24.16))") &
    2480            0 :                      "SKALA_GPW| Atom-composite one-center rho-gradient", &
    2481            0 :                      one_center_density_field_contraction, one_center_density_matrix_contraction, &
    2482            0 :                      one_center_gradient_field_contraction, one_center_gradient_matrix_contraction
    2483            0 :                   DO icomponent = 1, 3
    2484              :                      WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES24.16))") &
    2485            0 :                         "SKALA_GPW| Atom-composite component VXC", icomponent, &
    2486            0 :                         feature_component_analytic(icomponent), feature_component_fd(icomponent), &
    2487            0 :                         feature_component_analytic(icomponent) - feature_component_fd(icomponent)
    2488              :                   END DO
    2489              :                END IF
    2490              :             END IF
    2491          264 :             IF (atom_composite_reference) THEN
    2492          264 :                exc1 = atom_composite_exc
    2493          264 :                IF (native_grid_diagnostics) THEN
    2494           30 :                   IF (composite_nflat > 0) THEN
    2495       119540 :                      composite_density_min = MINVAL(composite_density)
    2496       119540 :                      composite_density_max = MAXVAL(composite_density)
    2497       119540 :                      composite_kin_min = MINVAL(composite_kin)
    2498       119540 :                      composite_kin_max = MAXVAL(composite_kin)
    2499       358620 :                      composite_grad_max = MAXVAL(ABS(composite_grad))
    2500              :                   ELSE
    2501           10 :                      composite_density_min = HUGE(1.0_dp)
    2502           10 :                      composite_density_max = -HUGE(1.0_dp)
    2503           10 :                      composite_kin_min = HUGE(1.0_dp)
    2504           10 :                      composite_kin_max = -HUGE(1.0_dp)
    2505           10 :                      composite_grad_max = 0.0_dp
    2506              :                   END IF
    2507              :                   composite_tau_integral = &
    2508       179250 :                      SUM(composite_grid_weights*SUM(composite_kin, DIM=2))
    2509           30 :                   CALL para_env%min(composite_density_min)
    2510           30 :                   CALL para_env%max(composite_density_max)
    2511           30 :                   CALL para_env%min(composite_kin_min)
    2512           30 :                   CALL para_env%max(composite_kin_max)
    2513           30 :                   CALL para_env%max(composite_grad_max)
    2514           30 :                   CALL para_env%sum(composite_tau_integral)
    2515              :                END IF
    2516          264 :                iw = cp_logger_get_default_io_unit()
    2517          264 :                IF (iw > 0) THEN
    2518              :                   WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    2519          132 :                      "SKALA_GPW| Active atom-composite XC energy", atom_composite_exc
    2520          132 :                   IF (native_grid_diagnostics) THEN
    2521              :                      WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    2522           15 :                         "SKALA_GPW| Active atom-composite electrons", atom_composite_nelec
    2523              :                      WRITE (UNIT=iw, FMT="(T2,A,2(1X,ES24.16))") &
    2524           15 :                         "SKALA_GPW| Active atom-composite density range", &
    2525           30 :                         composite_density_min, composite_density_max
    2526              :                      WRITE (UNIT=iw, FMT="(T2,A,2(1X,ES24.16))") &
    2527           15 :                         "SKALA_GPW| Active atom-composite tau range", &
    2528           30 :                         composite_kin_min, composite_kin_max
    2529              :                      WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    2530           15 :                         "SKALA_GPW| Active atom-composite tau integral", &
    2531           30 :                         composite_tau_integral
    2532              :                      WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
    2533           15 :                         "SKALA_GPW| Active atom-composite max gradient", &
    2534           30 :                         composite_grad_max
    2535              :                   END IF
    2536              :                END IF
    2537              :             END IF
    2538          264 :             CALL xc_rho_set_release(smooth_rho_set, pw_pool=auxbas_pw_pool)
    2539            0 :             DEALLOCATE (composite_atomic_grid_sizes, composite_atom_kind, &
    2540            0 :                         composite_atom_kind_index, composite_atom_start, composite_atom_end, &
    2541            0 :                         composite_atom_coords, composite_local_atoms, composite_local_grid_sizes, &
    2542            0 :                         composite_local_atom_coords, composite_grid_atom, &
    2543            0 :                         composite_partition_weights, composite_partition_atom_coords, &
    2544            0 :                         composite_distances, composite_density, composite_grad, composite_kin, &
    2545            0 :                         composite_smooth_density_cache, composite_smooth_gradient_cache, &
    2546            0 :                         composite_smooth_kin_cache, &
    2547            0 :                         composite_density_grad, composite_grad_grad, composite_kin_grad, &
    2548            0 :                         composite_grid_coords, composite_grid_weights, &
    2549          264 :                         composite_base_grid_weights, composite_atomic_grid_weights)
    2550          264 :             IF (lsd) THEN
    2551            0 :                DEALLOCATE (composite_smooth_rhoa, composite_smooth_rhob, &
    2552           42 :                            composite_smooth_tau_a, composite_smooth_tau_b)
    2553          168 :                DO idir = 1, 3
    2554            0 :                   DEALLOCATE (composite_smooth_drhoa(idir)%array, &
    2555          168 :                               composite_smooth_drhob(idir)%array)
    2556              :                END DO
    2557              :             ELSE
    2558          222 :                DEALLOCATE (composite_smooth_rho, composite_smooth_tau)
    2559          888 :                DO idir = 1, 3
    2560          888 :                   DEALLOCATE (composite_smooth_drho(idir)%array)
    2561              :                END DO
    2562              :             END IF
    2563              :          END IF
    2564              : 
    2565        28630 :          IF (.NOT. atom_composite_reference) CALL para_env%sum(exc1)
    2566              : 
    2567        28630 :          IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
    2568        28630 :          IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
    2569        28630 :          IF (ASSOCIATED(vxc_h)) DEALLOCATE (vxc_h)
    2570        28630 :          IF (ASSOCIATED(vxc_s)) DEALLOCATE (vxc_s)
    2571              : 
    2572        28630 :          IF (gradient_f) THEN
    2573        19776 :             IF (ASSOCIATED(drho_h)) DEALLOCATE (drho_h)
    2574        19776 :             IF (ASSOCIATED(drho_s)) DEALLOCATE (drho_s)
    2575        19776 :             IF (ASSOCIATED(vxg_h)) DEALLOCATE (vxg_h)
    2576        19776 :             IF (ASSOCIATED(vxg_s)) DEALLOCATE (vxg_s)
    2577              :          END IF
    2578              : 
    2579        28630 :          IF (tau_f) THEN
    2580          926 :             IF (ASSOCIATED(tau_h)) DEALLOCATE (tau_h)
    2581          926 :             IF (ASSOCIATED(tau_s)) DEALLOCATE (tau_s)
    2582          926 :             IF (ASSOCIATED(vtau_h)) DEALLOCATE (vtau_h)
    2583          926 :             IF (ASSOCIATED(vtau_s)) DEALLOCATE (vtau_s)
    2584              :          END IF
    2585              : 
    2586              :       END IF !xc_none
    2587              : 
    2588        32842 :       CALL timestop(handle)
    2589              : 
    2590      5747350 :    END SUBROUTINE calculate_vxc_atom
    2591              : 
    2592              : ! **************************************************************************************************
    2593              : !> \brief Add the GAPW one-center correction to CDFT values and operators.
    2594              : !> \param qs_env Quickstep environment
    2595              : !> \param energy_only skip construction of the CDFT one-center operator
    2596              : !> \param calculate_forces evaluate explicit derivatives of the partition weights
    2597              : !> \param values constraint values from the hard-minus-soft one-center densities
    2598              : !> \param electronic_charge optional one-center corrections to atomic populations
    2599              : !> \param operator_group optional group for which to build the unscaled weight operator
    2600              : !> \param rho_atom_operator_set optional destination for the one-center operator integrals
    2601              : ! **************************************************************************************************
    2602          440 :    SUBROUTINE gapw_cdft_one_center(qs_env, energy_only, calculate_forces, values, &
    2603          440 :                                    electronic_charge, operator_group, rho_atom_operator_set)
    2604              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2605              :       LOGICAL, INTENT(IN)                                :: energy_only, calculate_forces
    2606              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: values
    2607              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT), &
    2608              :          OPTIONAL                                        :: electronic_charge
    2609              :       INTEGER, INTENT(IN), OPTIONAL                      :: operator_group
    2610              :       TYPE(rho_atom_type), DIMENSION(:), POINTER, &
    2611              :          OPTIONAL                                        :: rho_atom_operator_set
    2612              : 
    2613              :       INTEGER                                            :: atom, channel, ia, iat, igroup, ikind, &
    2614              :                                                             ir, natom, natom_kind, nspins
    2615              :       INTEGER, DIMENSION(2)                              :: atom_bounds
    2616          440 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
    2617              :       LOGICAL                                            :: lsd, paw_atom
    2618              :       REAL(KIND=dp)                                      :: delta_density, point_factor, spin_factor
    2619          440 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: atomic_weights, group_weights
    2620          440 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: explicit_derivative, &
    2621          440 :                                                             group_point_derivative
    2622          440 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: group_atom_derivative
    2623              :       REAL(KIND=dp), DIMENSION(3)                        :: point
    2624          440 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: rho_h, rho_s
    2625          440 :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: drho_h, drho_s
    2626          440 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: vlocal_h, vlocal_s
    2627          440 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2628              :       TYPE(cdft_control_type), POINTER                   :: cdft_control
    2629          440 :       TYPE(cdft_point_context_type)                      :: context
    2630              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2631              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    2632              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    2633              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    2634              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2635          440 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2636          440 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    2637          440 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    2638          440 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
    2639          440 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    2640          440 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: operator_atom_set, rho_atom_set
    2641              :       TYPE(rho_atom_type), POINTER                       :: operator_atom, rho_atom
    2642              : 
    2643          440 :       NULLIFY (atom_list, atomic_kind_set, basis_1c, cdft_control, dft_control, force, &
    2644          440 :                grid_atom, harmonics, int_hh, int_ss, para_env, particle_set, r_h, r_s, &
    2645          440 :                dr_h, dr_s, r_h_d, r_s_d, rho_h, rho_s, drho_h, drho_s, &
    2646          440 :                operator_atom, operator_atom_set, rho_atom, rho_atom_set, qs_kind_set, &
    2647          440 :                vlocal_h, vlocal_s)
    2648              :       CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, dft_control=dft_control, &
    2649              :                       force=force, natom=natom, para_env=para_env, particle_set=particle_set, &
    2650          440 :                       qs_kind_set=qs_kind_set, rho_atom_set=rho_atom_set)
    2651          440 :       CPASSERT(ASSOCIATED(atomic_kind_set))
    2652          440 :       CPASSERT(ASSOCIATED(dft_control))
    2653          440 :       CPASSERT(ASSOCIATED(para_env))
    2654          440 :       CPASSERT(ASSOCIATED(particle_set))
    2655          440 :       CPASSERT(ASSOCIATED(qs_kind_set))
    2656          440 :       CPASSERT(ASSOCIATED(rho_atom_set))
    2657          440 :       operator_atom_set => rho_atom_set
    2658          440 :       IF (PRESENT(rho_atom_operator_set)) operator_atom_set => rho_atom_operator_set
    2659          440 :       CPASSERT(ASSOCIATED(operator_atom_set))
    2660          440 :       cdft_control => dft_control%qs_control%cdft_control
    2661          440 :       CPASSERT(ASSOCIATED(cdft_control))
    2662          440 :       nspins = dft_control%nspins
    2663          440 :       lsd = dft_control%lsd
    2664          440 :       CPASSERT(SIZE(values) == SIZE(cdft_control%group))
    2665          440 :       IF (PRESENT(operator_group)) THEN
    2666            4 :          CPASSERT(operator_group >= 1 .AND. operator_group <= SIZE(cdft_control%group))
    2667              :       END IF
    2668          440 :       IF (PRESENT(electronic_charge)) THEN
    2669           76 :          CPASSERT(SIZE(electronic_charge, 1) == natom)
    2670           76 :          CPASSERT(SIZE(electronic_charge, 2) == nspins)
    2671              :       END IF
    2672              : 
    2673          440 :       CALL cdft_point_context_create(qs_env, context, calculate_forces)
    2674              :       ALLOCATE (group_weights(context%ngroup), group_point_derivative(3, context%ngroup), &
    2675              :                 group_atom_derivative(3, natom, context%ngroup), &
    2676         4400 :                 explicit_derivative(3, natom))
    2677          592 :       IF (PRESENT(electronic_charge)) ALLOCATE (atomic_weights(natom))
    2678          952 :       values = 0.0_dp
    2679          440 :       explicit_derivative = 0.0_dp
    2680          988 :       IF (PRESENT(electronic_charge)) electronic_charge = 0.0_dp
    2681              : 
    2682         1036 :       DO ikind = 1, SIZE(atomic_kind_set)
    2683          596 :          CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom_kind)
    2684              :          CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom, grid_atom=grid_atom, &
    2685          596 :                           harmonics=harmonics)
    2686          596 :          IF (.NOT. paw_atom) CYCLE
    2687          596 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    2688          596 :          CPASSERT(ASSOCIATED(grid_atom))
    2689          596 :          CPASSERT(ASSOCIATED(harmonics))
    2690          596 :          CPASSERT(ASSOCIATED(basis_1c))
    2691              :          ALLOCATE (vlocal_h(grid_atom%ng_sphere, grid_atom%nr, nspins), &
    2692         5364 :                    vlocal_s(grid_atom%ng_sphere, grid_atom%nr, nspins))
    2693              : 
    2694          596 :          atom_bounds = get_limit(natom_kind, para_env%num_pe, para_env%mepos)
    2695         1099 :          DO iat = atom_bounds(1), atom_bounds(2)
    2696          503 :             atom = atom_list(iat)
    2697          503 :             rho_atom => rho_atom_set(atom)
    2698          503 :             NULLIFY (r_h, r_s)
    2699          503 :             CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    2700          503 :             CALL reallocate(rho_h, 1, grid_atom%ng_sphere, 1, grid_atom%nr, 1, nspins)
    2701          503 :             CALL reallocate(rho_s, 1, grid_atom%ng_sphere, 1, grid_atom%nr, 1, nspins)
    2702      1730081 :             rho_h = 0.0_dp
    2703      1730081 :             rho_s = 0.0_dp
    2704        25653 :             DO ir = 1, grid_atom%nr
    2705              :                CALL calc_rho_angular(grid_atom, harmonics, nspins, .FALSE., ir, r_h, r_s, &
    2706        25653 :                                      rho_h, rho_s, dr_h, dr_s, r_h_d, r_s_d, drho_h, drho_s)
    2707              :             END DO
    2708      1730081 :             vlocal_h = 0.0_dp
    2709      1730081 :             vlocal_s = 0.0_dp
    2710              : 
    2711        25653 :             DO ir = 1, grid_atom%nr
    2712      1283153 :                DO ia = 1, grid_atom%ng_sphere
    2713              :                   point(1) = particle_set(atom)%r(1) + grid_atom%rad(ir)* &
    2714      1257500 :                              grid_atom%sin_pol(ia)*grid_atom%cos_azi(ia)
    2715              :                   point(2) = particle_set(atom)%r(2) + grid_atom%rad(ir)* &
    2716      1257500 :                              grid_atom%sin_pol(ia)*grid_atom%sin_azi(ia)
    2717      1257500 :                   point(3) = particle_set(atom)%r(3) + grid_atom%rad(ir)*grid_atom%cos_pol(ia)
    2718      1257500 :                   IF (PRESENT(electronic_charge)) THEN
    2719              :                      CALL cdft_point_weights(context, point, group_weights, &
    2720              :                                              group_point_derivative, group_atom_derivative, &
    2721       247500 :                                              atomic_weights)
    2722              :                   ELSE
    2723              :                      CALL cdft_point_weights(context, point, group_weights, &
    2724      1010000 :                                              group_point_derivative, group_atom_derivative)
    2725              :                   END IF
    2726      2977650 :                   DO channel = 1, nspins
    2727      1695000 :                      delta_density = rho_h(ia, ir, channel) - rho_s(ia, ir, channel)
    2728      1695000 :                      IF (PRESENT(electronic_charge)) THEN
    2729              :                         electronic_charge(:, channel) = electronic_charge(:, channel) + &
    2730              :                                                         grid_atom%weight(ia, ir)*atomic_weights* &
    2731      1830000 :                                                         delta_density
    2732              :                      END IF
    2733      1695000 :                      point_factor = 0.0_dp
    2734      3750000 :                      DO igroup = 1, context%ngroup
    2735              :                         spin_factor = cdft_spin_factor( &
    2736      2055000 :                                       cdft_control%group(igroup)%constraint_type, channel, lsd)
    2737      2055000 :                         IF (PRESENT(operator_group)) THEN
    2738        10000 :                            IF (igroup == operator_group) THEN
    2739        10000 :                               point_factor = point_factor + group_weights(igroup)
    2740              :                            END IF
    2741              :                         ELSE
    2742              :                            point_factor = point_factor + cdft_control%strength(igroup)* &
    2743      2045000 :                                           group_weights(igroup)*spin_factor
    2744              :                         END IF
    2745              :                         values(igroup) = values(igroup) + grid_atom%weight(ia, ir)* &
    2746      2055000 :                                          group_weights(igroup)*delta_density*spin_factor
    2747      3750000 :                         IF (calculate_forces) THEN
    2748              :                            explicit_derivative(:, :) = &
    2749              :                               explicit_derivative + grid_atom%weight(ia, ir)* &
    2750              :                               cdft_control%strength(igroup)*delta_density* &
    2751       367500 :                               spin_factor*group_atom_derivative(:, :, igroup)
    2752              :                            explicit_derivative(:, atom) = explicit_derivative(:, atom) + &
    2753              :                                                           grid_atom%weight(ia, ir)* &
    2754              :                                                           cdft_control%strength(igroup)*delta_density* &
    2755       150000 :                                                           spin_factor*group_point_derivative(:, igroup)
    2756              :                         END IF
    2757              :                      END DO
    2758      1695000 :                      vlocal_h(ia, ir, channel) = grid_atom%weight(ia, ir)*point_factor
    2759      2952500 :                      vlocal_s(ia, ir, channel) = vlocal_h(ia, ir, channel)
    2760              :                   END DO
    2761              :                END DO
    2762              :             END DO
    2763              : 
    2764         1099 :             IF (.NOT. energy_only) THEN
    2765          372 :                NULLIFY (int_hh, int_ss)
    2766          372 :                operator_atom => operator_atom_set(atom)
    2767          372 :                CALL get_rho_atom(rho_atom=operator_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    2768              :                CALL gaVxcgb_noGC(vlocal_h, vlocal_s, int_hh, int_ss, grid_atom, &
    2769          372 :                                  basis_1c, harmonics, nspins)
    2770              :             END IF
    2771              :          END DO
    2772         1632 :          DEALLOCATE (vlocal_h, vlocal_s)
    2773              :       END DO
    2774              : 
    2775         1464 :       CALL para_env%sum(values)
    2776          440 :       CALL para_env%sum(explicit_derivative)
    2777         1536 :       IF (PRESENT(electronic_charge)) CALL para_env%sum(electronic_charge)
    2778          440 :       IF (calculate_forces .AND. ASSOCIATED(force) .AND. para_env%is_source()) THEN
    2779            9 :          DO ikind = 1, SIZE(atomic_kind_set)
    2780            5 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom_kind)
    2781           18 :             DO iat = 1, natom_kind
    2782            9 :                atom = atom_list(iat)
    2783              :                force(ikind)%rho_elec(:, iat) = force(ikind)%rho_elec(:, iat) + &
    2784           41 :                                                explicit_derivative(:, atom)
    2785              :             END DO
    2786              :          END DO
    2787              :       END IF
    2788              : 
    2789          440 :       IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
    2790          440 :       IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
    2791          440 :       IF (ALLOCATED(atomic_weights)) DEALLOCATE (atomic_weights)
    2792          440 :       DEALLOCATE (explicit_derivative, group_atom_derivative, group_point_derivative, group_weights)
    2793          880 :       CALL cdft_point_context_release(context)
    2794              : 
    2795              :    CONTAINS
    2796              : 
    2797              : ! **************************************************************************************************
    2798              : !> \brief ...
    2799              : !> \param constraint_type ...
    2800              : !> \param channel ...
    2801              : !> \param lsd ...
    2802              : !> \return ...
    2803              : ! **************************************************************************************************
    2804      2055000 :       FUNCTION cdft_spin_factor(constraint_type, channel, lsd) RESULT(factor)
    2805              :       INTEGER, INTENT(IN)                                :: constraint_type, channel
    2806              :       LOGICAL, INTENT(IN)                                :: lsd
    2807              :       REAL(KIND=dp)                                      :: factor
    2808              : 
    2809      2055000 :          SELECT CASE (constraint_type)
    2810              :          CASE (cdft_charge_constraint)
    2811            0 :             factor = 1.0_dp
    2812              :          CASE (cdft_magnetization_constraint)
    2813            0 :             CPASSERT(lsd)
    2814            0 :             factor = MERGE(1.0_dp, -1.0_dp, channel == 1)
    2815              :          CASE (cdft_alpha_constraint)
    2816       360000 :             CPASSERT(lsd)
    2817       360000 :             factor = MERGE(1.0_dp, 0.0_dp, channel == 1)
    2818              :          CASE (cdft_beta_constraint)
    2819       360000 :             CPASSERT(lsd)
    2820       360000 :             factor = MERGE(1.0_dp, 0.0_dp, channel == 2)
    2821              :          CASE DEFAULT
    2822      2055000 :             CPABORT("Unknown CDFT constraint type.")
    2823              :          END SELECT
    2824      2055000 :       END FUNCTION cdft_spin_factor
    2825              : 
    2826              :    END SUBROUTINE gapw_cdft_one_center
    2827              : 
    2828              : ! **************************************************************************************************
    2829              : !> \brief Contract a compact one-center density matrix with an integral in the padded old basis.
    2830              : !> \param density_matrix ...
    2831              : !> \param integral_matrix ...
    2832              : !> \param new_to_old ...
    2833              : !> \return ...
    2834              : ! **************************************************************************************************
    2835          756 :    FUNCTION contract_one_center_matrix(density_matrix, integral_matrix, new_to_old) RESULT(value)
    2836              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: density_matrix, integral_matrix
    2837              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: new_to_old
    2838              :       REAL(KIND=dp)                                      :: value
    2839              : 
    2840              :       INTEGER                                            :: ibas, jbas, nbas
    2841              : 
    2842          756 :       nbas = SIZE(density_matrix, 1)
    2843          756 :       CPASSERT(SIZE(density_matrix, 2) == nbas)
    2844          756 :       CPASSERT(SIZE(new_to_old) >= nbas)
    2845         5988 :       CPASSERT(MINVAL(new_to_old(1:nbas)) >= 1)
    2846         5988 :       CPASSERT(MAXVAL(new_to_old(1:nbas)) <= SIZE(integral_matrix, 1))
    2847         5988 :       CPASSERT(MAXVAL(new_to_old(1:nbas)) <= SIZE(integral_matrix, 2))
    2848              : 
    2849          756 :       value = 0.0_dp
    2850         5988 :       DO jbas = 1, nbas
    2851        73356 :          DO ibas = 1, nbas
    2852              :             value = value + density_matrix(ibas, jbas)* &
    2853        72600 :                     integral_matrix(new_to_old(ibas), new_to_old(jbas))
    2854              :          END DO
    2855              :       END DO
    2856              : 
    2857          756 :    END FUNCTION contract_one_center_matrix
    2858              : 
    2859              : ! **************************************************************************************************
    2860              : !> \brief Replicate a distributed real-space field for atom-grid interpolation.
    2861              : !> \param local_values ...
    2862              : !> \param pw_grid ...
    2863              : !> \param group ...
    2864              : !> \param global_values ...
    2865              : ! **************************************************************************************************
    2866         1530 :    SUBROUTINE gather_native_grid_field(local_values, pw_grid, group, global_values)
    2867              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN), &
    2868              :          POINTER                                         :: local_values
    2869              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    2870              :       TYPE(mp_para_env_type), INTENT(IN)                 :: group
    2871              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(OUT), &
    2872              :          POINTER                                         :: global_values
    2873              : 
    2874              :       INTEGER, DIMENSION(2, 3)                           :: bo
    2875              : 
    2876         1530 :       CPASSERT(ASSOCIATED(local_values))
    2877         1530 :       CPASSERT(ASSOCIATED(pw_grid))
    2878         1530 :       CPASSERT(.NOT. ASSOCIATED(global_values))
    2879        15300 :       bo = pw_grid%bounds_local
    2880              :       ALLOCATE (global_values(pw_grid%bounds(1, 1):pw_grid%bounds(2, 1), &
    2881              :                               pw_grid%bounds(1, 2):pw_grid%bounds(2, 2), &
    2882         7650 :                               pw_grid%bounds(1, 3):pw_grid%bounds(2, 3)))
    2883     12411000 :       global_values = 0.0_dp
    2884              :       global_values(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)) = &
    2885     12986670 :          local_values
    2886     24820470 :       CALL group%sum(global_values)
    2887              : 
    2888         1530 :    END SUBROUTINE gather_native_grid_field
    2889              : 
    2890              : ! **************************************************************************************************
    2891              : !> \brief Build the tensor-product interpolation stencil for one Cartesian point.
    2892              : !> \param stencil ...
    2893              : !> \param pw_grid ...
    2894              : !> \param cell ...
    2895              : !> \param point ...
    2896              : !> \param wrap_auxiliary_cell wrap all auxiliary-grid directions
    2897              : !> \param indices_only skip interpolation weights when only grid indices are needed
    2898              : ! **************************************************************************************************
    2899    162224040 :    SUBROUTINE create_native_grid_interpolation_stencil(stencil, pw_grid, cell, point, &
    2900              :                                                        wrap_auxiliary_cell, indices_only)
    2901              :       TYPE(native_grid_interpolation_stencil_type), &
    2902              :          INTENT(OUT)                                     :: stencil
    2903              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    2904              :       TYPE(cell_type), INTENT(IN), POINTER               :: cell
    2905              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: point
    2906              :       LOGICAL, INTENT(IN), OPTIONAL                      :: wrap_auxiliary_cell, indices_only
    2907              : 
    2908              :       INTEGER                                            :: idir, inode, relative_index
    2909              :       INTEGER, DIMENSION(3)                              :: base
    2910              :       LOGICAL                                            :: build_weights, wrap_grid
    2911              :       REAL(KIND=dp), DIMENSION(3)                        :: fraction, relative
    2912              : 
    2913      1374780 :       CPASSERT(ASSOCIATED(pw_grid))
    2914      1374780 :       CPASSERT(ASSOCIATED(cell))
    2915      1374780 :       stencil%active = .FALSE.
    2916     54991200 :       stencil%valid = .FALSE.
    2917     54991200 :       stencil%weight = 0.0_dp
    2918      1374780 :       build_weights = .TRUE.
    2919      1374780 :       IF (PRESENT(indices_only)) build_weights = .NOT. indices_only
    2920      5229120 :       wrap_grid = ANY(cell%perd == 0)
    2921      1374780 :       IF (PRESENT(wrap_auxiliary_cell)) wrap_grid = wrap_auxiliary_cell
    2922     17872140 :       relative = MATMUL(pw_grid%dh_inv, point)
    2923      5499120 :       DO idir = 1, 3
    2924      4124340 :          IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
    2925      4124340 :             relative(idir) = MODULO(relative(idir), REAL(pw_grid%npts(idir), KIND=dp))
    2926            0 :          ELSE IF (relative(idir) <= -REAL(native_grid_interp_offset_max, dp) .OR. &
    2927              :                   relative(idir) >= REAL(pw_grid%npts(idir) - &
    2928              :                                          native_grid_interp_offset_min, KIND=dp)) THEN
    2929            0 :             RETURN
    2930              :          END IF
    2931      4124340 :          base(idir) = FLOOR(relative(idir))
    2932      4124340 :          FRACTION(idir) = relative(idir) - REAL(base(idir), KIND=dp)
    2933      4124340 :          IF (build_weights) THEN
    2934      2749560 :             CALL native_grid_lagrange_weights(FRACTION(idir), stencil%weight(:, idir))
    2935              :          END IF
    2936     54991200 :          DO inode = 1, native_grid_interp_npts
    2937     49492080 :             relative_index = base(idir) + native_grid_interp_offset_min + inode - 1
    2938     49492080 :             IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
    2939     49492080 :                relative_index = MODULO(relative_index, pw_grid%npts(idir))
    2940     49492080 :                stencil%valid(inode, idir) = .TRUE.
    2941            0 :             ELSE IF (relative_index >= 0 .AND. relative_index < pw_grid%npts(idir)) THEN
    2942            0 :                stencil%valid(inode, idir) = .TRUE.
    2943              :             END IF
    2944     53616420 :             stencil%relative_index(inode, idir) = relative_index
    2945              :          END DO
    2946              :       END DO
    2947      1374780 :       stencil%active = .TRUE.
    2948              : 
    2949              :    END SUBROUTINE create_native_grid_interpolation_stencil
    2950              : 
    2951              : ! **************************************************************************************************
    2952              : !> \brief Interpolate density, gradient, and kinetic-density fields in one stencil traversal.
    2953              : !> \param density ...
    2954              : !> \param grad_x ...
    2955              : !> \param grad_y ...
    2956              : !> \param grad_z ...
    2957              : !> \param kin ...
    2958              : !> \param stencil ...
    2959              : !> \param density_value ...
    2960              : !> \param grad_value ...
    2961              : !> \param kin_value ...
    2962              : ! **************************************************************************************************
    2963       563260 :    SUBROUTINE interpolate_native_grid_fields(density, grad_x, grad_y, grad_z, kin, stencil, &
    2964              :                                              density_value, grad_value, kin_value)
    2965              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: density, grad_x, grad_y, grad_z, kin
    2966              :       TYPE(native_grid_interpolation_stencil_type), &
    2967              :          INTENT(IN)                                      :: stencil
    2968              :       REAL(KIND=dp), INTENT(OUT)                         :: density_value
    2969              :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT)           :: grad_value
    2970              :       REAL(KIND=dp), INTENT(OUT)                         :: kin_value
    2971              : 
    2972              :       INTEGER                                            :: inode_x, inode_y, inode_z
    2973              :       INTEGER, DIMENSION(3)                              :: index, lower_bound
    2974              :       REAL(KIND=dp)                                      :: coefficient
    2975              : 
    2976      2253040 :       CPASSERT(ALL(SHAPE(grad_x) == SHAPE(density)))
    2977      2253040 :       CPASSERT(ALL(SHAPE(grad_y) == SHAPE(density)))
    2978      2253040 :       CPASSERT(ALL(SHAPE(grad_z) == SHAPE(density)))
    2979      2253040 :       CPASSERT(ALL(SHAPE(kin) == SHAPE(density)))
    2980       563260 :       density_value = 0.0_dp
    2981       563260 :       grad_value = 0.0_dp
    2982       563260 :       kin_value = 0.0_dp
    2983       563260 :       IF (.NOT. stencil%active) RETURN
    2984              :       lower_bound = LBOUND(density)
    2985      7322380 :       DO inode_z = 1, native_grid_interp_npts
    2986      6759120 :          IF (.NOT. stencil%valid(inode_z, 3)) CYCLE
    2987      6759120 :          INDEX(3) = lower_bound(3) + stencil%relative_index(inode_z, 3)
    2988     88431820 :          DO inode_y = 1, native_grid_interp_npts
    2989     81109440 :             IF (.NOT. stencil%valid(inode_y, 2)) CYCLE
    2990     81109440 :             INDEX(2) = lower_bound(2) + stencil%relative_index(inode_y, 2)
    2991   1061181840 :             DO inode_x = 1, native_grid_interp_npts
    2992    973313280 :                IF (.NOT. stencil%valid(inode_x, 1)) CYCLE
    2993    973313280 :                INDEX(1) = lower_bound(1) + stencil%relative_index(inode_x, 1)
    2994              :                coefficient = stencil%weight(inode_x, 1)* &
    2995              :                              stencil%weight(inode_y, 2)* &
    2996    973313280 :                              stencil%weight(inode_z, 3)
    2997    973313280 :                density_value = density_value + coefficient*density(INDEX(1), INDEX(2), INDEX(3))
    2998    973313280 :                grad_value(1) = grad_value(1) + coefficient*grad_x(INDEX(1), INDEX(2), INDEX(3))
    2999    973313280 :                grad_value(2) = grad_value(2) + coefficient*grad_y(INDEX(1), INDEX(2), INDEX(3))
    3000    973313280 :                grad_value(3) = grad_value(3) + coefficient*grad_z(INDEX(1), INDEX(2), INDEX(3))
    3001   1054422720 :                kin_value = kin_value + coefficient*kin(INDEX(1), INDEX(2), INDEX(3))
    3002              :             END DO
    3003              :          END DO
    3004              :       END DO
    3005              : 
    3006              :    END SUBROUTINE interpolate_native_grid_fields
    3007              : 
    3008              : ! **************************************************************************************************
    3009              : !> \brief Group atom-grid rows by the disjoint PW tiles touched by their interpolation stencils.
    3010              : !> \param pw_grid ...
    3011              : !> \param cell ...
    3012              : !> \param points atom-grid coordinates
    3013              : !> \param wrap_auxiliary_cell wrap all auxiliary-grid directions
    3014              : !> \param tile_count number of tiles along each PW-grid direction
    3015              : !> \param bin_offsets CSR offsets into bin_rows
    3016              : !> \param bin_rows atom-grid rows touching each tile
    3017              : ! **************************************************************************************************
    3018          264 :    SUBROUTINE build_native_grid_adjoint_bins(pw_grid, cell, points, wrap_auxiliary_cell, &
    3019              :                                              tile_count, bin_offsets, bin_rows)
    3020              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    3021              :       TYPE(cell_type), INTENT(IN), POINTER               :: cell
    3022              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: points
    3023              :       LOGICAL, INTENT(IN)                                :: wrap_auxiliary_cell
    3024              :       INTEGER, DIMENSION(3), INTENT(OUT)                 :: tile_count
    3025              :       INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(OUT)    :: bin_offsets, bin_rows
    3026              : 
    3027              :       INTEGER                                            :: candidate, ibin, idir, inode, irow, ix, &
    3028              :                                                             iy, iz, nbin, ntouched, position
    3029          264 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: bin_counts, bin_cursor, row_bin_count
    3030          264 :       INTEGER, ALLOCATABLE, DIMENSION(:, :)              :: row_bins
    3031              :       INTEGER, DIMENSION(3)                              :: touched_count
    3032              :       INTEGER, DIMENSION(&
    3033              :          native_grid_adjoint_max_tiles_per_direction, 3) :: touched_tiles
    3034              :       TYPE(native_grid_interpolation_stencil_type)       :: stencil
    3035              : 
    3036            0 :       CPASSERT(ASSOCIATED(pw_grid))
    3037          264 :       CPASSERT(ASSOCIATED(cell))
    3038          264 :       CPASSERT(SIZE(points, 1) == 3)
    3039              :       tile_count = (pw_grid%npts + native_grid_adjoint_tile_edge - 1)/ &
    3040         1056 :                    native_grid_adjoint_tile_edge
    3041         1056 :       nbin = PRODUCT(tile_count)
    3042            0 :       ALLOCATE (row_bin_count(SIZE(points, 2)), &
    3043         1276 :                 row_bins(native_grid_adjoint_max_bins_per_row, SIZE(points, 2)))
    3044          264 :       row_bin_count = 0
    3045          264 :       row_bins = 0
    3046              : !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) &
    3047              : !$OMP PRIVATE(candidate, idir, inode, ix, iy, iz, ntouched, stencil, &
    3048              : !$OMP         touched_count, touched_tiles) &
    3049          264 : !$OMP SHARED(cell, points, pw_grid, row_bin_count, row_bins, tile_count, wrap_auxiliary_cell)
    3050              :       DO irow = 1, SIZE(points, 2)
    3051              :          CALL create_native_grid_interpolation_stencil( &
    3052              :             stencil, pw_grid, cell, points(:, irow), wrap_auxiliary_cell, indices_only=.TRUE.)
    3053              :          IF (.NOT. stencil%active) CYCLE
    3054              :          touched_count = 0
    3055              :          touched_tiles = 0
    3056              :          DO idir = 1, 3
    3057              :             DO inode = 1, native_grid_interp_npts
    3058              :                IF (.NOT. stencil%valid(inode, idir)) CYCLE
    3059              :                candidate = stencil%relative_index(inode, idir)/native_grid_adjoint_tile_edge + 1
    3060              :                IF (ALL(touched_tiles(1:touched_count(idir), idir) /= candidate)) THEN
    3061              :                   touched_count(idir) = touched_count(idir) + 1
    3062              :                   CPASSERT(touched_count(idir) <= SIZE(touched_tiles, 1))
    3063              :                   touched_tiles(touched_count(idir), idir) = candidate
    3064              :                END IF
    3065              :             END DO
    3066              :          END DO
    3067              :          ntouched = 0
    3068              :          DO iz = 1, touched_count(3)
    3069              :             DO iy = 1, touched_count(2)
    3070              :                DO ix = 1, touched_count(1)
    3071              :                   ntouched = ntouched + 1
    3072              :                   CPASSERT(ntouched <= native_grid_adjoint_max_bins_per_row)
    3073              :                   row_bins(ntouched, irow) = 1 + touched_tiles(ix, 1) - 1 + tile_count(1)*( &
    3074              :                                              touched_tiles(iy, 2) - 1 + tile_count(2)*( &
    3075              :                                              touched_tiles(iz, 3) - 1))
    3076              :                END DO
    3077              :             END DO
    3078              :          END DO
    3079              :          row_bin_count(irow) = ntouched
    3080              :       END DO
    3081              : !$OMP END PARALLEL DO
    3082              : 
    3083         1584 :       ALLOCATE (bin_counts(nbin), bin_cursor(nbin), bin_offsets(nbin + 1))
    3084          264 :       bin_counts = 0
    3085       458524 :       DO irow = 1, SIZE(points, 2)
    3086       916784 :          DO ibin = 1, row_bin_count(irow)
    3087       916520 :             bin_counts(row_bins(ibin, irow)) = bin_counts(row_bins(ibin, irow)) + 1
    3088              :          END DO
    3089              :       END DO
    3090          264 :       bin_offsets(1) = 1
    3091          528 :       DO ibin = 1, nbin
    3092          528 :          bin_offsets(ibin + 1) = bin_offsets(ibin) + bin_counts(ibin)
    3093              :       END DO
    3094          770 :       ALLOCATE (bin_rows(bin_offsets(nbin + 1) - 1))
    3095          528 :       bin_cursor(:) = bin_offsets(1:nbin)
    3096       458524 :       DO irow = 1, SIZE(points, 2)
    3097       916784 :          DO ibin = 1, row_bin_count(irow)
    3098       458260 :             candidate = row_bins(ibin, irow)
    3099       458260 :             position = bin_cursor(candidate)
    3100       458260 :             bin_rows(position) = irow
    3101       916520 :             bin_cursor(candidate) = position + 1
    3102              :          END DO
    3103              :       END DO
    3104          264 :       DEALLOCATE (bin_counts, bin_cursor, row_bin_count, row_bins)
    3105              : 
    3106        31944 :    END SUBROUTINE build_native_grid_adjoint_bins
    3107              : 
    3108              : ! **************************************************************************************************
    3109              : !> \brief Return the inclusive PW-grid bounds owned by one linear tile index.
    3110              : !> \param pw_grid ...
    3111              : !> \param tile_index linear tile index
    3112              : !> \param tile_count number of tiles along each PW-grid direction
    3113              : !> \param tile_lower zero-based lower grid index
    3114              : !> \param tile_upper zero-based upper grid index
    3115              : ! **************************************************************************************************
    3116          264 :    SUBROUTINE native_grid_adjoint_tile_bounds(pw_grid, tile_index, tile_count, &
    3117              :                                               tile_lower, tile_upper)
    3118              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    3119              :       INTEGER, INTENT(IN)                                :: tile_index
    3120              :       INTEGER, DIMENSION(3), INTENT(IN)                  :: tile_count
    3121              :       INTEGER, DIMENSION(3), INTENT(OUT)                 :: tile_lower, tile_upper
    3122              : 
    3123              :       INTEGER                                            :: linear_tile
    3124              :       INTEGER, DIMENSION(3)                              :: expected_tile_count, tile_coord
    3125              : 
    3126          264 :       CPASSERT(ASSOCIATED(pw_grid))
    3127              :       expected_tile_count = (pw_grid%npts + native_grid_adjoint_tile_edge - 1)/ &
    3128         1056 :                             native_grid_adjoint_tile_edge
    3129         1056 :       CPASSERT(ALL(tile_count == expected_tile_count))
    3130         1056 :       CPASSERT(tile_index >= 1 .AND. tile_index <= PRODUCT(tile_count))
    3131          264 :       linear_tile = tile_index - 1
    3132          264 :       tile_coord(1) = MOD(linear_tile, tile_count(1))
    3133          264 :       linear_tile = linear_tile/tile_count(1)
    3134          264 :       tile_coord(2) = MOD(linear_tile, tile_count(2))
    3135          264 :       tile_coord(3) = linear_tile/tile_count(2)
    3136         1056 :       tile_lower = tile_coord*native_grid_adjoint_tile_edge
    3137         1056 :       tile_upper = MIN(tile_lower + native_grid_adjoint_tile_edge - 1, pw_grid%npts - 1)
    3138              : 
    3139          264 :    END SUBROUTINE native_grid_adjoint_tile_bounds
    3140              : 
    3141              : ! **************************************************************************************************
    3142              : !> \brief Apply the primitive-field interpolation transpose inside one disjoint PW tile.
    3143              : !> \param density ...
    3144              : !> \param grad ...
    3145              : !> \param kin ...
    3146              : !> \param pw_grid ...
    3147              : !> \param stencil ...
    3148              : !> \param density_value ...
    3149              : !> \param grad_value ...
    3150              : !> \param kin_value ...
    3151              : !> \param nchannels number of spin channels accumulated by the adjoint
    3152              : !> \param tile_lower zero-based lower grid index owned by this call
    3153              : !> \param tile_upper zero-based upper grid index owned by this call
    3154              : ! **************************************************************************************************
    3155       458260 :    SUBROUTINE add_native_grid_fields_adjoint_tile( &
    3156       458260 :       density, grad, kin, pw_grid, stencil, density_value, grad_value, kin_value, nchannels, &
    3157              :       tile_lower, tile_upper)
    3158              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: density
    3159              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT)   :: grad
    3160              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: kin
    3161              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    3162              :       TYPE(native_grid_interpolation_stencil_type), &
    3163              :          INTENT(IN)                                      :: stencil
    3164              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: density_value
    3165              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: grad_value
    3166              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: kin_value
    3167              :       INTEGER, INTENT(IN)                                :: nchannels
    3168              :       INTEGER, DIMENSION(3), INTENT(IN)                  :: tile_lower, tile_upper
    3169              : 
    3170              :       INTEGER                                            :: idir, inode_x, inode_y, inode_z, ipt, &
    3171              :                                                             ispin
    3172              :       INTEGER, DIMENSION(3)                              :: relative_index
    3173              :       REAL(KIND=dp)                                      :: coefficient
    3174              : 
    3175       458260 :       CPASSERT(ASSOCIATED(pw_grid))
    3176      1833040 :       CPASSERT(SIZE(density, 1) == PRODUCT(pw_grid%npts))
    3177       458260 :       CPASSERT(SIZE(density, 2) == nchannels)
    3178      1833040 :       CPASSERT(SIZE(grad, 1) == PRODUCT(pw_grid%npts))
    3179       458260 :       CPASSERT(SIZE(grad, 2) == 3)
    3180       458260 :       CPASSERT(SIZE(grad, 3) == nchannels)
    3181      1833040 :       CPASSERT(SIZE(kin, 1) == PRODUCT(pw_grid%npts))
    3182       458260 :       CPASSERT(SIZE(kin, 2) == nchannels)
    3183       458260 :       CPASSERT(SIZE(density_value) == 2)
    3184      1374780 :       CPASSERT(ALL(SHAPE(grad_value) == [3, 2]))
    3185       458260 :       CPASSERT(SIZE(kin_value) == 2)
    3186       458260 :       CPASSERT(nchannels >= 1 .AND. nchannels <= 2)
    3187      1833040 :       CPASSERT(ALL(tile_lower >= 0))
    3188      1833040 :       CPASSERT(ALL(tile_upper >= tile_lower))
    3189      1833040 :       CPASSERT(ALL(tile_upper < pw_grid%npts))
    3190       458260 :       IF (.NOT. stencil%active) RETURN
    3191      5957380 :       DO inode_z = 1, native_grid_interp_npts
    3192      5499120 :          IF (.NOT. stencil%valid(inode_z, 3)) CYCLE
    3193      5499120 :          relative_index(3) = stencil%relative_index(inode_z, 3)
    3194      5499120 :          IF (relative_index(3) < tile_lower(3) .OR. relative_index(3) > tile_upper(3)) CYCLE
    3195     71946820 :          DO inode_y = 1, native_grid_interp_npts
    3196     65989440 :             IF (.NOT. stencil%valid(inode_y, 2)) CYCLE
    3197     65989440 :             relative_index(2) = stencil%relative_index(inode_y, 2)
    3198     65989440 :             IF (relative_index(2) < tile_lower(2) .OR. relative_index(2) > tile_upper(2)) CYCLE
    3199    863361840 :             DO inode_x = 1, native_grid_interp_npts
    3200    791873280 :                IF (.NOT. stencil%valid(inode_x, 1)) CYCLE
    3201    791873280 :                relative_index(1) = stencil%relative_index(inode_x, 1)
    3202    791873280 :                IF (relative_index(1) < tile_lower(1) .OR. relative_index(1) > tile_upper(1)) CYCLE
    3203              :                ipt = 1 + relative_index(1) + pw_grid%npts(1)*( &
    3204    791873280 :                      relative_index(2) + pw_grid%npts(2)*relative_index(3))
    3205              :                coefficient = stencil%weight(inode_x, 1)* &
    3206              :                              stencil%weight(inode_y, 2)* &
    3207    791873280 :                              stencil%weight(inode_z, 3)
    3208   1831176000 :                DO ispin = 1, nchannels
    3209    973313280 :                   density(ipt, ispin) = density(ipt, ispin) + coefficient*density_value(ispin)
    3210   3893253120 :                   DO idir = 1, 3
    3211              :                      grad(ipt, idir, ispin) = grad(ipt, idir, ispin) + &
    3212   3893253120 :                                               coefficient*grad_value(idir, ispin)
    3213              :                   END DO
    3214   1765186560 :                   kin(ipt, ispin) = kin(ipt, ispin) + coefficient*kin_value(ispin)
    3215              :                END DO
    3216              :             END DO
    3217              :          END DO
    3218              :       END DO
    3219              : 
    3220              :    END SUBROUTINE add_native_grid_fields_adjoint_tile
    3221              : 
    3222              : ! **************************************************************************************************
    3223              : !> \brief Interpolate a replicated native-grid field at a Cartesian point.
    3224              : !> \param values ...
    3225              : !> \param pw_grid ...
    3226              : !> \param cell ...
    3227              : !> \param point ...
    3228              : !> \param wrap_auxiliary_cell wrap all auxiliary-grid directions
    3229              : !> \return ...
    3230              : ! **************************************************************************************************
    3231       375120 :    FUNCTION interpolate_native_grid(values, pw_grid, cell, point, wrap_auxiliary_cell) RESULT(value)
    3232              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: values
    3233              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    3234              :       TYPE(cell_type), INTENT(IN), POINTER               :: cell
    3235              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: point
    3236              :       LOGICAL, INTENT(IN), OPTIONAL                      :: wrap_auxiliary_cell
    3237              :       REAL(KIND=dp)                                      :: value
    3238              : 
    3239              :       INTEGER                                            :: corner_x, corner_y, corner_z, idir
    3240              :       INTEGER, DIMENSION(3)                              :: base, index, relative_index
    3241              :       LOGICAL                                            :: wrap_grid
    3242              :       REAL(KIND=dp)                                      :: coefficient
    3243              :       REAL(KIND=dp), DIMENSION(3)                        :: fraction, relative
    3244              :       REAL(KIND=dp), &
    3245              :          DIMENSION(native_grid_interp_npts, 3)           :: weights
    3246              : 
    3247       375120 :       CPASSERT(ASSOCIATED(pw_grid))
    3248       375120 :       CPASSERT(ASSOCIATED(cell))
    3249      1500480 :       DO idir = 1, 3
    3250      1500480 :          CPASSERT(SIZE(values, idir) == pw_grid%npts(idir))
    3251              :       END DO
    3252              : 
    3253      1365480 :       wrap_grid = ANY(cell%perd == 0)
    3254       375120 :       IF (PRESENT(wrap_auxiliary_cell)) wrap_grid = wrap_auxiliary_cell
    3255      4876560 :       relative = MATMUL(pw_grid%dh_inv, point)
    3256      1500480 :       DO idir = 1, 3
    3257      1125360 :          IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
    3258      1125360 :             relative(idir) = MODULO(relative(idir), REAL(pw_grid%npts(idir), KIND=dp))
    3259            0 :          ELSE IF (relative(idir) <= -REAL(native_grid_interp_offset_max, dp) .OR. &
    3260              :                   relative(idir) >= REAL(pw_grid%npts(idir) - &
    3261              :                                          native_grid_interp_offset_min, KIND=dp)) THEN
    3262       375120 :             value = 0.0_dp
    3263              :             RETURN
    3264              :          END IF
    3265      1125360 :          base(idir) = FLOOR(relative(idir))
    3266      1125360 :          FRACTION(idir) = relative(idir) - REAL(base(idir), KIND=dp)
    3267      1500480 :          CALL native_grid_lagrange_weights(FRACTION(idir), weights(:, idir))
    3268              :       END DO
    3269              : 
    3270              :       value = 0.0_dp
    3271      4876560 :       DO corner_z = native_grid_interp_offset_min, native_grid_interp_offset_max
    3272     58893840 :          DO corner_y = native_grid_interp_offset_min, native_grid_interp_offset_max
    3273    706726080 :             DO corner_x = native_grid_interp_offset_min, native_grid_interp_offset_max
    3274   2592829440 :                relative_index = base + [corner_x, corner_y, corner_z]
    3275              :                coefficient = weights(corner_x - native_grid_interp_offset_min + 1, 1)* &
    3276              :                              weights(corner_y - native_grid_interp_offset_min + 1, 2)* &
    3277    648207360 :                              weights(corner_z - native_grid_interp_offset_min + 1, 3)
    3278   2592829440 :                DO idir = 1, 3
    3279   2592829440 :                   IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
    3280   1944622080 :                      relative_index(idir) = MODULO(relative_index(idir), pw_grid%npts(idir))
    3281            0 :                   ELSE IF (relative_index(idir) < 0 .OR. &
    3282              :                            relative_index(idir) >= pw_grid%npts(idir)) THEN
    3283            0 :                      coefficient = 0.0_dp
    3284              :                   END IF
    3285              :                END DO
    3286    648207360 :                IF (coefficient == 0.0_dp) CYCLE
    3287   2248863840 :                index = LBOUND(values) + relative_index
    3288    702224640 :                value = value + coefficient*values(INDEX(1), INDEX(2), INDEX(3))
    3289              :             END DO
    3290              :          END DO
    3291              :       END DO
    3292              : 
    3293              :    END FUNCTION interpolate_native_grid
    3294              : 
    3295              : ! **************************************************************************************************
    3296              : !> \brief Return the Cartesian gradient of native-grid interpolation at one point.
    3297              : !> \param values ...
    3298              : !> \param pw_grid ...
    3299              : !> \param cell ...
    3300              : !> \param point ...
    3301              : !> \param wrap_auxiliary_cell wrap all auxiliary-grid directions
    3302              : !> \return ...
    3303              : ! **************************************************************************************************
    3304       625200 :    FUNCTION interpolate_native_grid_gradient(values, pw_grid, cell, point, &
    3305       625200 :                                              wrap_auxiliary_cell) RESULT(gradient)
    3306              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: values
    3307              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
    3308              :       TYPE(cell_type), INTENT(IN), POINTER               :: cell
    3309              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: point
    3310              :       LOGICAL, INTENT(IN), OPTIONAL                      :: wrap_auxiliary_cell
    3311              :       REAL(KIND=dp), DIMENSION(3)                        :: gradient
    3312              : 
    3313              :       INTEGER                                            :: corner_x, corner_y, corner_z, idir, jdir
    3314              :       INTEGER, DIMENSION(3)                              :: base, corner_index, index, relative_index
    3315              :       LOGICAL                                            :: wrap_grid
    3316              :       REAL(KIND=dp)                                      :: coefficient
    3317              :       REAL(KIND=dp), DIMENSION(3)                        :: fraction, gradient_relative, relative
    3318              :       REAL(KIND=dp), &
    3319              :          DIMENSION(native_grid_interp_npts, 3)           :: derivative_weights, weights
    3320              : 
    3321       625200 :       CPASSERT(ASSOCIATED(pw_grid))
    3322       625200 :       CPASSERT(ASSOCIATED(cell))
    3323      2500800 :       DO idir = 1, 3
    3324      2500800 :          CPASSERT(SIZE(values, idir) == pw_grid%npts(idir))
    3325              :       END DO
    3326              : 
    3327      2275800 :       wrap_grid = ANY(cell%perd == 0)
    3328       625200 :       IF (PRESENT(wrap_auxiliary_cell)) wrap_grid = wrap_auxiliary_cell
    3329      8127600 :       relative = MATMUL(pw_grid%dh_inv, point)
    3330      2500800 :       DO idir = 1, 3
    3331      1875600 :          IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
    3332      1875600 :             relative(idir) = MODULO(relative(idir), REAL(pw_grid%npts(idir), KIND=dp))
    3333            0 :          ELSE IF (relative(idir) <= -REAL(native_grid_interp_offset_max, dp) .OR. &
    3334              :                   relative(idir) >= REAL(pw_grid%npts(idir) - &
    3335              :                                          native_grid_interp_offset_min, KIND=dp)) THEN
    3336            0 :             gradient = 0.0_dp
    3337            0 :             RETURN
    3338              :          END IF
    3339      1875600 :          base(idir) = FLOOR(relative(idir))
    3340      1875600 :          FRACTION(idir) = relative(idir) - REAL(base(idir), KIND=dp)
    3341              :          CALL native_grid_lagrange_weights( &
    3342      2500800 :             FRACTION(idir), weights(:, idir), derivative_weights(:, idir))
    3343              :       END DO
    3344              : 
    3345       625200 :       gradient_relative = 0.0_dp
    3346      8127600 :       DO corner_z = native_grid_interp_offset_min, native_grid_interp_offset_max
    3347     98156400 :          DO corner_y = native_grid_interp_offset_min, native_grid_interp_offset_max
    3348   1177876800 :             DO corner_x = native_grid_interp_offset_min, native_grid_interp_offset_max
    3349   4321382400 :                relative_index = base + [corner_x, corner_y, corner_z]
    3350              :                corner_index = [corner_x, corner_y, corner_z] - &
    3351   4321382400 :                               native_grid_interp_offset_min + 1
    3352   4321382400 :                DO idir = 1, 3
    3353   4321382400 :                   IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
    3354   3241036800 :                      relative_index(idir) = MODULO(relative_index(idir), pw_grid%npts(idir))
    3355            0 :                   ELSE IF (relative_index(idir) < 0 .OR. &
    3356              :                            relative_index(idir) >= pw_grid%npts(idir)) THEN
    3357              :                      EXIT
    3358              :                   END IF
    3359              :                END DO
    3360   1080345600 :                IF (idir <= 3) CYCLE
    3361   4321382400 :                index = LBOUND(values) + relative_index
    3362   4411411200 :                DO idir = 1, 3
    3363              :                   coefficient = 1.0_dp
    3364  12964147200 :                   DO jdir = 1, 3
    3365  12964147200 :                      IF (jdir == idir) THEN
    3366              :                         coefficient = coefficient*derivative_weights( &
    3367   3241036800 :                                       corner_index(jdir), jdir)
    3368              :                      ELSE
    3369              :                         coefficient = coefficient*weights( &
    3370   6482073600 :                                       corner_index(jdir), jdir)
    3371              :                      END IF
    3372              :                   END DO
    3373              :                   gradient_relative(idir) = gradient_relative(idir) + &
    3374   4321382400 :                                             coefficient*values(INDEX(1), INDEX(2), INDEX(3))
    3375              :                END DO
    3376              :             END DO
    3377              :          END DO
    3378              :       END DO
    3379       625200 :       gradient = MATMUL(TRANSPOSE(pw_grid%dh_inv), gradient_relative)
    3380              : 
    3381              :    END FUNCTION interpolate_native_grid_gradient
    3382              : 
    3383              : ! **************************************************************************************************
    3384              : !> \brief Build the value and optional derivative weights for the native-grid interpolation.
    3385              : !> \param fraction fractional coordinate between two grid points
    3386              : !> \param weights interpolation weights
    3387              : !> \param derivative_weights optional derivatives with respect to fraction
    3388              : ! **************************************************************************************************
    3389      5750520 :    SUBROUTINE native_grid_lagrange_weights(fraction, weights, derivative_weights)
    3390              :       REAL(KIND=dp), INTENT(IN)                          :: fraction
    3391              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: weights
    3392              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT), OPTIONAL :: derivative_weights
    3393              : 
    3394              :       INTEGER                                            :: inode, jnode, knode, npoints
    3395              :       REAL(KIND=dp)                                      :: denominator, derivative, numerator
    3396     11501040 :       REAL(KIND=dp), DIMENSION(SIZE(weights))            :: nodes
    3397              : 
    3398      5750520 :       npoints = SIZE(weights)
    3399      5750520 :       IF (PRESENT(derivative_weights)) THEN
    3400      1875600 :          CPASSERT(SIZE(derivative_weights) == npoints)
    3401              :       END IF
    3402     74756760 :       DO inode = 1, npoints
    3403     74756760 :          nodes(inode) = REAL(native_grid_interp_offset_min + inode - 1, dp)
    3404              :       END DO
    3405     74756760 :       DO inode = 1, npoints
    3406              :          denominator = 1.0_dp
    3407              :          numerator = 1.0_dp
    3408    897081120 :          DO jnode = 1, npoints
    3409    828074880 :             IF (jnode == inode) CYCLE
    3410    759068640 :             denominator = denominator*(nodes(inode) - nodes(jnode))
    3411    897081120 :             numerator = numerator*(fraction - nodes(jnode))
    3412              :          END DO
    3413     69006240 :          weights(inode) = numerator/denominator
    3414     74756760 :          IF (PRESENT(derivative_weights)) THEN
    3415              :             derivative = 0.0_dp
    3416    292593600 :             DO knode = 1, npoints
    3417    270086400 :                IF (knode == inode) CYCLE
    3418              :                numerator = 1.0_dp
    3419   3218529600 :                DO jnode = 1, npoints
    3420   2970950400 :                   IF (jnode == inode .OR. jnode == knode) CYCLE
    3421   3218529600 :                   numerator = numerator*(fraction - nodes(jnode))
    3422              :                END DO
    3423    292593600 :                derivative = derivative + numerator/denominator
    3424              :             END DO
    3425     22507200 :             derivative_weights(inode) = derivative
    3426              :          END IF
    3427              :       END DO
    3428              : 
    3429      5750520 :    END SUBROUTINE native_grid_lagrange_weights
    3430              : 
    3431              : ! **************************************************************************************************
    3432              : !> \brief Express one radial node's first and second derivatives as linear combinations of the
    3433              : !>        local node values used by the C2-continuous quintic Hermite interpolant.
    3434              : !> \param grid_atom radial source grid
    3435              : !> \param descending whether radial nodes are stored in descending order
    3436              : !> \param node logical index of the node whose derivatives are required
    3437              : !> \param logical_start first logical index represented by the coefficient arrays
    3438              : !> \param slope coefficients of the first derivative
    3439              : !> \param curvature coefficients of the second derivative
    3440              : ! **************************************************************************************************
    3441       357470 :    SUBROUTINE radial_node_derivative_coefficients( &
    3442              :       grid_atom, descending, node, logical_start, slope, curvature)
    3443              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    3444              :       LOGICAL, INTENT(IN)                                :: descending
    3445              :       INTEGER, INTENT(IN)                                :: node, logical_start
    3446              :       REAL(dp), DIMENSION(4), INTENT(OUT)                :: slope, curvature
    3447              : 
    3448              :       INTEGER                                            :: center, hi, lo, n
    3449              :       REAL(dp)                                           :: h_hi, h_lo, x_center, x_hi, x_lo
    3450              : 
    3451       357470 :       n = grid_atom%nr
    3452       357470 :       slope = 0.0_dp
    3453       357470 :       curvature = 0.0_dp
    3454       357470 :       IF (node == 1) THEN
    3455              :          lo = 1
    3456              :          hi = 2
    3457       357470 :       ELSE IF (node == n) THEN
    3458            0 :          lo = n - 1
    3459            0 :          hi = n
    3460              :       ELSE
    3461       357470 :          lo = node - 1
    3462       357470 :          hi = node + 1
    3463              :       END IF
    3464       357470 :       x_lo = grid_atom%rad(MERGE(n + 1 - lo, lo, descending))
    3465       357470 :       x_hi = grid_atom%rad(MERGE(n + 1 - hi, hi, descending))
    3466       357470 :       slope(lo - logical_start + 1) = -1.0_dp/(x_hi - x_lo)
    3467       357470 :       slope(hi - logical_start + 1) = 1.0_dp/(x_hi - x_lo)
    3468              : 
    3469       357470 :       IF (n < 3) RETURN
    3470       357470 :       center = MIN(MAX(node, 2), n - 1)
    3471       357470 :       lo = center - 1
    3472       357470 :       hi = center + 1
    3473       357470 :       x_lo = grid_atom%rad(MERGE(n + 1 - lo, lo, descending))
    3474       357470 :       x_center = grid_atom%rad(MERGE(n + 1 - center, center, descending))
    3475       357470 :       x_hi = grid_atom%rad(MERGE(n + 1 - hi, hi, descending))
    3476       357470 :       h_lo = x_center - x_lo
    3477       357470 :       h_hi = x_hi - x_center
    3478       357470 :       curvature(lo - logical_start + 1) = 2.0_dp/(h_lo*(h_lo + h_hi))
    3479              :       curvature(center - logical_start + 1) = &
    3480       357470 :          -2.0_dp*(1.0_dp/h_lo + 1.0_dp/h_hi)/(h_lo + h_hi)
    3481       357470 :       curvature(hi - logical_start + 1) = 2.0_dp/(h_hi*(h_lo + h_hi))
    3482              : 
    3483              :    END SUBROUTINE radial_node_derivative_coefficients
    3484              : 
    3485              : ! **************************************************************************************************
    3486              : !> \brief Build mutually consistent value and Cartesian-derivative weights for interpolation from
    3487              : !>        a GAPW radial/Lebedev atom grid to one arbitrary local displacement.
    3488              : !> \param grid_atom source atom grid
    3489              : !> \param harmonics source spherical harmonics
    3490              : !> \param displacement point minus source-image coordinate
    3491              : !> \param cutoff compact support radius
    3492              : !> \param radial_indices active radial nodes
    3493              : !> \param radial_weights interpolation weights on the active radial nodes
    3494              : !> \param radial_derivative_weights radial derivatives of the interpolation weights
    3495              : !> \param nradial number of active radial nodes
    3496              : !> \param angular_weights angular interpolation weights
    3497              : !> \param angular_derivative_weights Cartesian derivatives of the angular weights
    3498              : !> \param active whether the point lies inside the compact support
    3499              : ! **************************************************************************************************
    3500     55270820 :    SUBROUTINE atom_grid_interpolation_weights( &
    3501              :       grid_atom, harmonics, displacement, cutoff, radial_indices, radial_weights, &
    3502     55270820 :       radial_derivative_weights, nradial, angular_weights, angular_derivative_weights, active)
    3503              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    3504              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    3505              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: displacement
    3506              :       REAL(dp), INTENT(IN)                               :: cutoff
    3507              :       INTEGER, DIMENSION(4), INTENT(OUT)                 :: radial_indices
    3508              :       REAL(dp), DIMENSION(4), INTENT(OUT)                :: radial_weights, radial_derivative_weights
    3509              :       INTEGER, INTENT(OUT)                               :: nradial
    3510              :       REAL(dp), DIMENSION(:), INTENT(OUT)                :: angular_weights
    3511              :       REAL(dp), DIMENSION(:, :), INTENT(OUT)             :: angular_derivative_weights
    3512              :       LOGICAL, INTENT(OUT)                               :: active
    3513              : 
    3514              :       INTEGER                                            :: ia, ic, inode, iso, l, left, left_pos, &
    3515              :                                                             logical_end, logical_start, lx, ly, &
    3516              :                                                             lz, n, right_pos, shell_index
    3517              :       LOGICAL                                            :: descending
    3518              :       REAL(dp)                                           :: dh00, dh01, dh10, dh11, dh20, dh21, h00, &
    3519              :                                                             h01, h10, h11, h20, h21, h_interval, &
    3520              :                                                             monomial, radius, solid_derivative, t, &
    3521              :                                                             x1, x2
    3522              :       REAL(dp), DIMENSION(3)                             :: direction
    3523    110541640 :       REAL(dp), DIMENSION(harmonics%max_s_harm)          :: angular_values
    3524              :       REAL(dp), DIMENSION(4)                             :: curvature_left, curvature_right, &
    3525              :                                                             slope_left, slope_right
    3526     55092085 :       REAL(dp), DIMENSION(3, harmonics%max_s_harm)       :: angular_value_derivatives
    3527              : 
    3528     55270820 :       CPASSERT(ASSOCIATED(grid_atom))
    3529     55270820 :       CPASSERT(ASSOCIATED(harmonics))
    3530     55270820 :       CPASSERT(SIZE(angular_weights) == grid_atom%ng_sphere)
    3531     55270820 :       CPASSERT(SIZE(angular_derivative_weights, 1) == 3)
    3532     55270820 :       CPASSERT(SIZE(angular_derivative_weights, 2) == grid_atom%ng_sphere)
    3533              : 
    3534     55270820 :       radial_indices = 0
    3535     55270820 :       radial_weights = 0.0_dp
    3536     55270820 :       radial_derivative_weights = 0.0_dp
    3537   2399655180 :       angular_weights = 0.0_dp
    3538   9432808260 :       angular_derivative_weights = 0.0_dp
    3539     55270820 :       nradial = 0
    3540     55270820 :       active = .FALSE.
    3541     55270820 :       n = grid_atom%nr
    3542     55270820 :       descending = grid_atom%rad(1) > grid_atom%rad(n)
    3543    221083280 :       radius = SQRT(SUM(displacement**2))
    3544     55270820 :       IF (radius > cutoff .OR. &
    3545              :           radius > grid_atom%rad(MERGE(1, n, descending))) RETURN
    3546       178735 :       IF (radius <= 1.0E-12_dp) RETURN
    3547       714940 :       direction = displacement/radius
    3548              : 
    3549       178735 :       CPASSERT(n >= 2)
    3550       178735 :       left = n - 1
    3551       357470 :       IF (radius <= grid_atom%rad(MERGE(n, 1, descending))) THEN
    3552            0 :          left = 1
    3553              :       ELSE
    3554      4338267 :          DO inode = 1, n - 1
    3555      4338267 :             IF (radius <= grid_atom%rad(MERGE(n - inode, inode + 1, descending))) THEN
    3556       178735 :                left = inode
    3557       178735 :                EXIT
    3558              :             END IF
    3559              :          END DO
    3560              :       END IF
    3561              : 
    3562       178735 :       logical_start = MAX(1, left - 1)
    3563       178735 :       logical_end = MIN(n, left + 2)
    3564       178735 :       nradial = logical_end - logical_start + 1
    3565       893675 :       DO inode = 1, nradial
    3566              :          radial_indices(inode) = MERGE(n + 2 - logical_start - inode, &
    3567       893675 :                                        logical_start + inode - 1, descending)
    3568              :       END DO
    3569       178735 :       left_pos = left - logical_start + 1
    3570       178735 :       right_pos = left_pos + 1
    3571       178735 :       x1 = grid_atom%rad(radial_indices(left_pos))
    3572       178735 :       x2 = grid_atom%rad(radial_indices(right_pos))
    3573       178735 :       h_interval = x2 - x1
    3574       178735 :       t = (radius - x1)/h_interval
    3575              : 
    3576       178735 :       h00 = 1.0_dp - 10.0_dp*t**3 + 15.0_dp*t**4 - 6.0_dp*t**5
    3577       178735 :       h10 = t - 6.0_dp*t**3 + 8.0_dp*t**4 - 3.0_dp*t**5
    3578       178735 :       h20 = 0.5_dp*(t**2 - 3.0_dp*t**3 + 3.0_dp*t**4 - t**5)
    3579       178735 :       h01 = 10.0_dp*t**3 - 15.0_dp*t**4 + 6.0_dp*t**5
    3580       178735 :       h11 = -4.0_dp*t**3 + 7.0_dp*t**4 - 3.0_dp*t**5
    3581       178735 :       h21 = 0.5_dp*(t**3 - 2.0_dp*t**4 + t**5)
    3582       178735 :       dh00 = -30.0_dp*t**2 + 60.0_dp*t**3 - 30.0_dp*t**4
    3583       178735 :       dh10 = 1.0_dp - 18.0_dp*t**2 + 32.0_dp*t**3 - 15.0_dp*t**4
    3584       178735 :       dh20 = 0.5_dp*(2.0_dp*t - 9.0_dp*t**2 + 12.0_dp*t**3 - 5.0_dp*t**4)
    3585       178735 :       dh01 = 30.0_dp*t**2 - 60.0_dp*t**3 + 30.0_dp*t**4
    3586       178735 :       dh11 = -12.0_dp*t**2 + 28.0_dp*t**3 - 15.0_dp*t**4
    3587       178735 :       dh21 = 0.5_dp*(3.0_dp*t**2 - 8.0_dp*t**3 + 5.0_dp*t**4)
    3588              : 
    3589              :       CALL radial_node_derivative_coefficients( &
    3590       178735 :          grid_atom, descending, left, logical_start, slope_left, curvature_left)
    3591              :       CALL radial_node_derivative_coefficients( &
    3592       178735 :          grid_atom, descending, left + 1, logical_start, slope_right, curvature_right)
    3593       178735 :       radial_weights(left_pos) = radial_weights(left_pos) + h00
    3594       178735 :       radial_weights(right_pos) = radial_weights(right_pos) + h01
    3595              :       radial_weights(1:nradial) = radial_weights(1:nradial) + &
    3596              :                                   h_interval*(h10*slope_left(1:nradial) + &
    3597              :                                               h11*slope_right(1:nradial)) + &
    3598              :                                   h_interval**2*(h20*curvature_left(1:nradial) + &
    3599       893675 :                                                  h21*curvature_right(1:nradial))
    3600              :       radial_derivative_weights(left_pos) = &
    3601       178735 :          radial_derivative_weights(left_pos) + dh00/h_interval
    3602              :       radial_derivative_weights(right_pos) = &
    3603       178735 :          radial_derivative_weights(right_pos) + dh01/h_interval
    3604              :       radial_derivative_weights(1:nradial) = radial_derivative_weights(1:nradial) + &
    3605              :                                              dh10*slope_left(1:nradial) + &
    3606              :                                              dh11*slope_right(1:nradial) + &
    3607              :                                              h_interval*(dh20*curvature_left(1:nradial) + &
    3608       893675 :                                                          dh21*curvature_right(1:nradial))
    3609              : 
    3610      1066278 :       angular_values = 0.0_dp
    3611      3728907 :       angular_value_derivatives = 0.0_dp
    3612      1066278 :       DO iso = 1, harmonics%max_s_harm
    3613       887543 :          l = indso(1, iso)
    3614       887543 :          CALL y_lm(direction, angular_values(iso), l, indso(2, iso))
    3615       887543 :          IF (l == 0) CYCLE
    3616       708808 :          shell_index = iso - nsoset(l - 1)
    3617      4878622 :          DO ic = 1, nco(l)
    3618      4169814 :             lx = indco(1, ic + ncoset(l - 1))
    3619      4169814 :             ly = indco(2, ic + ncoset(l - 1))
    3620      4169814 :             lz = indco(3, ic + ncoset(l - 1))
    3621      4169814 :             IF (lx > 0) THEN
    3622              :                monomial = REAL(lx, dp)*direction(1)**(lx - 1)* &
    3623      2134818 :                           direction(2)**ly*direction(3)**lz
    3624              :                angular_value_derivatives(1, iso) = angular_value_derivatives(1, iso) + &
    3625      2134818 :                                                    orbtramat(l)%slm(shell_index, ic)*monomial
    3626              :             END IF
    3627      4169814 :             IF (ly > 0) THEN
    3628              :                monomial = direction(1)**lx*REAL(ly, dp)*direction(2)**(ly - 1)* &
    3629      2134818 :                           direction(3)**lz
    3630              :                angular_value_derivatives(2, iso) = angular_value_derivatives(2, iso) + &
    3631      2134818 :                                                    orbtramat(l)%slm(shell_index, ic)*monomial
    3632              :             END IF
    3633      4878622 :             IF (lz > 0) THEN
    3634              :                monomial = direction(1)**lx*direction(2)**ly* &
    3635      2134818 :                           REAL(lz, dp)*direction(3)**(lz - 1)
    3636              :                angular_value_derivatives(3, iso) = angular_value_derivatives(3, iso) + &
    3637      2134818 :                                                    orbtramat(l)%slm(shell_index, ic)*monomial
    3638              :             END IF
    3639              :          END DO
    3640      3013967 :          DO inode = 1, 3
    3641      2126424 :             solid_derivative = angular_value_derivatives(inode, iso)
    3642              :             angular_value_derivatives(inode, iso) = (solid_derivative - &
    3643              :                                                      REAL(l, dp)*angular_values(iso)* &
    3644      3013967 :                                                      direction(inode))/radius
    3645              :          END DO
    3646              :       END DO
    3647              : 
    3648      7705401 :       DO ia = 1, grid_atom%ng_sphere
    3649              :          angular_weights(ia) = grid_atom%wa(ia)* &
    3650              :                                DOT_PRODUCT(harmonics%slm(ia, 1:harmonics%max_s_harm), &
    3651     45553092 :                                            angular_values)
    3652     30285399 :          DO inode = 1, 3
    3653              :             angular_derivative_weights(inode, ia) = grid_atom%wa(ia)* &
    3654              :                                                     DOT_PRODUCT(harmonics%slm(ia, 1:harmonics%max_s_harm), &
    3655    144185942 :                                                                 angular_value_derivatives(inode, :))
    3656              :          END DO
    3657              :       END DO
    3658       178735 :       active = .TRUE.
    3659              : 
    3660              :    END SUBROUTINE atom_grid_interpolation_weights
    3661              : 
    3662              : ! **************************************************************************************************
    3663              : !> \brief Interpolate hard-minus-soft primitive fields and their spatial derivatives from one
    3664              : !>        GAPW atom grid.
    3665              : !> \param grid_atom radial and angular source grid
    3666              : !> \param harmonics spherical-harmonic representation of the source grid
    3667              : !> \param displacement target point relative to the source-atom image
    3668              : !> \param cutoff compact support radius of the source fields
    3669              : !> \param nspins number of spin channels
    3670              : !> \param rho_h hard one-center density values
    3671              : !> \param rho_s soft one-center density values
    3672              : !> \param drho_h hard one-center density-gradient values
    3673              : !> \param drho_s soft one-center density-gradient values
    3674              : !> \param tau_h hard one-center kinetic-energy-density values
    3675              : !> \param tau_s soft one-center kinetic-energy-density values
    3676              : !> \param density interpolated hard-minus-soft density
    3677              : !> \param gradient interpolated hard-minus-soft density gradient
    3678              : !> \param kin interpolated hard-minus-soft kinetic-energy density
    3679              : !> \param density_spatial Cartesian derivatives of density
    3680              : !> \param gradient_spatial Cartesian derivatives of the density gradient
    3681              : !> \param kin_spatial Cartesian derivatives of the kinetic-energy density
    3682              : ! **************************************************************************************************
    3683     32381628 :    SUBROUTINE interpolate_gapw_atom_grid_fields( &
    3684     64763256 :       grid_atom, harmonics, displacement, cutoff, nspins, rho_h, rho_s, drho_h, drho_s, &
    3685     32381628 :       tau_h, tau_s, density, gradient, kin, density_spatial, gradient_spatial, kin_spatial)
    3686              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    3687              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    3688              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: displacement
    3689              :       REAL(dp), INTENT(IN)                               :: cutoff
    3690              :       INTEGER, INTENT(IN)                                :: nspins
    3691              :       REAL(dp), DIMENSION(:, :, :), INTENT(IN)           :: rho_h, rho_s
    3692              :       REAL(dp), DIMENSION(:, :, :, :), INTENT(IN)        :: drho_h, drho_s
    3693              :       REAL(dp), DIMENSION(:, :, :), INTENT(IN)           :: tau_h, tau_s
    3694              :       REAL(dp), DIMENSION(2), INTENT(OUT)                :: density
    3695              :       REAL(dp), DIMENSION(3, 2), INTENT(OUT)             :: gradient
    3696              :       REAL(dp), DIMENSION(2), INTENT(OUT)                :: kin
    3697              :       REAL(dp), DIMENSION(3, 2), INTENT(OUT)             :: density_spatial
    3698              :       REAL(dp), DIMENSION(3, 3, 2), INTENT(OUT)          :: gradient_spatial
    3699              :       REAL(dp), DIMENSION(3, 2), INTENT(OUT)             :: kin_spatial
    3700              : 
    3701              :       INTEGER                                            :: ia, idir, inode, ir, ispin, jdir, nradial
    3702              :       INTEGER, DIMENSION(4)                              :: radial_indices
    3703              :       LOGICAL                                            :: active
    3704              :       REAL(dp)                                           :: derivative_weight, weight
    3705     64763256 :       REAL(dp), DIMENSION(grid_atom%ng_sphere)           :: angular_weights
    3706              :       REAL(dp), DIMENSION(4)                             :: radial_derivative_weights, radial_weights
    3707     64763256 :       REAL(dp), DIMENSION(3, grid_atom%ng_sphere)        :: angular_derivative_weights
    3708              : 
    3709     32381628 :       density = 0.0_dp
    3710     32381628 :       gradient = 0.0_dp
    3711     32381628 :       kin = 0.0_dp
    3712     32381628 :       density_spatial = 0.0_dp
    3713     32381628 :       gradient_spatial = 0.0_dp
    3714     32381628 :       kin_spatial = 0.0_dp
    3715              :       CALL atom_grid_interpolation_weights( &
    3716              :          grid_atom, harmonics, displacement, cutoff, radial_indices, radial_weights, &
    3717     32381628 :          radial_derivative_weights, nradial, angular_weights, angular_derivative_weights, active)
    3718     32381628 :       IF (active) THEN
    3719       521725 :          DO inode = 1, nradial
    3720       417380 :             ir = radial_indices(inode)
    3721     18412949 :             DO ia = 1, grid_atom%ng_sphere
    3722     17891224 :                weight = radial_weights(inode)*angular_weights(ia)
    3723     36199828 :                DO ispin = 1, nspins
    3724              :                   density(ispin) = density(ispin) + &
    3725     17891224 :                                    weight*(rho_h(ia, ir, ispin) - rho_s(ia, ir, ispin))
    3726              :                   kin(ispin) = kin(ispin) + &
    3727     17891224 :                                weight*(tau_h(ia, ir, ispin) - tau_s(ia, ir, ispin))
    3728     89456120 :                   DO idir = 1, 3
    3729              :                      gradient(idir, ispin) = gradient(idir, ispin) + &
    3730              :                                              weight*(drho_h(idir, ia, ir, ispin) - &
    3731     53673672 :                                                      drho_s(idir, ia, ir, ispin))
    3732              :                      derivative_weight = radial_derivative_weights(inode)* &
    3733              :                                          displacement(idir)/SQRT(SUM(displacement**2))* &
    3734              :                                          angular_weights(ia) + radial_weights(inode)* &
    3735    214694688 :                                          angular_derivative_weights(idir, ia)
    3736              :                      density_spatial(idir, ispin) = density_spatial(idir, ispin) + &
    3737     53673672 :                                                     derivative_weight*(rho_h(ia, ir, ispin) - rho_s(ia, ir, ispin))
    3738              :                      kin_spatial(idir, ispin) = kin_spatial(idir, ispin) + &
    3739     53673672 :                                                 derivative_weight*(tau_h(ia, ir, ispin) - tau_s(ia, ir, ispin))
    3740    232585912 :                      DO jdir = 1, 3
    3741              :                         gradient_spatial(jdir, idir, ispin) = &
    3742              :                            gradient_spatial(jdir, idir, ispin) + derivative_weight*( &
    3743    214694688 :                            drho_h(jdir, ia, ir, ispin) - drho_s(jdir, ia, ir, ispin))
    3744              :                      END DO
    3745              :                   END DO
    3746              :                END DO
    3747              :             END DO
    3748              :          END DO
    3749              :       END IF
    3750     32381628 :    END SUBROUTINE interpolate_gapw_atom_grid_fields
    3751              : 
    3752              : ! **************************************************************************************************
    3753              : !> \brief Apply the exact transpose of interpolate_gapw_atom_grid_fields to one-center potentials.
    3754              : !> \param grid_atom radial and angular source grid
    3755              : !> \param harmonics spherical-harmonic representation of the source grid
    3756              : !> \param displacement target point relative to the source-atom image
    3757              : !> \param cutoff compact support radius of the source fields
    3758              : !> \param nspins number of spin channels
    3759              : !> \param density_adjoint model derivative with respect to density
    3760              : !> \param gradient_adjoint model derivative with respect to the density gradient
    3761              : !> \param kin_adjoint model derivative with respect to kinetic-energy density
    3762              : !> \param vxc_h accumulated hard one-center density potential
    3763              : !> \param vxc_s accumulated soft one-center density potential
    3764              : !> \param vxg_h accumulated hard one-center density-gradient potential
    3765              : !> \param vxg_s accumulated soft one-center density-gradient potential
    3766              : !> \param vtau_h accumulated hard one-center kinetic-energy-density potential
    3767              : !> \param vtau_s accumulated soft one-center kinetic-energy-density potential
    3768              : ! **************************************************************************************************
    3769     22889192 :    SUBROUTINE add_gapw_atom_grid_interpolation_adjoint( &
    3770              :       grid_atom, harmonics, displacement, cutoff, nspins, density_adjoint, gradient_adjoint, &
    3771     22889192 :       kin_adjoint, vxc_h, vxc_s, vxg_h, vxg_s, vtau_h, vtau_s)
    3772              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    3773              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    3774              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: displacement
    3775              :       REAL(dp), INTENT(IN)                               :: cutoff
    3776              :       INTEGER, INTENT(IN)                                :: nspins
    3777              :       REAL(dp), DIMENSION(2), INTENT(IN)                 :: density_adjoint
    3778              :       REAL(dp), DIMENSION(3, 2), INTENT(IN)              :: gradient_adjoint
    3779              :       REAL(dp), DIMENSION(2), INTENT(IN)                 :: kin_adjoint
    3780              :       REAL(dp), DIMENSION(:, :, :), INTENT(INOUT)        :: vxc_h, vxc_s
    3781              :       REAL(dp), DIMENSION(:, :, :, :), INTENT(INOUT)     :: vxg_h, vxg_s
    3782              :       REAL(dp), DIMENSION(:, :, :), INTENT(INOUT)        :: vtau_h, vtau_s
    3783              : 
    3784              :       INTEGER                                            :: ia, idir, inode, ir, ispin, nradial
    3785              :       INTEGER, DIMENSION(4)                              :: radial_indices
    3786              :       LOGICAL                                            :: active
    3787              :       REAL(dp)                                           :: value
    3788     45778384 :       REAL(dp), DIMENSION(grid_atom%ng_sphere)           :: angular_weights
    3789              :       REAL(dp), DIMENSION(4)                             :: radial_derivative_weights, radial_weights
    3790     45778384 :       REAL(dp), DIMENSION(3, grid_atom%ng_sphere)        :: angular_derivative_weights
    3791              : 
    3792              :       CALL atom_grid_interpolation_weights( &
    3793              :          grid_atom, harmonics, displacement, cutoff, radial_indices, radial_weights, &
    3794     22889192 :          radial_derivative_weights, nradial, angular_weights, angular_derivative_weights, active)
    3795     22889192 :       IF (active) THEN
    3796       371950 :          DO inode = 1, nradial
    3797       297560 :             ir = radial_indices(inode)
    3798     12587390 :             DO ia = 1, grid_atom%ng_sphere
    3799     12215440 :                value = radial_weights(inode)*angular_weights(ia)
    3800     24728440 :                DO ispin = 1, nspins
    3801              :                   ! CP2K applies the hard-minus-soft sign when the two one-center
    3802              :                   ! matrices are assembled, so both stored potentials carry the
    3803              :                   ! same transpose-interpolation coefficient.
    3804     12215440 :                   vxc_h(ia, ir, ispin) = vxc_h(ia, ir, ispin) + value*density_adjoint(ispin)
    3805     12215440 :                   vxc_s(ia, ir, ispin) = vxc_s(ia, ir, ispin) + value*density_adjoint(ispin)
    3806     12215440 :                   vtau_h(ia, ir, ispin) = vtau_h(ia, ir, ispin) + value*kin_adjoint(ispin)
    3807     12215440 :                   vtau_s(ia, ir, ispin) = vtau_s(ia, ir, ispin) + value*kin_adjoint(ispin)
    3808     61077200 :                   DO idir = 1, 3
    3809              :                      vxg_h(idir, ia, ir, ispin) = vxg_h(idir, ia, ir, ispin) + &
    3810     36646320 :                                                   value*gradient_adjoint(idir, ispin)
    3811              :                      vxg_s(idir, ia, ir, ispin) = vxg_s(idir, ia, ir, ispin) + &
    3812     48861760 :                                                   value*gradient_adjoint(idir, ispin)
    3813              :                   END DO
    3814              :                END DO
    3815              :             END DO
    3816              :          END DO
    3817              :       END IF
    3818     22889192 :    END SUBROUTINE add_gapw_atom_grid_interpolation_adjoint
    3819              : 
    3820              : ! **************************************************************************************************
    3821              : !> \brief ...
    3822              : !> \param qs_env ...
    3823              : !> \param exc1 the on-body ex energy contribution
    3824              : !> \param gradient_atom_set ...
    3825              : ! **************************************************************************************************
    3826           10 :    SUBROUTINE calculate_vxc_atom_epr(qs_env, exc1, gradient_atom_set)
    3827              : 
    3828              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3829              :       REAL(dp), INTENT(INOUT)                            :: exc1
    3830              :       TYPE(nablavks_atom_type), DIMENSION(:), POINTER    :: gradient_atom_set
    3831              : 
    3832              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_vxc_atom_epr'
    3833              : 
    3834              :       INTEGER                                            :: bo(2), handle, ia, iat, iatom, idir, &
    3835              :                                                             ikind, ir, ispin, myfun, na, natom, &
    3836              :                                                             nr, nspins, num_pe
    3837              :       INTEGER, DIMENSION(2, 3)                           :: bounds
    3838           10 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
    3839              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
    3840              :                                                             paw_atom, tau_f
    3841              :       REAL(dp)                                           :: agr, alpha, density_cut, exc_h, exc_s, &
    3842              :                                                             gradient_cut, tau_cut
    3843              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
    3844              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
    3845           20 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
    3846           20 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho_h, rho_s, tau_h, tau_s, vtau_h, &
    3847           10 :                                                             vtau_s, vxc_h, vxc_s
    3848           20 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho_h, drho_s, vxg_h, vxg_s
    3849           10 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3850              :       TYPE(dft_control_type), POINTER                    :: dft_control
    3851              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
    3852              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
    3853              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
    3854              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3855           10 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: my_kind_set
    3856           10 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
    3857           10 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
    3858           10 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: my_rho_atom_set
    3859              :       TYPE(rho_atom_type), POINTER                       :: rho_atom
    3860              :       TYPE(section_vals_type), POINTER                   :: input, my_xc_section, xc_fun_section
    3861           10 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
    3862              :       TYPE(xc_derivative_set_type)                       :: deriv_set
    3863              :       TYPE(xc_rho_cflags_type)                           :: needs
    3864              :       TYPE(xc_rho_set_type)                              :: rho_set_h, rho_set_s
    3865              : 
    3866              : ! -------------------------------------------------------------------------
    3867              : 
    3868           10 :       CALL timeset(routineN, handle)
    3869              : 
    3870           10 :       NULLIFY (atom_list)
    3871           10 :       NULLIFY (my_kind_set)
    3872           10 :       NULLIFY (atomic_kind_set)
    3873           10 :       NULLIFY (grid_atom)
    3874           10 :       NULLIFY (harmonics)
    3875           10 :       NULLIFY (input)
    3876           10 :       NULLIFY (para_env)
    3877           10 :       NULLIFY (rho_atom)
    3878           10 :       NULLIFY (my_rho_atom_set)
    3879           10 :       NULLIFY (rho_nlcc)
    3880              : 
    3881              :       CALL get_qs_env(qs_env=qs_env, &
    3882              :                       dft_control=dft_control, &
    3883              :                       para_env=para_env, &
    3884              :                       atomic_kind_set=atomic_kind_set, &
    3885              :                       qs_kind_set=my_kind_set, &
    3886              :                       input=input, &
    3887           10 :                       rho_atom_set=my_rho_atom_set)
    3888              : 
    3889           10 :       nlcc = has_nlcc(my_kind_set)
    3890           10 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
    3891              : 
    3892              :       my_xc_section => section_vals_get_subs_vals(input, &
    3893           10 :                                                   "PROPERTIES%LINRES%EPR%PRINT%G_TENSOR%XC")
    3894           10 :       xc_fun_section => section_vals_get_subs_vals(my_xc_section, "XC_FUNCTIONAL")
    3895              :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", &
    3896           10 :                                 i_val=myfun)
    3897              : 
    3898           10 :       IF (myfun == xc_none) THEN
    3899            0 :          exc1 = 0.0_dp
    3900            0 :          my_rho_atom_set(:)%exc_h = 0.0_dp
    3901            0 :          my_rho_atom_set(:)%exc_s = 0.0_dp
    3902              :       ELSE
    3903              :          CALL section_vals_val_get(my_xc_section, "DENSITY_CUTOFF", &
    3904           10 :                                    r_val=density_cut)
    3905              :          CALL section_vals_val_get(my_xc_section, "GRADIENT_CUTOFF", &
    3906           10 :                                    r_val=gradient_cut)
    3907              :          CALL section_vals_val_get(my_xc_section, "TAU_CUTOFF", &
    3908           10 :                                    r_val=tau_cut)
    3909              : 
    3910           10 :          lsd = dft_control%lsd
    3911           10 :          nspins = dft_control%nspins
    3912              :          needs = xc_functionals_get_needs(xc_fun_section, &
    3913              :                                           lsd=lsd, &
    3914           10 :                                           calc_potential=.TRUE.)
    3915              : 
    3916              :          ! whatever the xc, if epr_xc, drho_spin is needed
    3917           10 :          needs%drho_spin = .TRUE.
    3918              : 
    3919           10 :          gradient_f = (needs%drho .OR. needs%drho_spin)
    3920           10 :          tau_f = (needs%tau .OR. needs%tau_spin)
    3921              : 
    3922              :          ! Initialize energy contribution from the one center XC terms to zero
    3923           10 :          exc1 = 0.0_dp
    3924              : 
    3925              :          ! Nullify some pointers for work-arrays
    3926           10 :          NULLIFY (rho_h, drho_h, rho_s, drho_s, weight_h, weight_s)
    3927           10 :          NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
    3928           10 :          NULLIFY (tau_h, tau_s)
    3929           10 :          NULLIFY (vtau_h, vtau_s)
    3930              : 
    3931              :          ! Here starts the loop over all the atoms
    3932              : 
    3933           30 :          DO ikind = 1, SIZE(atomic_kind_set)
    3934           20 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
    3935              :             CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
    3936           20 :                              harmonics=harmonics, grid_atom=grid_atom)
    3937           20 :             CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
    3938              : 
    3939           20 :             IF (.NOT. paw_atom) CYCLE
    3940              : 
    3941           20 :             nr = grid_atom%nr
    3942           20 :             na = grid_atom%ng_sphere
    3943              : 
    3944              :             ! Prepare the structures needed to calculate and store the xc derivatives
    3945              : 
    3946              :             ! Array dimension: here anly one dimensional arrays are used,
    3947              :             ! i.e. only the first column of deriv_data is read.
    3948              :             ! The other to dimensions  are set to size equal 1
    3949          200 :             bounds(1:2, 1:3) = 1
    3950           20 :             bounds(2, 1) = na
    3951           20 :             bounds(2, 2) = nr
    3952              : 
    3953              :             ! set integration weights
    3954           20 :             IF (accint) THEN
    3955            0 :                weight_h => grid_atom%weight
    3956            0 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
    3957            0 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    3958            0 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
    3959              :                END IF
    3960            0 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
    3961            0 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
    3962            0 :                   DO ir = 1, nr
    3963            0 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
    3964            0 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
    3965              :                   END DO
    3966            0 :                   grid_atom%gapw_weight_alpha = alpha
    3967              :                END IF
    3968            0 :                weight_s => grid_atom%gapw_weight_s
    3969              :             ELSE
    3970           20 :                weight_h => grid_atom%weight
    3971           20 :                weight_s => grid_atom%weight
    3972              :             END IF
    3973              : 
    3974              :             ! create a place where to put the derivatives
    3975           20 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
    3976              :             ! create the place where to store the argument for the functionals
    3977              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
    3978           20 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3979              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
    3980           20 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
    3981              : 
    3982              :             ! allocate the required 3d arrays where to store rho and drho
    3983           20 :             CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
    3984           20 :             CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
    3985              : 
    3986           20 :             CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
    3987           20 :             CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
    3988           20 :             CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
    3989           20 :             CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
    3990              :             !
    3991              :             IF (gradient_f) THEN
    3992           20 :                CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
    3993           20 :                CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
    3994           20 :                CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
    3995           20 :                CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
    3996              :             END IF
    3997              : 
    3998           20 :             IF (tau_f) THEN
    3999            0 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
    4000            0 :                CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
    4001            0 :                CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
    4002            0 :                CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
    4003            0 :                CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
    4004              :             END IF
    4005              : 
    4006              :             ! NLCC: prepare rho and drho of the core charge for this KIND
    4007           20 :             donlcc = .FALSE.
    4008           20 :             IF (nlcc) THEN
    4009            0 :                NULLIFY (rho_nlcc)
    4010            0 :                rho_nlcc => my_kind_set(ikind)%nlcc_pot
    4011            0 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
    4012              :             END IF
    4013              : 
    4014              :             ! Distribute the atoms of this kind
    4015              : 
    4016           20 :             num_pe = para_env%num_pe
    4017           20 :             bo = get_limit(natom, para_env%num_pe, para_env%mepos)
    4018              : 
    4019           35 :             DO iat = bo(1), bo(2)
    4020           15 :                iatom = atom_list(iat)
    4021              : 
    4022           15 :                my_rho_atom_set(iatom)%exc_h = 0.0_dp
    4023           15 :                my_rho_atom_set(iatom)%exc_s = 0.0_dp
    4024              : 
    4025           15 :                rho_atom => my_rho_atom_set(iatom)
    4026        76545 :                rho_h = 0.0_dp
    4027        76545 :                rho_s = 0.0_dp
    4028              :                IF (gradient_f) THEN
    4029           15 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
    4030              :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
    4031              :                                     rho_rad_s=r_s, drho_rad_h=dr_h, &
    4032              :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
    4033           15 :                                     rho_rad_s_d=r_s_d)
    4034       376545 :                   drho_h = 0.0_dp
    4035       376545 :                   drho_s = 0.0_dp
    4036              :                ELSE
    4037              :                   NULLIFY (r_h, r_s)
    4038              :                   CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
    4039              :                   rho_d = 0.0_dp
    4040              :                END IF
    4041           15 :                IF (tau_f) THEN
    4042              :                   !compute tau on the grid all at once
    4043            0 :                   CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
    4044              :                ELSE
    4045           15 :                   tau_d = 0.0_dp
    4046              :                END IF
    4047              : 
    4048          765 :                DO ir = 1, nr
    4049              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
    4050              :                                         ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
    4051          750 :                                         r_h_d, r_s_d, drho_h, drho_s)
    4052          765 :                   IF (donlcc) THEN
    4053              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
    4054            0 :                                         ir, rho_nlcc(:, 1), rho_h, rho_s, rho_nlcc(:, 2), drho_h, drho_s)
    4055              :                   END IF
    4056              :                END DO
    4057          765 :                DO ir = 1, nr
    4058          765 :                   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              :                   ELSE IF (gradient_f) THEN
    4062          750 :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
    4063          750 :                      CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
    4064              :                   ELSE
    4065              :                      CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
    4066              :                      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              :                !-------------------!
    4071              :                ! hard atom density !
    4072              :                !-------------------!
    4073           15 :                CALL xc_dset_zero_all(deriv_set)
    4074              :                CALL vxc_of_r_epr(xc_fun_section, rho_set_h, deriv_set, needs, weight_h, &
    4075           15 :                                  lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h)
    4076           15 :                rho_atom%exc_h = rho_atom%exc_h + exc_h
    4077              : 
    4078              :                !-------------------!
    4079              :                ! soft atom density !
    4080              :                !-------------------!
    4081           15 :                CALL xc_dset_zero_all(deriv_set)
    4082              :                CALL vxc_of_r_epr(xc_fun_section, rho_set_s, deriv_set, needs, weight_s, &
    4083           15 :                                  lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s)
    4084           15 :                rho_atom%exc_s = rho_atom%exc_s + exc_s
    4085              : 
    4086           45 :                DO ispin = 1, nspins
    4087          135 :                   DO idir = 1, 3
    4088         4620 :                      DO ir = 1, nr
    4089       229590 :                         DO ia = 1, na
    4090              :                            gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) = &
    4091              :                               gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) &
    4092       225000 :                               + vxg_h(idir, ia, ir, ispin)
    4093              :                            gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) = &
    4094              :                               gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) &
    4095       229500 :                               + vxg_s(idir, ia, ir, ispin)
    4096              :                         END DO ! ia
    4097              :                      END DO ! ir
    4098              :                   END DO ! idir
    4099              :                END DO ! ispin
    4100              : 
    4101              :                ! Add contributions to the exc energy
    4102              : 
    4103           15 :                exc1 = exc1 + rho_atom%exc_h - rho_atom%exc_s
    4104              : 
    4105              :                ! Integration to get the matrix elements relative to the vxc_atom
    4106              :                ! here the products with the primitives is done: gaVxcgb
    4107              :                ! internal transformation to get the integral in cartesian Gaussians
    4108              : 
    4109           15 :                NULLIFY (int_hh, int_ss)
    4110           15 :                CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
    4111              :                IF (gradient_f) THEN
    4112              :                   CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
    4113           15 :                                   grid_atom, basis_1c, harmonics, nspins)
    4114              :                ELSE
    4115              :                   CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
    4116              :                                     grid_atom, basis_1c, harmonics, nspins)
    4117              :                END IF
    4118           15 :                IF (tau_f) THEN
    4119              :                   CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
    4120            0 :                                   tau_basis_cache, nspins)
    4121              :                END IF
    4122           35 :                NULLIFY (r_h, r_s, dr_h, dr_s)
    4123              :             END DO ! iat
    4124              : 
    4125           20 :             IF (tau_f) CALL release_tau_basis_cache(tau_basis_cache)
    4126              : 
    4127              :             ! Release the xc structure used to store the xc derivatives
    4128           20 :             CALL xc_dset_release(deriv_set)
    4129           20 :             CALL xc_rho_set_release(rho_set_h)
    4130           70 :             CALL xc_rho_set_release(rho_set_s)
    4131              :          END DO ! ikind
    4132              : 
    4133           10 :          CALL para_env%sum(exc1)
    4134              : 
    4135           10 :          IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
    4136           10 :          IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
    4137           10 :          IF (ASSOCIATED(vxc_h)) DEALLOCATE (vxc_h)
    4138           10 :          IF (ASSOCIATED(vxc_s)) DEALLOCATE (vxc_s)
    4139              : 
    4140              :          IF (gradient_f) THEN
    4141           10 :             IF (ASSOCIATED(drho_h)) DEALLOCATE (drho_h)
    4142           10 :             IF (ASSOCIATED(drho_s)) DEALLOCATE (drho_s)
    4143           10 :             IF (ASSOCIATED(vxg_h)) DEALLOCATE (vxg_h)
    4144           10 :             IF (ASSOCIATED(vxg_s)) DEALLOCATE (vxg_s)
    4145              :          END IF
    4146              : 
    4147           10 :          IF (tau_f) THEN
    4148            0 :             IF (ASSOCIATED(tau_h)) DEALLOCATE (tau_h)
    4149            0 :             IF (ASSOCIATED(tau_s)) DEALLOCATE (tau_s)
    4150            0 :             IF (ASSOCIATED(vtau_h)) DEALLOCATE (vtau_h)
    4151            0 :             IF (ASSOCIATED(vtau_s)) DEALLOCATE (vtau_s)
    4152              :          END IF
    4153              : 
    4154              :       END IF !xc_none
    4155              : 
    4156           10 :       CALL timestop(handle)
    4157              : 
    4158          380 :    END SUBROUTINE calculate_vxc_atom_epr
    4159              : 
    4160            0 : END MODULE qs_vxc_atom
        

Generated by: LCOV version 2.0-1