LCOV - code coverage report
Current view: top level - src - qs_collocate_density.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:ccc2433) Lines: 825 1071 77.0 %
Date: 2024-04-25 07:09:54 Functions: 15 16 93.8 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Calculate the plane wave density by collocating the primitive Gaussian
      10             : !>      functions (pgf).
      11             : !> \par History
      12             : !>      - rewrote collocate for increased accuracy and speed
      13             : !>      - introduced the PGI hack for increased speed with that compiler
      14             : !>        (22.02.02)
      15             : !>      - Added Multiple Grid feature
      16             : !>      - new way to get over the grid (01.03.02)
      17             : !>      - removed timing calls since they were getting expensive
      18             : !>      - Updated with the new QS data structures (09.04.02,MK)
      19             : !>      - introduction of the real space grid type ( prelim. version JVdV 05.02)
      20             : !>      - parallel FFT (JGH 22.05.02)
      21             : !>      - multigrid arrays independent from density (JGH 30.08.02)
      22             : !>      - old density stored in g space (JGH 30.08.02)
      23             : !>      - distributed real space code (JGH 17.07.03)
      24             : !>      - refactoring and new loop ordering (JGH 23.11.03)
      25             : !>      - OpenMP parallelization (JGH 03.12.03)
      26             : !>      - Modified to compute tau (Joost 12.03)
      27             : !>      - removed the incremental density rebuild (Joost 01.04)
      28             : !>      - introduced realspace multigridding (Joost 02.04)
      29             : !>      - introduced map_consistent (Joost 02.04)
      30             : !>      - Addition of the subroutine calculate_atomic_charge_density (TdK, 08.05)
      31             : !>      - rewrite of the collocate/integrate kernels (Joost VandeVondele, 03.07)
      32             : !>      - Extended by the derivatives for DFPT [Sandra Luber, Edward Ditler, 2021]
      33             : !> \author Matthias Krack (03.04.2001)
      34             : !>      1) Joost VandeVondele (01.2002)
      35             : !>      Thomas D. Kuehne (04.08.2005)
      36             : !>      Ole Schuett (2020)
      37             : ! **************************************************************************************************
      38             : MODULE qs_collocate_density
      39             :    USE admm_types, ONLY: get_admm_env
      40             :    USE ao_util, ONLY: exp_radius_very_extended
      41             :    USE atomic_kind_types, ONLY: atomic_kind_type, &
      42             :                                 get_atomic_kind, &
      43             :                                 get_atomic_kind_set
      44             :    USE basis_set_types, ONLY: get_gto_basis_set, &
      45             :                               gto_basis_set_type
      46             :    USE cell_types, ONLY: cell_type, &
      47             :                          pbc
      48             :    USE cp_control_types, ONLY: dft_control_type
      49             :    USE cp_dbcsr_operations, ONLY: dbcsr_deallocate_matrix_set
      50             :    USE cp_fm_types, ONLY: cp_fm_get_element, &
      51             :                           cp_fm_get_info, &
      52             :                           cp_fm_type
      53             :    USE dbcsr_api, ONLY: dbcsr_copy, &
      54             :                         dbcsr_get_block_p, &
      55             :                         dbcsr_p_type, &
      56             :                         dbcsr_type
      57             :    USE external_potential_types, ONLY: get_potential, &
      58             :                                        gth_potential_type
      59             :    USE gaussian_gridlevels, ONLY: gaussian_gridlevel, &
      60             :                                   gridlevel_info_type
      61             :    USE grid_api, ONLY: &
      62             :       GRID_FUNC_AB, GRID_FUNC_CORE_X, GRID_FUNC_CORE_Y, GRID_FUNC_CORE_Z, GRID_FUNC_DAB_X, &
      63             :       GRID_FUNC_DAB_Y, GRID_FUNC_DAB_Z, GRID_FUNC_DABpADB_X, GRID_FUNC_DABpADB_Y, &
      64             :       GRID_FUNC_DABpADB_Z, GRID_FUNC_DADB, GRID_FUNC_DX, GRID_FUNC_DXDX, GRID_FUNC_DXDY, &
      65             :       GRID_FUNC_DY, GRID_FUNC_DYDY, GRID_FUNC_DYDZ, GRID_FUNC_DZ, GRID_FUNC_DZDX, &
      66             :       GRID_FUNC_DZDZ, collocate_pgf_product, grid_collocate_task_list
      67             :    USE input_constants, ONLY: &
      68             :       orb_dx2, orb_dxy, orb_dy2, orb_dyz, orb_dz2, orb_dzx, orb_px, orb_py, orb_pz, orb_s
      69             :    USE kinds, ONLY: default_string_length, &
      70             :                     dp
      71             :    USE lri_environment_types, ONLY: lri_kind_type
      72             :    USE memory_utilities, ONLY: reallocate
      73             :    USE message_passing, ONLY: mp_comm_type
      74             :    USE orbital_pointers, ONLY: coset, &
      75             :                                ncoset
      76             :    USE particle_types, ONLY: particle_type
      77             :    USE pw_env_types, ONLY: pw_env_get, &
      78             :                            pw_env_type
      79             :    USE pw_methods, ONLY: pw_axpy, &
      80             :                          pw_integrate_function, &
      81             :                          pw_transfer, &
      82             :                          pw_zero
      83             :    USE pw_pool_types, ONLY: pw_pool_p_type, &
      84             :                             pw_pool_type, &
      85             :                             pw_pools_create_pws, &
      86             :                             pw_pools_give_back_pws
      87             :    USE pw_types, ONLY: &
      88             :       pw_r3d_rs_type, &
      89             :       pw_c1d_gs_type, pw_r3d_rs_type
      90             :    USE qs_environment_types, ONLY: get_qs_env, &
      91             :                                    qs_environment_type
      92             :    USE qs_kind_types, ONLY: get_qs_kind, &
      93             :                             get_qs_kind_set, &
      94             :                             qs_kind_type
      95             :    USE qs_ks_types, ONLY: get_ks_env, &
      96             :                           qs_ks_env_type
      97             :    USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
      98             :    USE realspace_grid_types, ONLY: map_gaussian_here, &
      99             :                                    realspace_grid_desc_p_type, &
     100             :                                    realspace_grid_type, &
     101             :                                    rs_grid_zero, &
     102             :                                    transfer_rs2pw
     103             :    USE rs_pw_interface, ONLY: density_rs2pw
     104             :    USE task_list_methods, ONLY: rs_copy_to_buffer, &
     105             :                                 rs_distribute_matrix, &
     106             :                                 rs_scatter_matrices
     107             :    USE task_list_types, ONLY: atom_pair_type, &
     108             :                               task_list_type, &
     109             :                               task_type
     110             : 
     111             : !$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
     112             : 
     113             : #include "./base/base_uses.f90"
     114             : 
     115             :    IMPLICIT NONE
     116             : 
     117             :    PRIVATE
     118             : 
     119             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_collocate_density'
     120             : ! *** Public subroutines ***
     121             : 
     122             :    PUBLIC :: calculate_ppl_grid, &
     123             :              calculate_rho_core, &
     124             :              calculate_lri_rho_elec, &
     125             :              calculate_rho_single_gaussian, &
     126             :              calculate_rho_metal, &
     127             :              calculate_rho_resp_single, &
     128             :              calculate_rho_resp_all, &
     129             :              calculate_rho_elec, &
     130             :              calculate_drho_elec, &
     131             :              calculate_wavefunction, &
     132             :              calculate_rho_nlcc, &
     133             :              calculate_drho_elec_dR, &
     134             :              calculate_drho_core, &
     135             :              collocate_single_gaussian
     136             : 
     137             :    INTERFACE calculate_rho_core
     138             :       MODULE PROCEDURE calculate_rho_core_r3d_rs
     139             :       MODULE PROCEDURE calculate_rho_core_c1d_gs
     140             :    END INTERFACE
     141             : 
     142             :    INTERFACE calculate_rho_resp_all
     143             :       MODULE PROCEDURE calculate_rho_resp_all_r3d_rs, calculate_rho_resp_all_c1d_gs
     144             :    END INTERFACE
     145             : 
     146             : CONTAINS
     147             : 
     148             : ! **************************************************************************************************
     149             : !> \brief computes the density of the non-linear core correction on the grid
     150             : !> \param rho_nlcc ...
     151             : !> \param qs_env ...
     152             : ! **************************************************************************************************
     153          36 :    SUBROUTINE calculate_rho_nlcc(rho_nlcc, qs_env)
     154             : 
     155             :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                       :: rho_nlcc
     156             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     157             : 
     158             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_nlcc'
     159             : 
     160             :       INTEGER                                            :: atom_a, handle, iatom, iexp_nlcc, ikind, &
     161             :                                                             ithread, j, n, natom, nc, nexp_nlcc, &
     162             :                                                             ni, npme, nthread, subpatch_pattern
     163          36 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores, nct_nlcc
     164             :       LOGICAL                                            :: nlcc
     165             :       REAL(KIND=dp)                                      :: alpha, eps_rho_rspace, radius
     166             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
     167          36 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: alpha_nlcc
     168          36 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: cval_nlcc, pab
     169          36 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     170             :       TYPE(cell_type), POINTER                           :: cell
     171             :       TYPE(dft_control_type), POINTER                    :: dft_control
     172             :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     173          36 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     174             :       TYPE(pw_env_type), POINTER                         :: pw_env
     175             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     176          36 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     177             :       TYPE(realspace_grid_type), POINTER                 :: rs_rho
     178             : 
     179          36 :       CALL timeset(routineN, handle)
     180             : 
     181          36 :       NULLIFY (cell, dft_control, pab, particle_set, atomic_kind_set, &
     182          36 :                qs_kind_set, atom_list, pw_env, rs_rho, auxbas_pw_pool, cores)
     183             : 
     184             :       CALL get_qs_env(qs_env=qs_env, &
     185             :                       atomic_kind_set=atomic_kind_set, &
     186             :                       qs_kind_set=qs_kind_set, &
     187             :                       cell=cell, &
     188             :                       dft_control=dft_control, &
     189             :                       particle_set=particle_set, &
     190          36 :                       pw_env=pw_env)
     191             :       CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
     192          36 :                       auxbas_pw_pool=auxbas_pw_pool)
     193             :       ! be careful in parallel nsmax is chosen with multigrid in mind!
     194          36 :       CALL rs_grid_zero(rs_rho)
     195             : 
     196          36 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     197             : 
     198          92 :       DO ikind = 1, SIZE(atomic_kind_set)
     199          56 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
     200          56 :          CALL get_qs_kind(qs_kind_set(ikind), gth_potential=gth_potential)
     201             : 
     202          56 :          IF (.NOT. ASSOCIATED(gth_potential)) CYCLE
     203             :          CALL get_potential(potential=gth_potential, nlcc_present=nlcc, nexp_nlcc=nexp_nlcc, &
     204          56 :                             alpha_nlcc=alpha_nlcc, nct_nlcc=nct_nlcc, cval_nlcc=cval_nlcc)
     205             : 
     206          56 :          IF (.NOT. nlcc) CYCLE
     207             : 
     208         256 :          DO iexp_nlcc = 1, nexp_nlcc
     209             : 
     210          54 :             alpha = alpha_nlcc(iexp_nlcc)
     211          54 :             nc = nct_nlcc(iexp_nlcc)
     212             : 
     213          54 :             ni = ncoset(2*nc - 2)
     214         162 :             ALLOCATE (pab(ni, 1))
     215         306 :             pab = 0._dp
     216             : 
     217          54 :             nthread = 1
     218          54 :             ithread = 0
     219             : 
     220          54 :             CALL reallocate(cores, 1, natom)
     221          54 :             npme = 0
     222         232 :             cores = 0
     223             : 
     224             :             ! prepare core function
     225         124 :             DO j = 1, nc
     226          54 :                SELECT CASE (j)
     227             :                CASE (1)
     228          54 :                   pab(1, 1) = cval_nlcc(1, iexp_nlcc)
     229             :                CASE (2)
     230          16 :                   n = coset(2, 0, 0)
     231          16 :                   pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
     232          16 :                   n = coset(0, 2, 0)
     233          16 :                   pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
     234          16 :                   n = coset(0, 0, 2)
     235          16 :                   pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
     236             :                CASE (3)
     237           0 :                   n = coset(4, 0, 0)
     238           0 :                   pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
     239           0 :                   n = coset(0, 4, 0)
     240           0 :                   pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
     241           0 :                   n = coset(0, 0, 4)
     242           0 :                   pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
     243           0 :                   n = coset(2, 2, 0)
     244           0 :                   pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
     245           0 :                   n = coset(2, 0, 2)
     246           0 :                   pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
     247           0 :                   n = coset(0, 2, 2)
     248           0 :                   pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
     249             :                CASE (4)
     250           0 :                   n = coset(6, 0, 0)
     251           0 :                   pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
     252           0 :                   n = coset(0, 6, 0)
     253           0 :                   pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
     254           0 :                   n = coset(0, 0, 6)
     255           0 :                   pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
     256           0 :                   n = coset(4, 2, 0)
     257           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     258           0 :                   n = coset(4, 0, 2)
     259           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     260           0 :                   n = coset(2, 4, 0)
     261           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     262           0 :                   n = coset(2, 0, 4)
     263           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     264           0 :                   n = coset(0, 4, 2)
     265           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     266           0 :                   n = coset(0, 2, 4)
     267           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     268           0 :                   n = coset(2, 2, 2)
     269           0 :                   pab(n, 1) = 6._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     270             :                CASE DEFAULT
     271          70 :                   CPABORT("")
     272             :                END SELECT
     273             :             END DO
     274          54 :             IF (dft_control%nspins == 2) pab = pab*0.5_dp
     275             : 
     276         232 :             DO iatom = 1, natom
     277         178 :                atom_a = atom_list(iatom)
     278         178 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
     279         232 :                IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
     280             :                   ! replicated realspace grid, split the atoms up between procs
     281         178 :                   IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
     282          89 :                      npme = npme + 1
     283          89 :                      cores(npme) = iatom
     284             :                   END IF
     285             :                ELSE
     286           0 :                   npme = npme + 1
     287           0 :                   cores(npme) = iatom
     288             :                END IF
     289             :             END DO
     290             : 
     291         143 :             DO j = 1, npme
     292             : 
     293          89 :                iatom = cores(j)
     294          89 :                atom_a = atom_list(iatom)
     295          89 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
     296          89 :                subpatch_pattern = 0
     297          89 :                ni = 2*nc - 2
     298             :                radius = exp_radius_very_extended(la_min=0, la_max=ni, lb_min=0, lb_max=0, &
     299             :                                                  ra=ra, rb=ra, rp=ra, &
     300             :                                                  zetp=1/(2*alpha**2), eps=eps_rho_rspace, &
     301             :                                                  pab=pab, o1=0, o2=0, &  ! without map_consistent
     302          89 :                                                  prefactor=1.0_dp, cutoff=0.0_dp)
     303             : 
     304             :                CALL collocate_pgf_product(ni, 1/(2*alpha**2), 0, 0, 0.0_dp, 0, ra, &
     305             :                                           (/0.0_dp, 0.0_dp, 0.0_dp/), 1.0_dp, pab, 0, 0, rs_rho, &
     306             :                                           ga_gb_function=GRID_FUNC_AB, radius=radius, &
     307         143 :                                           use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
     308             : 
     309             :             END DO
     310             : 
     311         110 :             DEALLOCATE (pab)
     312             : 
     313             :          END DO
     314             : 
     315             :       END DO
     316             : 
     317          36 :       IF (ASSOCIATED(cores)) THEN
     318          36 :          DEALLOCATE (cores)
     319             :       END IF
     320             : 
     321          36 :       CALL transfer_rs2pw(rs_rho, rho_nlcc)
     322             : 
     323          36 :       CALL timestop(handle)
     324             : 
     325          36 :    END SUBROUTINE calculate_rho_nlcc
     326             : 
     327             : ! **************************************************************************************************
     328             : !> \brief computes the local pseudopotential (without erf term) on the grid
     329             : !> \param vppl ...
     330             : !> \param qs_env ...
     331             : ! **************************************************************************************************
     332          12 :    SUBROUTINE calculate_ppl_grid(vppl, qs_env)
     333             : 
     334             :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                       :: vppl
     335             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     336             : 
     337             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_ppl_grid'
     338             : 
     339             :       INTEGER                                            :: atom_a, handle, iatom, ikind, ithread, &
     340             :                                                             j, lppl, n, natom, ni, npme, nthread, &
     341             :                                                             subpatch_pattern
     342          12 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores
     343             :       REAL(KIND=dp)                                      :: alpha, eps_rho_rspace, radius
     344             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
     345          12 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: cexp_ppl
     346          12 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
     347          12 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     348             :       TYPE(cell_type), POINTER                           :: cell
     349             :       TYPE(dft_control_type), POINTER                    :: dft_control
     350             :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     351          12 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     352             :       TYPE(pw_env_type), POINTER                         :: pw_env
     353             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     354          12 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     355             :       TYPE(realspace_grid_type), POINTER                 :: rs_rho
     356             : 
     357          12 :       CALL timeset(routineN, handle)
     358             : 
     359          12 :       NULLIFY (cell, dft_control, pab, atomic_kind_set, qs_kind_set, particle_set, &
     360          12 :                atom_list, pw_env, rs_rho, auxbas_pw_pool, cores)
     361             : 
     362             :       CALL get_qs_env(qs_env=qs_env, &
     363             :                       atomic_kind_set=atomic_kind_set, &
     364             :                       qs_kind_set=qs_kind_set, &
     365             :                       cell=cell, &
     366             :                       dft_control=dft_control, &
     367             :                       particle_set=particle_set, &
     368          12 :                       pw_env=pw_env)
     369             :       CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
     370          12 :                       auxbas_pw_pool=auxbas_pw_pool)
     371             :       ! be careful in parallel nsmax is chosen with multigrid in mind!
     372          12 :       CALL rs_grid_zero(rs_rho)
     373             : 
     374          12 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     375             : 
     376          28 :       DO ikind = 1, SIZE(atomic_kind_set)
     377          16 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
     378          16 :          CALL get_qs_kind(qs_kind_set(ikind), gth_potential=gth_potential)
     379             : 
     380          16 :          IF (.NOT. ASSOCIATED(gth_potential)) CYCLE
     381          16 :          CALL get_potential(potential=gth_potential, alpha_ppl=alpha, nexp_ppl=lppl, cexp_ppl=cexp_ppl)
     382             : 
     383          16 :          IF (lppl <= 0) CYCLE
     384             : 
     385          16 :          ni = ncoset(2*lppl - 2)
     386          48 :          ALLOCATE (pab(ni, 1))
     387         192 :          pab = 0._dp
     388             : 
     389          16 :          nthread = 1
     390          16 :          ithread = 0
     391             : 
     392          16 :          CALL reallocate(cores, 1, natom)
     393          16 :          npme = 0
     394          60 :          cores = 0
     395             : 
     396             :          ! prepare core function
     397          48 :          DO j = 1, lppl
     398          16 :             SELECT CASE (j)
     399             :             CASE (1)
     400          16 :                pab(1, 1) = cexp_ppl(1)
     401             :             CASE (2)
     402          16 :                n = coset(2, 0, 0)
     403          16 :                pab(n, 1) = cexp_ppl(2)
     404          16 :                n = coset(0, 2, 0)
     405          16 :                pab(n, 1) = cexp_ppl(2)
     406          16 :                n = coset(0, 0, 2)
     407          16 :                pab(n, 1) = cexp_ppl(2)
     408             :             CASE (3)
     409           0 :                n = coset(4, 0, 0)
     410           0 :                pab(n, 1) = cexp_ppl(3)
     411           0 :                n = coset(0, 4, 0)
     412           0 :                pab(n, 1) = cexp_ppl(3)
     413           0 :                n = coset(0, 0, 4)
     414           0 :                pab(n, 1) = cexp_ppl(3)
     415           0 :                n = coset(2, 2, 0)
     416           0 :                pab(n, 1) = 2._dp*cexp_ppl(3)
     417           0 :                n = coset(2, 0, 2)
     418           0 :                pab(n, 1) = 2._dp*cexp_ppl(3)
     419           0 :                n = coset(0, 2, 2)
     420           0 :                pab(n, 1) = 2._dp*cexp_ppl(3)
     421             :             CASE (4)
     422           0 :                n = coset(6, 0, 0)
     423           0 :                pab(n, 1) = cexp_ppl(4)
     424           0 :                n = coset(0, 6, 0)
     425           0 :                pab(n, 1) = cexp_ppl(4)
     426           0 :                n = coset(0, 0, 6)
     427           0 :                pab(n, 1) = cexp_ppl(4)
     428           0 :                n = coset(4, 2, 0)
     429           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     430           0 :                n = coset(4, 0, 2)
     431           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     432           0 :                n = coset(2, 4, 0)
     433           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     434           0 :                n = coset(2, 0, 4)
     435           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     436           0 :                n = coset(0, 4, 2)
     437           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     438           0 :                n = coset(0, 2, 4)
     439           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     440           0 :                n = coset(2, 2, 2)
     441           0 :                pab(n, 1) = 6._dp*cexp_ppl(4)
     442             :             CASE DEFAULT
     443          32 :                CPABORT("")
     444             :             END SELECT
     445             :          END DO
     446             : 
     447          60 :          DO iatom = 1, natom
     448          44 :             atom_a = atom_list(iatom)
     449          44 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
     450          60 :             IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
     451             :                ! replicated realspace grid, split the atoms up between procs
     452          44 :                IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
     453          22 :                   npme = npme + 1
     454          22 :                   cores(npme) = iatom
     455             :                END IF
     456             :             ELSE
     457           0 :                npme = npme + 1
     458           0 :                cores(npme) = iatom
     459             :             END IF
     460             :          END DO
     461             : 
     462          16 :          IF (npme .GT. 0) THEN
     463          36 :             DO j = 1, npme
     464             : 
     465          22 :                iatom = cores(j)
     466          22 :                atom_a = atom_list(iatom)
     467          22 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
     468          22 :                subpatch_pattern = 0
     469          22 :                ni = 2*lppl - 2
     470             : 
     471             :                radius = exp_radius_very_extended(la_min=0, la_max=ni, &
     472             :                                                  lb_min=0, lb_max=0, &
     473             :                                                  ra=ra, rb=ra, rp=ra, &
     474             :                                                  zetp=alpha, eps=eps_rho_rspace, &
     475             :                                                  pab=pab, o1=0, o2=0, &  ! without map_consistent
     476          22 :                                                  prefactor=1.0_dp, cutoff=0.0_dp)
     477             : 
     478             :                CALL collocate_pgf_product(ni, alpha, 0, 0, 0.0_dp, 0, ra, &
     479             :                                           (/0.0_dp, 0.0_dp, 0.0_dp/), 1.0_dp, pab, 0, 0, rs_rho, &
     480             :                                           radius=radius, ga_gb_function=GRID_FUNC_AB, &
     481          36 :                                           use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
     482             : 
     483             :             END DO
     484             :          END IF
     485             : 
     486          60 :          DEALLOCATE (pab)
     487             : 
     488             :       END DO
     489             : 
     490          12 :       IF (ASSOCIATED(cores)) THEN
     491          12 :          DEALLOCATE (cores)
     492             :       END IF
     493             : 
     494          12 :       CALL transfer_rs2pw(rs_rho, vppl)
     495             : 
     496          12 :       CALL timestop(handle)
     497             : 
     498          12 :    END SUBROUTINE calculate_ppl_grid
     499             : 
     500             : ! **************************************************************************************************
     501             : !> \brief Collocates the fitted lri density on a grid.
     502             : !> \param lri_rho_g ...
     503             : !> \param lri_rho_r ...
     504             : !> \param qs_env ...
     505             : !> \param lri_coef ...
     506             : !> \param total_rho ...
     507             : !> \param basis_type ...
     508             : !> \param exact_1c_terms ...
     509             : !> \param pmat replicated block diagonal density matrix (optional)
     510             : !> \param atomlist list of atoms to be included (optional)
     511             : !> \par History
     512             : !>      04.2013
     513             : !> \author Dorothea Golze
     514             : ! **************************************************************************************************
     515         930 :    SUBROUTINE calculate_lri_rho_elec(lri_rho_g, lri_rho_r, qs_env, &
     516         930 :                                      lri_coef, total_rho, basis_type, exact_1c_terms, pmat, atomlist)
     517             : 
     518             :       TYPE(pw_c1d_gs_type), INTENT(INOUT) :: lri_rho_g
     519             :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                       ::  lri_rho_r
     520             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     521             :       TYPE(lri_kind_type), DIMENSION(:), POINTER         :: lri_coef
     522             :       REAL(KIND=dp), INTENT(OUT)                         :: total_rho
     523             :       CHARACTER(len=*), INTENT(IN)                       :: basis_type
     524             :       LOGICAL, INTENT(IN)                                :: exact_1c_terms
     525             :       TYPE(dbcsr_type), OPTIONAL                         :: pmat
     526             :       INTEGER, DIMENSION(:), OPTIONAL                    :: atomlist
     527             : 
     528             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_lri_rho_elec'
     529             : 
     530             :       INTEGER :: atom_a, group_size, handle, iatom, igrid_level, ikind, ipgf, iset, jpgf, jset, &
     531             :                  m1, maxco, maxsgf_set, my_pos, na1, natom, nb1, ncoa, ncob, nseta, offset, sgfa, sgfb
     532         930 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, la_max, la_min, npgfa, nsgfa
     533         930 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa
     534             :       LOGICAL                                            :: found
     535         930 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: map_it
     536         930 :       LOGICAL, ALLOCATABLE, DIMENSION(:, :)              :: map_it2
     537             :       REAL(KIND=dp)                                      :: eps_rho_rspace, radius, zetp
     538             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
     539         930 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: aci
     540         930 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: p_block, pab, sphi_a, work, zeta
     541         930 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     542             :       TYPE(cell_type), POINTER                           :: cell
     543             :       TYPE(dft_control_type), POINTER                    :: dft_control
     544             :       TYPE(gridlevel_info_type), POINTER                 :: gridlevel_info
     545             :       TYPE(gto_basis_set_type), POINTER                  :: lri_basis_set, orb_basis_set
     546         930 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     547             :       TYPE(pw_env_type), POINTER                         :: pw_env
     548         930 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
     549         930 :       TYPE(pw_c1d_gs_type), ALLOCATABLE, DIMENSION(:) :: mgrid_gspace
     550         930 :       TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:)           ::  mgrid_rspace
     551         930 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     552         930 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_rho
     553             :       TYPE(realspace_grid_type), POINTER                 :: rs_grid
     554             : 
     555         930 :       NULLIFY (aci, atomic_kind_set, qs_kind_set, atom_list, cell, &
     556         930 :                dft_control, first_sgfa, gridlevel_info, la_max, &
     557         930 :                la_min, lri_basis_set, npgfa, nsgfa, &
     558         930 :                pab, particle_set, pw_env, pw_pools, rs_grid, rs_rho, sphi_a, &
     559         930 :                work, zeta)
     560             : 
     561         930 :       CALL timeset(routineN, handle)
     562             : 
     563         930 :       IF (exact_1c_terms) THEN
     564          48 :          CPASSERT(PRESENT(pmat))
     565             :       END IF
     566             : 
     567             :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, &
     568             :                       atomic_kind_set=atomic_kind_set, &
     569             :                       cell=cell, particle_set=particle_set, &
     570             :                       pw_env=pw_env, &
     571         930 :                       dft_control=dft_control)
     572             : 
     573         930 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     574         930 :       gridlevel_info => pw_env%gridlevel_info
     575             : 
     576             :       ! *** set up the pw multi-grids *** !
     577         930 :       CPASSERT(ASSOCIATED(pw_env))
     578         930 :       CALL pw_env_get(pw_env=pw_env, rs_grids=rs_rho, pw_pools=pw_pools)
     579             : 
     580         930 :       CALL pw_pools_create_pws(pw_pools, mgrid_rspace)
     581             : 
     582         930 :       CALL pw_pools_create_pws(pw_pools, mgrid_gspace)
     583             : 
     584             :       ! *** set up the rs multi-grids *** !
     585        4602 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
     586        4602 :          CALL rs_grid_zero(rs_rho(igrid_level))
     587             :       END DO
     588             : 
     589             :       !take maxco from the LRI basis set!
     590             :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
     591         930 :                            maxco=maxco, basis_type=basis_type)
     592             : 
     593        2790 :       ALLOCATE (pab(maxco, 1))
     594         930 :       offset = 0
     595         930 :       my_pos = mgrid_rspace(1)%pw_grid%para%my_pos
     596         930 :       group_size = mgrid_rspace(1)%pw_grid%para%group_size
     597             : 
     598        2788 :       DO ikind = 1, SIZE(atomic_kind_set)
     599             : 
     600        1858 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
     601        1858 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=lri_basis_set, basis_type=basis_type)
     602             : 
     603             :          !Take the lri basis set here!
     604             :          CALL get_gto_basis_set(gto_basis_set=lri_basis_set, lmax=la_max, &
     605             :                                 lmin=la_min, zet=zeta, nset=nseta, npgf=npgfa, &
     606        1858 :                                 sphi=sphi_a, first_sgf=first_sgfa, nsgf_set=nsgfa)
     607             : 
     608        8138 :          DO iatom = 1, natom
     609        3492 :             atom_a = atom_list(iatom)
     610        3492 :             IF (PRESENT(ATOMLIST)) THEN
     611         500 :                IF (atomlist(atom_a) == 0) CYCLE
     612             :             END IF
     613        3292 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
     614        3292 :             aci => lri_coef(ikind)%acoef(iatom, :)
     615             : 
     616       49116 :             m1 = MAXVAL(npgfa(1:nseta))
     617        9876 :             ALLOCATE (map_it(m1))
     618       49116 :             DO iset = 1, nseta
     619             :                ! collocate this set locally?
     620       96512 :                map_it = .FALSE.
     621       96320 :                DO ipgf = 1, npgfa(iset)
     622       50496 :                   igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
     623       50496 :                   rs_grid => rs_rho(igrid_level)
     624       96320 :                   map_it(ipgf) = map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)
     625             :                END DO
     626       45824 :                offset = offset + 1
     627             : 
     628       74364 :                IF (ANY(map_it(1:npgfa(iset)))) THEN
     629       22912 :                   sgfa = first_sgfa(1, iset)
     630       22912 :                   ncoa = npgfa(iset)*ncoset(la_max(iset))
     631       22912 :                   m1 = sgfa + nsgfa(iset) - 1
     632       68736 :                   ALLOCATE (work(nsgfa(iset), 1))
     633      384840 :                   work(1:nsgfa(iset), 1) = aci(sgfa:m1)
     634      674191 :                   pab = 0._dp
     635             : 
     636             :                   CALL dgemm("N", "N", ncoa, 1, nsgfa(iset), 1.0_dp, lri_basis_set%sphi(1, sgfa), &
     637             :                              SIZE(lri_basis_set%sphi, 1), work(1, 1), SIZE(work, 1), 0.0_dp, pab(1, 1), &
     638       22912 :                              SIZE(pab, 1))
     639             : 
     640       48160 :                   DO ipgf = 1, npgfa(iset)
     641       25248 :                      na1 = (ipgf - 1)*ncoset(la_max(iset))
     642       25248 :                      igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
     643       25248 :                      rs_grid => rs_rho(igrid_level)
     644       48160 :                      IF (map_it(ipgf)) THEN
     645             :                         radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
     646             :                                                           lb_min=0, lb_max=0, &
     647             :                                                           ra=ra, rb=ra, rp=ra, &
     648             :                                                           zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
     649       25248 :                                                           prefactor=1.0_dp, cutoff=1.0_dp)
     650             : 
     651             :                         CALL collocate_pgf_product(la_max=la_max(iset), &
     652             :                                                    zeta=zeta(ipgf, iset), &
     653             :                                                    la_min=la_min(iset), &
     654             :                                                    lb_max=0, zetb=0.0_dp, lb_min=0, &
     655             :                                                    ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
     656             :                                                    scale=1._dp, &
     657             :                                                    pab=pab, o1=na1, o2=0, &
     658             :                                                    rsgrid=rs_grid, &
     659             :                                                    radius=radius, &
     660       25248 :                                                    ga_gb_function=GRID_FUNC_AB)
     661             :                      END IF
     662             :                   END DO
     663       22912 :                   DEALLOCATE (work)
     664             :                END IF
     665             :             END DO
     666        5350 :             DEALLOCATE (map_it)
     667             :          END DO
     668             :       END DO
     669             : 
     670         930 :       DEALLOCATE (pab)
     671             : 
     672             :       ! process the one-center terms
     673         930 :       IF (exact_1c_terms) THEN
     674             :          ! find maximum numbers
     675          48 :          offset = 0
     676             :          CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
     677             :                               maxco=maxco, &
     678             :                               maxsgf_set=maxsgf_set, &
     679          48 :                               basis_type="ORB")
     680         336 :          ALLOCATE (pab(maxco, maxco), work(maxco, maxsgf_set))
     681             : 
     682         144 :          DO ikind = 1, SIZE(atomic_kind_set)
     683          96 :             CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
     684          96 :             CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type="ORB")
     685             :             CALL get_gto_basis_set(gto_basis_set=orb_basis_set, lmax=la_max, &
     686             :                                    lmin=la_min, zet=zeta, nset=nseta, npgf=npgfa, &
     687          96 :                                    sphi=sphi_a, first_sgf=first_sgfa, nsgf_set=nsgfa)
     688         528 :             DO iatom = 1, natom
     689         288 :                atom_a = atom_list(iatom)
     690         288 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
     691         288 :                CALL dbcsr_get_block_p(matrix=pmat, row=atom_a, col=atom_a, BLOCK=p_block, found=found)
     692         576 :                m1 = MAXVAL(npgfa(1:nseta))
     693        1152 :                ALLOCATE (map_it2(m1, m1))
     694         576 :                DO iset = 1, nseta
     695         864 :                   DO jset = 1, nseta
     696             :                      ! processor mappint
     697       16416 :                      map_it2 = .FALSE.
     698        2304 :                      DO ipgf = 1, npgfa(iset)
     699       16416 :                         DO jpgf = 1, npgfa(jset)
     700       14112 :                            zetp = zeta(ipgf, iset) + zeta(jpgf, jset)
     701       14112 :                            igrid_level = gaussian_gridlevel(gridlevel_info, zetp)
     702       14112 :                            rs_grid => rs_rho(igrid_level)
     703       16128 :                            map_it2(ipgf, jpgf) = map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)
     704             :                         END DO
     705             :                      END DO
     706         288 :                      offset = offset + 1
     707             :                      !
     708        8640 :                      IF (ANY(map_it2(1:npgfa(iset), 1:npgfa(jset)))) THEN
     709         144 :                         ncoa = npgfa(iset)*ncoset(la_max(iset))
     710         144 :                         sgfa = first_sgfa(1, iset)
     711         144 :                         ncob = npgfa(jset)*ncoset(la_max(jset))
     712         144 :                         sgfb = first_sgfa(1, jset)
     713             :                         ! decontract density block
     714             :                         CALL dgemm("N", "N", ncoa, nsgfa(jset), nsgfa(iset), &
     715             :                                    1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     716             :                                    p_block(sgfa, sgfb), SIZE(p_block, 1), &
     717         144 :                                    0.0_dp, work(1, 1), maxco)
     718             :                         CALL dgemm("N", "T", ncoa, ncob, nsgfa(jset), &
     719             :                                    1.0_dp, work(1, 1), maxco, &
     720             :                                    sphi_a(1, sgfb), SIZE(sphi_a, 1), &
     721         144 :                                    0.0_dp, pab(1, 1), maxco)
     722        1152 :                         DO ipgf = 1, npgfa(iset)
     723        8208 :                            DO jpgf = 1, npgfa(jset)
     724        7056 :                               zetp = zeta(ipgf, iset) + zeta(jpgf, jset)
     725        7056 :                               igrid_level = gaussian_gridlevel(gridlevel_info, zetp)
     726        7056 :                               rs_grid => rs_rho(igrid_level)
     727             : 
     728        7056 :                               na1 = (ipgf - 1)*ncoset(la_max(iset))
     729        7056 :                               nb1 = (jpgf - 1)*ncoset(la_max(jset))
     730             : 
     731        8064 :                               IF (map_it2(ipgf, jpgf)) THEN
     732             :                                  radius = exp_radius_very_extended(la_min=la_min(iset), &
     733             :                                                                    la_max=la_max(iset), &
     734             :                                                                    lb_min=la_min(jset), &
     735             :                                                                    lb_max=la_max(jset), &
     736             :                                                                    ra=ra, rb=ra, rp=ra, &
     737             :                                                                    zetp=zetp, eps=eps_rho_rspace, &
     738        7056 :                                                                    prefactor=1.0_dp, cutoff=1.0_dp)
     739             : 
     740             :                                  CALL collocate_pgf_product( &
     741             :                                     la_max(iset), zeta(ipgf, iset), la_min(iset), &
     742             :                                     la_max(jset), zeta(jpgf, jset), la_min(jset), &
     743             :                                     ra, (/0.0_dp, 0.0_dp, 0.0_dp/), 1.0_dp, pab, na1, nb1, &
     744             :                                     rs_grid, &
     745        7056 :                                     radius=radius, ga_gb_function=GRID_FUNC_AB)
     746             :                               END IF
     747             :                            END DO
     748             :                         END DO
     749             :                      END IF
     750             :                   END DO
     751             :                END DO
     752         672 :                DEALLOCATE (map_it2)
     753             :                !
     754             :             END DO
     755             :          END DO
     756          96 :          DEALLOCATE (pab, work)
     757             :       END IF
     758             : 
     759         930 :       CALL pw_zero(lri_rho_g)
     760         930 :       CALL pw_zero(lri_rho_r)
     761             : 
     762        4602 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
     763        3672 :          CALL pw_zero(mgrid_rspace(igrid_level))
     764             :          CALL transfer_rs2pw(rs=rs_rho(igrid_level), &
     765        4602 :                              pw=mgrid_rspace(igrid_level))
     766             :       END DO
     767             : 
     768        4602 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
     769        3672 :          CALL pw_zero(mgrid_gspace(igrid_level))
     770             :          CALL pw_transfer(mgrid_rspace(igrid_level), &
     771        3672 :                           mgrid_gspace(igrid_level))
     772        4602 :          CALL pw_axpy(mgrid_gspace(igrid_level), lri_rho_g)
     773             :       END DO
     774         930 :       CALL pw_transfer(lri_rho_g, lri_rho_r)
     775         930 :       total_rho = pw_integrate_function(lri_rho_r, isign=-1)
     776             : 
     777             :       ! *** give back the multi-grids *** !
     778         930 :       CALL pw_pools_give_back_pws(pw_pools, mgrid_gspace)
     779         930 :       CALL pw_pools_give_back_pws(pw_pools, mgrid_rspace)
     780             : 
     781         930 :       CALL timestop(handle)
     782             : 
     783        4650 :    END SUBROUTINE calculate_lri_rho_elec
     784             : 
     785             :    #:for kind in ["r3d_rs", "c1d_gs"]
     786             : ! **************************************************************************************************
     787             : !> \brief computes the density of the core charges on the grid
     788             : !> \param rho_core ...
     789             : !> \param total_rho ...
     790             : !> \param qs_env ...
     791             : !> \param calpha ...
     792             : !> \param ccore ...
     793             : !> \param only_nopaw ...
     794             : ! **************************************************************************************************
     795        9068 :       SUBROUTINE calculate_rho_core_${kind}$ (rho_core, total_rho, qs_env, calpha, ccore, only_nopaw)
     796             : 
     797             :          TYPE(pw_${kind}$_type), INTENT(INOUT)                       :: rho_core
     798             :          REAL(KIND=dp), INTENT(OUT)                         :: total_rho
     799             :          TYPE(qs_environment_type), POINTER                 :: qs_env
     800             :          REAL(KIND=dp), DIMENSION(:), OPTIONAL              :: calpha, ccore
     801             :          LOGICAL, INTENT(IN), OPTIONAL                      :: only_nopaw
     802             : 
     803             :          CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_core'
     804             : 
     805             :          INTEGER                                            :: atom_a, handle, iatom, ikind, ithread, &
     806             :                                                                j, natom, npme, nthread, &
     807             :                                                                subpatch_pattern
     808        9068 :          INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores
     809             :          LOGICAL                                            :: my_only_nopaw, paw_atom
     810             :          REAL(KIND=dp)                                      :: alpha, eps_rho_rspace, radius
     811             :          REAL(KIND=dp), DIMENSION(3)                        :: ra
     812        9068 :          REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
     813        9068 :          TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     814             :          TYPE(cell_type), POINTER                           :: cell
     815             :          TYPE(dft_control_type), POINTER                    :: dft_control
     816        9068 :          TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     817             :          TYPE(pw_env_type), POINTER                         :: pw_env
     818             :          TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     819             :          TYPE(pw_r3d_rs_type)                                      :: rhoc_r
     820        9068 :          TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     821             :          TYPE(realspace_grid_type), POINTER                 :: rs_rho
     822             : 
     823        9068 :          CALL timeset(routineN, handle)
     824        9068 :          NULLIFY (cell, dft_control, pab, atomic_kind_set, qs_kind_set, particle_set, &
     825        9068 :                   atom_list, pw_env, rs_rho, auxbas_pw_pool, cores)
     826        9068 :          ALLOCATE (pab(1, 1))
     827             : 
     828        9068 :          my_only_nopaw = .FALSE.
     829        9068 :          IF (PRESENT(only_nopaw)) my_only_nopaw = only_nopaw
     830        9068 :          IF (PRESENT(calpha)) THEN
     831           2 :             CPASSERT(PRESENT(ccore))
     832             :          END IF
     833             : 
     834             :          CALL get_qs_env(qs_env=qs_env, &
     835             :                          atomic_kind_set=atomic_kind_set, &
     836             :                          qs_kind_set=qs_kind_set, &
     837             :                          cell=cell, &
     838             :                          dft_control=dft_control, &
     839             :                          particle_set=particle_set, &
     840        9068 :                          pw_env=pw_env)
     841             :          CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
     842        9068 :                          auxbas_pw_pool=auxbas_pw_pool)
     843             :          ! be careful in parallel nsmax is chosen with multigrid in mind!
     844        9068 :          CALL rs_grid_zero(rs_rho)
     845             : 
     846        9068 :          eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     847             : 
     848       25173 :          DO ikind = 1, SIZE(atomic_kind_set)
     849       16105 :             CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
     850       16105 :             IF (PRESENT(calpha)) THEN
     851           4 :                alpha = calpha(ikind)
     852           4 :                pab(1, 1) = ccore(ikind)
     853             :             ELSE
     854             :                CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom, &
     855       16101 :                                 alpha_core_charge=alpha, ccore_charge=pab(1, 1))
     856             :             END IF
     857             : 
     858       16105 :             IF (my_only_nopaw .AND. paw_atom) CYCLE
     859       15951 :             IF (alpha == 0.0_dp .OR. pab(1, 1) == 0.0_dp) CYCLE
     860             : 
     861       15783 :             nthread = 1
     862       15783 :             ithread = 0
     863             : 
     864       15783 :             CALL reallocate(cores, 1, natom)
     865       15783 :             npme = 0
     866       51218 :             cores = 0
     867             : 
     868       51218 :             DO iatom = 1, natom
     869       51218 :                IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
     870             :                   ! replicated realspace grid, split the atoms up between procs
     871       34608 :                   IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
     872       17304 :                      npme = npme + 1
     873       17304 :                      cores(npme) = iatom
     874             :                   END IF
     875             :                ELSE
     876         827 :                   npme = npme + 1
     877         827 :                   cores(npme) = iatom
     878             :                END IF
     879             :             END DO
     880             : 
     881       40956 :             IF (npme .GT. 0) THEN
     882       30686 :                DO j = 1, npme
     883             : 
     884       18131 :                   iatom = cores(j)
     885       18131 :                   atom_a = atom_list(iatom)
     886       18131 :                   ra(:) = pbc(particle_set(atom_a)%r, cell)
     887       18131 :                   subpatch_pattern = 0
     888             :                   radius = exp_radius_very_extended(la_min=0, la_max=0, &
     889             :                                                     lb_min=0, lb_max=0, &
     890             :                                                     ra=ra, rb=ra, rp=ra, &
     891             :                                                     zetp=alpha, eps=eps_rho_rspace, &
     892             :                                                     pab=pab, o1=0, o2=0, &  ! without map_consistent
     893       18131 :                                                     prefactor=-1.0_dp, cutoff=0.0_dp)
     894             : 
     895             :                   CALL collocate_pgf_product(0, alpha, 0, 0, 0.0_dp, 0, ra, &
     896             :                                              (/0.0_dp, 0.0_dp, 0.0_dp/), -1.0_dp, pab, 0, 0, rs_rho, &
     897             :                                              radius=radius, ga_gb_function=GRID_FUNC_AB, &
     898       30686 :                                              use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
     899             : 
     900             :                END DO
     901             :             END IF
     902             : 
     903             :          END DO
     904             : 
     905        9068 :          IF (ASSOCIATED(cores)) THEN
     906        9060 :             DEALLOCATE (cores)
     907             :          END IF
     908        9068 :          DEALLOCATE (pab)
     909             : 
     910        9068 :          CALL auxbas_pw_pool%create_pw(rhoc_r)
     911             : 
     912        9068 :          CALL transfer_rs2pw(rs_rho, rhoc_r)
     913             : 
     914        9068 :          total_rho = pw_integrate_function(rhoc_r, isign=-1)
     915             : 
     916        9068 :          CALL pw_transfer(rhoc_r, rho_core)
     917             : 
     918        9068 :          CALL auxbas_pw_pool%give_back_pw(rhoc_r)
     919             : 
     920        9068 :          CALL timestop(handle)
     921             : 
     922        9068 :       END SUBROUTINE calculate_rho_core_${kind}$
     923             :    #:endfor
     924             : 
     925             : ! *****************************************************************************
     926             : !> \brief Computes the derivative of the density of the core charges with
     927             : !>        respect to the nuclear coordinates on the grid.
     928             : !> \param drho_core The resulting density derivative
     929             : !> \param qs_env ...
     930             : !> \param beta Derivative direction
     931             : !> \param lambda Atom index
     932             : !> \note SL November 2014, ED 2021
     933             : ! **************************************************************************************************
     934         108 :    SUBROUTINE calculate_drho_core(drho_core, qs_env, beta, lambda)
     935             : 
     936             :       TYPE(pw_c1d_gs_type), INTENT(INOUT)                       :: drho_core
     937             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     938             :       INTEGER, INTENT(IN)                                :: beta, lambda
     939             : 
     940             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_drho_core'
     941             : 
     942             :       INTEGER                                            :: atom_a, dabqadb_func, handle, iatom, &
     943             :                                                             ikind, ithread, j, natom, npme, &
     944             :                                                             nthread, subpatch_pattern
     945         108 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores
     946             :       REAL(KIND=dp)                                      :: alpha, eps_rho_rspace, radius
     947             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
     948         108 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
     949         108 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     950             :       TYPE(cell_type), POINTER                           :: cell
     951             :       TYPE(dft_control_type), POINTER                    :: dft_control
     952         108 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     953             :       TYPE(pw_env_type), POINTER                         :: pw_env
     954             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     955             :       TYPE(pw_r3d_rs_type)                                      :: rhoc_r
     956         108 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     957             :       TYPE(realspace_grid_type), POINTER                 :: rs_rho
     958             : 
     959         108 :       CALL timeset(routineN, handle)
     960         108 :       NULLIFY (cell, dft_control, pab, atomic_kind_set, qs_kind_set, particle_set, &
     961         108 :                atom_list, pw_env, rs_rho, auxbas_pw_pool, cores)
     962         108 :       ALLOCATE (pab(1, 1))
     963             : 
     964             :       CALL get_qs_env(qs_env=qs_env, &
     965             :                       atomic_kind_set=atomic_kind_set, &
     966             :                       qs_kind_set=qs_kind_set, &
     967             :                       cell=cell, &
     968             :                       dft_control=dft_control, &
     969             :                       particle_set=particle_set, &
     970         108 :                       pw_env=pw_env)
     971             :       CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
     972         108 :                       auxbas_pw_pool=auxbas_pw_pool)
     973             :       ! be careful in parallel nsmax is chosen with multigrid in mind!
     974         108 :       CALL rs_grid_zero(rs_rho)
     975             : 
     976         108 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     977             : 
     978         144 :       SELECT CASE (beta)
     979             :       CASE (1)
     980          36 :          dabqadb_func = GRID_FUNC_CORE_X
     981             :       CASE (2)
     982          36 :          dabqadb_func = GRID_FUNC_CORE_Y
     983             :       CASE (3)
     984          36 :          dabqadb_func = GRID_FUNC_CORE_Z
     985             :       CASE DEFAULT
     986         108 :          CPABORT("invalid beta")
     987             :       END SELECT
     988         324 :       DO ikind = 1, SIZE(atomic_kind_set)
     989         216 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
     990             :          CALL get_qs_kind(qs_kind_set(ikind), &
     991         216 :                           alpha_core_charge=alpha, ccore_charge=pab(1, 1))
     992             : 
     993         216 :          IF (alpha == 0.0_dp .OR. pab(1, 1) == 0.0_dp) CYCLE
     994             : 
     995         216 :          nthread = 1
     996         216 :          ithread = 0
     997             : 
     998         216 :          CALL reallocate(cores, 1, natom)
     999         216 :          npme = 0
    1000         540 :          cores = 0
    1001             : 
    1002         540 :          DO iatom = 1, natom
    1003         540 :             IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
    1004             :                ! replicated realspace grid, split the atoms up between procs
    1005         324 :                IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
    1006         162 :                   npme = npme + 1
    1007         162 :                   cores(npme) = iatom
    1008             :                END IF
    1009             :             ELSE
    1010           0 :                npme = npme + 1
    1011           0 :                cores(npme) = iatom
    1012             :             END IF
    1013             :          END DO
    1014             : 
    1015         540 :          IF (npme .GT. 0) THEN
    1016         324 :             DO j = 1, npme
    1017             : 
    1018         162 :                iatom = cores(j)
    1019         162 :                atom_a = atom_list(iatom)
    1020         162 :                IF (atom_a /= lambda) CYCLE
    1021          54 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
    1022          54 :                subpatch_pattern = 0
    1023             :                radius = exp_radius_very_extended(la_min=0, la_max=0, &
    1024             :                                                  lb_min=0, lb_max=0, &
    1025             :                                                  ra=ra, rb=ra, rp=ra, &
    1026             :                                                  zetp=alpha, eps=eps_rho_rspace, &
    1027             :                                                  pab=pab, o1=0, o2=0, &  ! without map_consistent
    1028          54 :                                                  prefactor=-1.0_dp, cutoff=0.0_dp)
    1029             : 
    1030             :                CALL collocate_pgf_product(0, alpha, 0, 0, 0.0_dp, 0, ra, &
    1031             :                                           (/0.0_dp, 0.0_dp, 0.0_dp/), -1.0_dp, pab, 0, 0, rs_rho, &
    1032             :                                           radius=radius, ga_gb_function=dabqadb_func, &
    1033         324 :                                           use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
    1034             : 
    1035             :             END DO
    1036             :          END IF
    1037             : 
    1038             :       END DO
    1039             : 
    1040         108 :       IF (ASSOCIATED(cores)) THEN
    1041         108 :          DEALLOCATE (cores)
    1042             :       END IF
    1043         108 :       DEALLOCATE (pab)
    1044             : 
    1045         108 :       CALL auxbas_pw_pool%create_pw(rhoc_r)
    1046             : 
    1047         108 :       CALL transfer_rs2pw(rs_rho, rhoc_r)
    1048             : 
    1049         108 :       CALL pw_transfer(rhoc_r, drho_core)
    1050             : 
    1051         108 :       CALL auxbas_pw_pool%give_back_pw(rhoc_r)
    1052             : 
    1053         108 :       CALL timestop(handle)
    1054             : 
    1055         108 :    END SUBROUTINE calculate_drho_core
    1056             : 
    1057             : ! **************************************************************************************************
    1058             : !> \brief collocate a single Gaussian on the grid
    1059             : !> \param rho_gb charge density generated by a single gaussian
    1060             : !> \param qs_env qs environment
    1061             : !> \param iatom_in atom index
    1062             : !> \par History
    1063             : !>        12.2011 created
    1064             : !> \author Dorothea Golze
    1065             : ! **************************************************************************************************
    1066           4 :    SUBROUTINE calculate_rho_single_gaussian(rho_gb, qs_env, iatom_in)
    1067             : 
    1068             :       TYPE(pw_c1d_gs_type), INTENT(INOUT)                       :: rho_gb
    1069             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1070             :       INTEGER, INTENT(IN)                                :: iatom_in
    1071             : 
    1072             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_single_gaussian'
    1073             : 
    1074             :       INTEGER                                            :: atom_a, handle, iatom, npme, &
    1075             :                                                             subpatch_pattern
    1076             :       REAL(KIND=dp)                                      :: eps_rho_rspace, radius
    1077             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
    1078           4 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
    1079             :       TYPE(cell_type), POINTER                           :: cell
    1080             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1081             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1082             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1083             :       TYPE(pw_r3d_rs_type)                                      :: rhoc_r
    1084             :       TYPE(realspace_grid_type), POINTER                 :: rs_rho
    1085             : 
    1086           4 :       CALL timeset(routineN, handle)
    1087           4 :       NULLIFY (cell, dft_control, pab, pw_env, rs_rho, auxbas_pw_pool)
    1088             : 
    1089           4 :       ALLOCATE (pab(1, 1))
    1090             : 
    1091             :       CALL get_qs_env(qs_env=qs_env, &
    1092             :                       cell=cell, &
    1093             :                       dft_control=dft_control, &
    1094           4 :                       pw_env=pw_env)
    1095             :       CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
    1096           4 :                       auxbas_pw_pool=auxbas_pw_pool)
    1097           4 :       CALL rs_grid_zero(rs_rho)
    1098             : 
    1099           4 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    1100           4 :       pab(1, 1) = 1.0_dp
    1101           4 :       iatom = iatom_in
    1102             : 
    1103           4 :       npme = 0
    1104             : 
    1105           4 :       IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
    1106           4 :          IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
    1107             :             npme = npme + 1
    1108             :          END IF
    1109             :       ELSE
    1110             :          npme = npme + 1
    1111             :       END IF
    1112             : 
    1113             :       IF (npme .GT. 0) THEN
    1114           2 :          atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
    1115           2 :          ra(:) = pbc(qs_env%qmmm_env_qm%image_charge_pot%particles_all(atom_a)%r, cell)
    1116           2 :          subpatch_pattern = 0
    1117             :          radius = exp_radius_very_extended(la_min=0, la_max=0, &
    1118             :                                            lb_min=0, lb_max=0, &
    1119             :                                            ra=ra, rb=ra, rp=ra, &
    1120             :                                            zetp=qs_env%qmmm_env_qm%image_charge_pot%eta, &
    1121             :                                            eps=eps_rho_rspace, &
    1122             :                                            pab=pab, o1=0, o2=0, &  ! without map_consistent
    1123           2 :                                            prefactor=1.0_dp, cutoff=0.0_dp)
    1124             : 
    1125             :          CALL collocate_pgf_product(0, qs_env%qmmm_env_qm%image_charge_pot%eta, &
    1126             :                                     0, 0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), 1.0_dp, pab, 0, 0, rs_rho, &
    1127             :                                     radius=radius, ga_gb_function=GRID_FUNC_AB, &
    1128           2 :                                     use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
    1129             :       END IF
    1130             : 
    1131           4 :       DEALLOCATE (pab)
    1132             : 
    1133           4 :       CALL auxbas_pw_pool%create_pw(rhoc_r)
    1134             : 
    1135           4 :       CALL transfer_rs2pw(rs_rho, rhoc_r)
    1136             : 
    1137           4 :       CALL pw_transfer(rhoc_r, rho_gb)
    1138             : 
    1139           4 :       CALL auxbas_pw_pool%give_back_pw(rhoc_r)
    1140             : 
    1141           4 :       CALL timestop(handle)
    1142             : 
    1143           4 :    END SUBROUTINE calculate_rho_single_gaussian
    1144             : 
    1145             : ! **************************************************************************************************
    1146             : !> \brief computes the image charge density on the grid (including coeffcients)
    1147             : !> \param rho_metal image charge density
    1148             : !> \param coeff expansion coefficients of the image charge density, i.e.
    1149             : !>        rho_metal=sum_a c_a*g_a
    1150             : !> \param total_rho_metal total induced image charge density
    1151             : !> \param qs_env qs environment
    1152             : !> \par History
    1153             : !>        01.2012 created
    1154             : !> \author Dorothea Golze
    1155             : ! **************************************************************************************************
    1156          90 :    SUBROUTINE calculate_rho_metal(rho_metal, coeff, total_rho_metal, qs_env)
    1157             : 
    1158             :       TYPE(pw_c1d_gs_type), INTENT(INOUT)                       :: rho_metal
    1159             :       REAL(KIND=dp), DIMENSION(:), POINTER               :: coeff
    1160             :       REAL(KIND=dp), INTENT(OUT), OPTIONAL               :: total_rho_metal
    1161             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1162             : 
    1163             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_metal'
    1164             : 
    1165             :       INTEGER                                            :: atom_a, handle, iatom, j, natom, npme, &
    1166             :                                                             subpatch_pattern
    1167          90 :       INTEGER, DIMENSION(:), POINTER                     :: cores
    1168             :       REAL(KIND=dp)                                      :: eps_rho_rspace, radius
    1169             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
    1170          90 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
    1171             :       TYPE(cell_type), POINTER                           :: cell
    1172             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1173             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1174             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1175             :       TYPE(pw_r3d_rs_type)                                      :: rhoc_r
    1176             :       TYPE(realspace_grid_type), POINTER                 :: rs_rho
    1177             : 
    1178          90 :       CALL timeset(routineN, handle)
    1179             : 
    1180          90 :       NULLIFY (cell, dft_control, pab, pw_env, rs_rho, auxbas_pw_pool, cores)
    1181             : 
    1182          90 :       ALLOCATE (pab(1, 1))
    1183             : 
    1184             :       CALL get_qs_env(qs_env=qs_env, &
    1185             :                       cell=cell, &
    1186             :                       dft_control=dft_control, &
    1187          90 :                       pw_env=pw_env)
    1188             :       CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
    1189          90 :                       auxbas_pw_pool=auxbas_pw_pool)
    1190          90 :       CALL rs_grid_zero(rs_rho)
    1191             : 
    1192          90 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    1193          90 :       pab(1, 1) = 1.0_dp
    1194             : 
    1195          90 :       natom = SIZE(qs_env%qmmm_env_qm%image_charge_pot%image_mm_list)
    1196             : 
    1197          90 :       CALL reallocate(cores, 1, natom)
    1198          90 :       npme = 0
    1199         270 :       cores = 0
    1200             : 
    1201         270 :       DO iatom = 1, natom
    1202         270 :          IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
    1203         180 :             IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
    1204          90 :                npme = npme + 1
    1205          90 :                cores(npme) = iatom
    1206             :             END IF
    1207             :          ELSE
    1208           0 :             npme = npme + 1
    1209           0 :             cores(npme) = iatom
    1210             :          END IF
    1211             :       END DO
    1212             : 
    1213          90 :       IF (npme .GT. 0) THEN
    1214         180 :          DO j = 1, npme
    1215          90 :             iatom = cores(j)
    1216          90 :             atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
    1217          90 :             ra(:) = pbc(qs_env%qmmm_env_qm%image_charge_pot%particles_all(atom_a)%r, cell)
    1218          90 :             subpatch_pattern = 0
    1219             :             radius = exp_radius_very_extended(la_min=0, la_max=0, &
    1220             :                                               lb_min=0, lb_max=0, &
    1221             :                                               ra=ra, rb=ra, rp=ra, &
    1222             :                                               zetp=qs_env%qmmm_env_qm%image_charge_pot%eta, &
    1223             :                                               eps=eps_rho_rspace, &
    1224             :                                               pab=pab, o1=0, o2=0, &  ! without map_consistent
    1225          90 :                                               prefactor=coeff(iatom), cutoff=0.0_dp)
    1226             : 
    1227             :             CALL collocate_pgf_product( &
    1228             :                0, qs_env%qmmm_env_qm%image_charge_pot%eta, &
    1229             :                0, 0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), coeff(iatom), pab, 0, 0, rs_rho, &
    1230             :                radius=radius, ga_gb_function=GRID_FUNC_AB, &
    1231         180 :                use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
    1232             :          END DO
    1233             :       END IF
    1234             : 
    1235          90 :       DEALLOCATE (pab, cores)
    1236             : 
    1237          90 :       CALL auxbas_pw_pool%create_pw(rhoc_r)
    1238             : 
    1239          90 :       CALL transfer_rs2pw(rs_rho, rhoc_r)
    1240             : 
    1241          90 :       IF (PRESENT(total_rho_metal)) &
    1242             :          !minus sign: account for the fact that rho_metal has opposite sign
    1243          90 :          total_rho_metal = pw_integrate_function(rhoc_r, isign=-1)
    1244             : 
    1245          90 :       CALL pw_transfer(rhoc_r, rho_metal)
    1246          90 :       CALL auxbas_pw_pool%give_back_pw(rhoc_r)
    1247             : 
    1248          90 :       CALL timestop(handle)
    1249             : 
    1250          90 :    END SUBROUTINE calculate_rho_metal
    1251             : 
    1252             : ! **************************************************************************************************
    1253             : !> \brief collocate a single Gaussian on the grid for periodic RESP fitting
    1254             : !> \param rho_gb charge density generated by a single gaussian
    1255             : !> \param qs_env qs environment
    1256             : !> \param eta width of single Gaussian
    1257             : !> \param iatom_in atom index
    1258             : !> \par History
    1259             : !>        06.2012 created
    1260             : !> \author Dorothea Golze
    1261             : ! **************************************************************************************************
    1262          66 :    SUBROUTINE calculate_rho_resp_single(rho_gb, qs_env, eta, iatom_in)
    1263             : 
    1264             :       TYPE(pw_c1d_gs_type), INTENT(INOUT)                       :: rho_gb
    1265             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1266             :       REAL(KIND=dp), INTENT(IN)                          :: eta
    1267             :       INTEGER, INTENT(IN)                                :: iatom_in
    1268             : 
    1269             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_resp_single'
    1270             : 
    1271             :       INTEGER                                            :: handle, iatom, npme, subpatch_pattern
    1272             :       REAL(KIND=dp)                                      :: eps_rho_rspace, radius
    1273             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
    1274          66 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
    1275             :       TYPE(cell_type), POINTER                           :: cell
    1276             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1277          66 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1278             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1279             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1280             :       TYPE(pw_r3d_rs_type)                                      :: rhoc_r
    1281             :       TYPE(realspace_grid_type), POINTER                 :: rs_rho
    1282             : 
    1283          66 :       CALL timeset(routineN, handle)
    1284          66 :       NULLIFY (cell, dft_control, pab, pw_env, rs_rho, auxbas_pw_pool, &
    1285          66 :                particle_set)
    1286             : 
    1287          66 :       ALLOCATE (pab(1, 1))
    1288             : 
    1289             :       CALL get_qs_env(qs_env=qs_env, &
    1290             :                       cell=cell, &
    1291             :                       dft_control=dft_control, &
    1292             :                       particle_set=particle_set, &
    1293          66 :                       pw_env=pw_env)
    1294             :       CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
    1295          66 :                       auxbas_pw_pool=auxbas_pw_pool)
    1296          66 :       CALL rs_grid_zero(rs_rho)
    1297             : 
    1298          66 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    1299          66 :       pab(1, 1) = 1.0_dp
    1300          66 :       iatom = iatom_in
    1301             : 
    1302          66 :       npme = 0
    1303             : 
    1304          66 :       IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
    1305          66 :          IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
    1306             :             npme = npme + 1
    1307             :          END IF
    1308             :       ELSE
    1309             :          npme = npme + 1
    1310             :       END IF
    1311             : 
    1312             :       IF (npme .GT. 0) THEN
    1313          33 :          ra(:) = pbc(particle_set(iatom)%r, cell)
    1314          33 :          subpatch_pattern = 0
    1315             :          radius = exp_radius_very_extended(la_min=0, la_max=0, &
    1316             :                                            lb_min=0, lb_max=0, &
    1317             :                                            ra=ra, rb=ra, rp=ra, &
    1318             :                                            zetp=eta, eps=eps_rho_rspace, &
    1319             :                                            pab=pab, o1=0, o2=0, &  ! without map_consistent
    1320          33 :                                            prefactor=1.0_dp, cutoff=0.0_dp)
    1321             : 
    1322             :          CALL collocate_pgf_product(0, eta, 0, 0, 0.0_dp, 0, ra, &
    1323             :                                     (/0.0_dp, 0.0_dp, 0.0_dp/), 1.0_dp, pab, 0, 0, rs_rho, &
    1324             :                                     radius=radius, ga_gb_function=GRID_FUNC_AB, &
    1325          33 :                                     use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
    1326             :       END IF
    1327             : 
    1328          66 :       DEALLOCATE (pab)
    1329             : 
    1330          66 :       CALL auxbas_pw_pool%create_pw(rhoc_r)
    1331             : 
    1332          66 :       CALL transfer_rs2pw(rs_rho, rhoc_r)
    1333             : 
    1334          66 :       CALL pw_transfer(rhoc_r, rho_gb)
    1335             : 
    1336          66 :       CALL auxbas_pw_pool%give_back_pw(rhoc_r)
    1337             : 
    1338          66 :       CALL timestop(handle)
    1339             : 
    1340          66 :    END SUBROUTINE calculate_rho_resp_single
    1341             : 
    1342             :    #:for kind in ["r3d_rs", "c1d_gs"]
    1343             : ! **************************************************************************************************
    1344             : !> \brief computes the RESP charge density on a grid based on the RESP charges
    1345             : !> \param rho_resp RESP charge density
    1346             : !> \param coeff RESP charges, take care of normalization factor
    1347             : !>        (eta/pi)**1.5 later
    1348             : !> \param natom number of atoms
    1349             : !> \param eta width of single Gaussian
    1350             : !> \param qs_env qs environment
    1351             : !> \par History
    1352             : !>        01.2012 created
    1353             : !> \author Dorothea Golze
    1354             : ! **************************************************************************************************
    1355          24 :       SUBROUTINE calculate_rho_resp_all_${kind}$ (rho_resp, coeff, natom, eta, qs_env)
    1356             : 
    1357             :          TYPE(pw_${kind}$_type), INTENT(INOUT)                       :: rho_resp
    1358             :          REAL(KIND=dp), DIMENSION(:), POINTER               :: coeff
    1359             :          INTEGER, INTENT(IN)                                :: natom
    1360             :          REAL(KIND=dp), INTENT(IN)                          :: eta
    1361             :          TYPE(qs_environment_type), POINTER                 :: qs_env
    1362             : 
    1363             :          CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_resp_all'
    1364             : 
    1365             :          INTEGER                                            :: handle, iatom, j, npme, subpatch_pattern
    1366          24 :          INTEGER, DIMENSION(:), POINTER                     :: cores
    1367             :          REAL(KIND=dp)                                      :: eps_rho_rspace, radius
    1368             :          REAL(KIND=dp), DIMENSION(3)                        :: ra
    1369          24 :          REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
    1370             :          TYPE(cell_type), POINTER                           :: cell
    1371             :          TYPE(dft_control_type), POINTER                    :: dft_control
    1372          24 :          TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1373             :          TYPE(pw_env_type), POINTER                         :: pw_env
    1374             :          TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1375             :          TYPE(pw_r3d_rs_type)                                      :: rhoc_r
    1376             :          TYPE(realspace_grid_type), POINTER                 :: rs_rho
    1377             : 
    1378          24 :          CALL timeset(routineN, handle)
    1379             : 
    1380          24 :          NULLIFY (cell, cores, dft_control, pab, pw_env, rs_rho, auxbas_pw_pool, &
    1381          24 :                   particle_set)
    1382             : 
    1383          24 :          ALLOCATE (pab(1, 1))
    1384             : 
    1385             :          CALL get_qs_env(qs_env=qs_env, &
    1386             :                          cell=cell, &
    1387             :                          dft_control=dft_control, &
    1388             :                          particle_set=particle_set, &
    1389          24 :                          pw_env=pw_env)
    1390             :          CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
    1391          24 :                          auxbas_pw_pool=auxbas_pw_pool)
    1392          24 :          CALL rs_grid_zero(rs_rho)
    1393             : 
    1394          24 :          eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    1395          24 :          pab(1, 1) = 1.0_dp
    1396             : 
    1397          24 :          CALL reallocate(cores, 1, natom)
    1398          24 :          npme = 0
    1399         142 :          cores = 0
    1400             : 
    1401         142 :          DO iatom = 1, natom
    1402         142 :             IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
    1403         118 :                IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
    1404          59 :                   npme = npme + 1
    1405          59 :                   cores(npme) = iatom
    1406             :                END IF
    1407             :             ELSE
    1408           0 :                npme = npme + 1
    1409           0 :                cores(npme) = iatom
    1410             :             END IF
    1411             :          END DO
    1412             : 
    1413          24 :          IF (npme .GT. 0) THEN
    1414          83 :             DO j = 1, npme
    1415          59 :                iatom = cores(j)
    1416          59 :                ra(:) = pbc(particle_set(iatom)%r, cell)
    1417          59 :                subpatch_pattern = 0
    1418             :                radius = exp_radius_very_extended(la_min=0, la_max=0, &
    1419             :                                                  lb_min=0, lb_max=0, &
    1420             :                                                  ra=ra, rb=ra, rp=ra, &
    1421             :                                                  zetp=eta, eps=eps_rho_rspace, &
    1422             :                                                  pab=pab, o1=0, o2=0, &  ! without map_consistent
    1423          59 :                                                  prefactor=coeff(iatom), cutoff=0.0_dp)
    1424             : 
    1425             :                CALL collocate_pgf_product( &
    1426             :                   0, eta, &
    1427             :                   0, 0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), coeff(iatom), pab, 0, 0, rs_rho, &
    1428             :                   radius=radius, ga_gb_function=GRID_FUNC_AB, &
    1429          83 :                   use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
    1430             :             END DO
    1431             :          END IF
    1432             : 
    1433          24 :          DEALLOCATE (pab, cores)
    1434             : 
    1435          24 :          CALL auxbas_pw_pool%create_pw(rhoc_r)
    1436             : 
    1437          24 :          CALL transfer_rs2pw(rs_rho, rhoc_r)
    1438             : 
    1439          24 :          CALL pw_transfer(rhoc_r, rho_resp)
    1440          24 :          CALL auxbas_pw_pool%give_back_pw(rhoc_r)
    1441             : 
    1442          24 :          CALL timestop(handle)
    1443             : 
    1444          24 :       END SUBROUTINE calculate_rho_resp_all_${kind}$
    1445             :    #:endfor
    1446             : 
    1447             : ! **************************************************************************************************
    1448             : !> \brief computes the density corresponding to a given density matrix on the grid
    1449             : !> \param matrix_p ...
    1450             : !> \param matrix_p_kp ...
    1451             : !> \param rho ...
    1452             : !> \param rho_gspace ...
    1453             : !> \param total_rho ...
    1454             : !> \param ks_env ...
    1455             : !> \param soft_valid ...
    1456             : !> \param compute_tau ...
    1457             : !> \param compute_grad ...
    1458             : !> \param basis_type ...
    1459             : !> \param der_type ...
    1460             : !> \param idir ...
    1461             : !> \param task_list_external ...
    1462             : !> \param pw_env_external ...
    1463             : !> \par History
    1464             : !>      IAB (15-Feb-2010): Added OpenMP parallelisation to task loop
    1465             : !>                         (c) The Numerical Algorithms Group (NAG) Ltd, 2010 on behalf of the HECToR project
    1466             : !>      Anything that is not the default ORB basis_type requires an external_task_list 12.2019, (A.Bussy)
    1467             : !>      Ole Schuett (2020): Migrated to C, see grid_api.F
    1468             : !> \note
    1469             : !>      both rho and rho_gspace contain the new rho
    1470             : !>      (in real and g-space respectively)
    1471             : ! **************************************************************************************************
    1472      191345 :    SUBROUTINE calculate_rho_elec(matrix_p, matrix_p_kp, rho, rho_gspace, total_rho, &
    1473             :                                  ks_env, soft_valid, compute_tau, compute_grad, &
    1474             :                                  basis_type, der_type, idir, task_list_external, pw_env_external)
    1475             : 
    1476             :       TYPE(dbcsr_type), OPTIONAL, TARGET                 :: matrix_p
    1477             :       TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
    1478             :          POINTER                                         :: matrix_p_kp
    1479             :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                       :: rho
    1480             :       TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_gspace
    1481             :       REAL(KIND=dp), INTENT(OUT), OPTIONAL               :: total_rho
    1482             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1483             :       LOGICAL, INTENT(IN), OPTIONAL                      :: soft_valid, compute_tau, compute_grad
    1484             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: basis_type
    1485             :       INTEGER, INTENT(IN), OPTIONAL                      :: der_type, idir
    1486             :       TYPE(task_list_type), OPTIONAL, POINTER            :: task_list_external
    1487             :       TYPE(pw_env_type), OPTIONAL, POINTER               :: pw_env_external
    1488             : 
    1489             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_elec'
    1490             : 
    1491             :       CHARACTER(LEN=default_string_length)               :: my_basis_type
    1492             :       INTEGER                                            :: ga_gb_function, handle, ilevel, img, &
    1493             :                                                             nimages, nlevels
    1494             :       LOGICAL                                            :: any_distributed, my_compute_grad, &
    1495             :                                                             my_compute_tau, my_soft_valid
    1496      191345 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_images
    1497             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1498             :       TYPE(mp_comm_type)                                 :: group
    1499             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1500      191345 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_rho
    1501             :       TYPE(task_list_type), POINTER                      :: task_list
    1502             : 
    1503      191345 :       CALL timeset(routineN, handle)
    1504             : 
    1505      191345 :       NULLIFY (matrix_images, dft_control, pw_env, rs_rho, task_list)
    1506             : 
    1507             :       ! Figure out which function to collocate.
    1508      191345 :       my_compute_tau = .FALSE.
    1509      191345 :       IF (PRESENT(compute_tau)) my_compute_tau = compute_tau
    1510      191345 :       my_compute_grad = .FALSE.
    1511      191345 :       IF (PRESENT(compute_grad)) my_compute_grad = compute_grad
    1512      191345 :       IF (PRESENT(der_type)) THEN
    1513          84 :          SELECT CASE (der_type)
    1514             :          CASE (orb_s)
    1515          36 :             ga_gb_function = GRID_FUNC_AB
    1516             :          CASE (orb_px)
    1517           0 :             ga_gb_function = GRID_FUNC_DX
    1518             :          CASE (orb_py)
    1519           0 :             ga_gb_function = GRID_FUNC_DY
    1520             :          CASE (orb_pz)
    1521          12 :             ga_gb_function = GRID_FUNC_DZ
    1522             :          CASE (orb_dxy)
    1523           0 :             ga_gb_function = GRID_FUNC_DXDY
    1524             :          CASE (orb_dyz)
    1525           0 :             ga_gb_function = GRID_FUNC_DYDZ
    1526             :          CASE (orb_dzx)
    1527           0 :             ga_gb_function = GRID_FUNC_DZDX
    1528             :          CASE (orb_dx2)
    1529           0 :             ga_gb_function = GRID_FUNC_DXDX
    1530             :          CASE (orb_dy2)
    1531           0 :             ga_gb_function = GRID_FUNC_DYDY
    1532             :          CASE (orb_dz2)
    1533           0 :             ga_gb_function = GRID_FUNC_DZDZ
    1534             :          CASE DEFAULT
    1535          48 :             CPABORT("Unknown der_type")
    1536             :          END SELECT
    1537      191297 :       ELSE IF (my_compute_tau) THEN
    1538        4156 :          ga_gb_function = GRID_FUNC_DADB
    1539      187141 :       ELSE IF (my_compute_grad) THEN
    1540         258 :          CPASSERT(PRESENT(idir))
    1541         344 :          SELECT CASE (idir)
    1542             :          CASE (1)
    1543          86 :             ga_gb_function = GRID_FUNC_DABpADB_X
    1544             :          CASE (2)
    1545          86 :             ga_gb_function = GRID_FUNC_DABpADB_Y
    1546             :          CASE (3)
    1547          86 :             ga_gb_function = GRID_FUNC_DABpADB_Z
    1548             :          CASE DEFAULT
    1549         258 :             CPABORT("invalid idir")
    1550             :          END SELECT
    1551             :       ELSE
    1552      186883 :          ga_gb_function = GRID_FUNC_AB
    1553             :       END IF
    1554             : 
    1555             :       ! Figure out which basis_type to use.
    1556      191345 :       my_basis_type = "ORB"  ! by default, the full density is calculated
    1557      191345 :       IF (PRESENT(basis_type)) my_basis_type = basis_type
    1558      191345 :       CPASSERT(my_basis_type == "ORB" .OR. PRESENT(task_list_external))
    1559             : 
    1560             :       ! Figure out which task_list to use.
    1561      191345 :       my_soft_valid = .FALSE.
    1562      191345 :       IF (PRESENT(soft_valid)) my_soft_valid = soft_valid
    1563      191345 :       IF (PRESENT(task_list_external)) THEN
    1564       37582 :          task_list => task_list_external
    1565      153763 :       ELSEIF (my_soft_valid) THEN
    1566       22972 :          CALL get_ks_env(ks_env, task_list_soft=task_list)
    1567             :       ELSE
    1568      130791 :          CALL get_ks_env(ks_env, task_list=task_list)
    1569             :       END IF
    1570      191345 :       CPASSERT(ASSOCIATED(task_list))
    1571             : 
    1572             :       ! Figure out which pw_env to use.
    1573      191345 :       IF (PRESENT(pw_env_external)) THEN
    1574       21218 :          pw_env => pw_env_external
    1575             :       ELSE
    1576      170127 :          CALL get_ks_env(ks_env, pw_env=pw_env)
    1577             :       END IF
    1578      191345 :       CPASSERT(ASSOCIATED(pw_env))
    1579             : 
    1580             :       ! Get grids.
    1581      191345 :       CALL pw_env_get(pw_env, rs_grids=rs_rho)
    1582      191345 :       nlevels = SIZE(rs_rho)
    1583      191345 :       group = rs_rho(1)%desc%group
    1584             : 
    1585             :       ! Check if any of the grids is distributed.
    1586      191345 :       any_distributed = .FALSE.
    1587      951377 :       DO ilevel = 1, nlevels
    1588     1710501 :          any_distributed = any_distributed .OR. rs_rho(ilevel)%desc%distributed
    1589             :       END DO
    1590             : 
    1591             :       ! Gather all matrix images in a single array.
    1592      191345 :       CALL get_ks_env(ks_env, dft_control=dft_control)
    1593      191345 :       nimages = dft_control%nimages
    1594      882192 :       ALLOCATE (matrix_images(nimages))
    1595      191345 :       IF (PRESENT(matrix_p_kp)) THEN
    1596      161627 :          CPASSERT(.NOT. PRESENT(matrix_p))
    1597      440066 :          DO img = 1, nimages
    1598      440066 :             matrix_images(img)%matrix => matrix_p_kp(img)%matrix
    1599             :          END DO
    1600             :       ELSE
    1601       29718 :          CPASSERT(PRESENT(matrix_p) .AND. nimages == 1)
    1602       29718 :          matrix_images(1)%matrix => matrix_p
    1603             :       END IF
    1604             : 
    1605             :       ! Distribute matrix blocks.
    1606      191345 :       IF (any_distributed) THEN
    1607         230 :          CALL rs_scatter_matrices(matrix_images, task_list%pab_buffer, task_list, group)
    1608             :       ELSE
    1609      191115 :          CALL rs_copy_to_buffer(matrix_images, task_list%pab_buffer, task_list)
    1610             :       END IF
    1611      191345 :       DEALLOCATE (matrix_images)
    1612             : 
    1613             :       ! Map all tasks onto the grids
    1614             :       CALL grid_collocate_task_list(task_list=task_list%grid_task_list, &
    1615             :                                     ga_gb_function=ga_gb_function, &
    1616             :                                     pab_blocks=task_list%pab_buffer, &
    1617      191345 :                                     rs_grids=rs_rho)
    1618             : 
    1619             :       ! Merge realspace multi-grids into single planewave grid.
    1620      191345 :       CALL density_rs2pw(pw_env, rs_rho, rho, rho_gspace)
    1621      191345 :       IF (PRESENT(total_rho)) total_rho = pw_integrate_function(rho, isign=-1)
    1622             : 
    1623      191345 :       CALL timestop(handle)
    1624             : 
    1625      191345 :    END SUBROUTINE calculate_rho_elec
    1626             : 
    1627             : ! **************************************************************************************************
    1628             : !> \brief computes the gradient of the density corresponding to a given
    1629             : !>        density matrix on the grid
    1630             : !> \param matrix_p ...
    1631             : !> \param matrix_p_kp ...
    1632             : !> \param drho ...
    1633             : !> \param drho_gspace ...
    1634             : !> \param qs_env ...
    1635             : !> \param soft_valid ...
    1636             : !> \param basis_type ...
    1637             : !> \note  this is an alternative to calculate the gradient through FFTs
    1638             : ! **************************************************************************************************
    1639           0 :    SUBROUTINE calculate_drho_elec(matrix_p, matrix_p_kp, drho, drho_gspace, qs_env, &
    1640             :                                   soft_valid, basis_type)
    1641             : 
    1642             :       TYPE(dbcsr_type), OPTIONAL, TARGET                 :: matrix_p
    1643             :       TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
    1644             :          POINTER                                         :: matrix_p_kp
    1645             :       TYPE(pw_r3d_rs_type), DIMENSION(3), INTENT(INOUT)         :: drho
    1646             :       TYPE(pw_c1d_gs_type), DIMENSION(3), INTENT(INOUT) :: drho_gspace
    1647             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1648             :       LOGICAL, INTENT(IN), OPTIONAL                      :: soft_valid
    1649             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: basis_type
    1650             : 
    1651             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_drho_elec'
    1652             : 
    1653             :       CHARACTER(LEN=default_string_length)               :: my_basis_type
    1654             :       INTEGER :: bcol, brow, dabqadb_func, handle, iatom, iatom_old, idir, igrid_level, ikind, &
    1655             :                  ikind_old, img, img_old, ipgf, iset, iset_old, itask, ithread, jatom, jatom_old, jkind, &
    1656             :                  jkind_old, jpgf, jset, jset_old, maxco, maxsgf_set, na1, na2, natoms, nb1, nb2, ncoa, &
    1657             :                  ncob, nimages, nseta, nsetb, ntasks, nthread, sgfa, sgfb
    1658           0 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, npgfa, &
    1659           0 :                                                             npgfb, nsgfa, nsgfb
    1660           0 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
    1661             :       LOGICAL                                            :: atom_pair_changed, distributed_rs_grids, &
    1662             :                                                             do_kp, found, my_soft, use_subpatch
    1663             :       REAL(KIND=dp)                                      :: eps_rho_rspace, f, prefactor, radius, &
    1664             :                                                             scale, zetp
    1665             :       REAL(KIND=dp), DIMENSION(3)                        :: ra, rab, rab_inv, rb, rp
    1666           0 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: p_block, pab, sphi_a, sphi_b, work, &
    1667           0 :                                                             zeta, zetb
    1668           0 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: pabt, workt
    1669           0 :       TYPE(atom_pair_type), DIMENSION(:), POINTER        :: atom_pair_recv, atom_pair_send
    1670             :       TYPE(cell_type), POINTER                           :: cell
    1671           0 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: deltap
    1672             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1673             :       TYPE(gridlevel_info_type), POINTER                 :: gridlevel_info
    1674             :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1675             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1676           0 :          POINTER                                         :: sab_orb
    1677           0 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1678             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1679           0 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1680             :       TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
    1681           0 :          POINTER                                         :: rs_descs
    1682           0 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_rho
    1683             :       TYPE(task_list_type), POINTER                      :: task_list, task_list_soft
    1684           0 :       TYPE(task_type), DIMENSION(:), POINTER             :: tasks
    1685             : 
    1686           0 :       CALL timeset(routineN, handle)
    1687             : 
    1688           0 :       CPASSERT(PRESENT(matrix_p) .OR. PRESENT(matrix_p_kp))
    1689           0 :       do_kp = PRESENT(matrix_p_kp)
    1690             : 
    1691           0 :       NULLIFY (cell, dft_control, orb_basis_set, deltap, qs_kind_set, &
    1692           0 :                sab_orb, particle_set, rs_rho, pw_env, rs_descs, la_max, la_min, &
    1693           0 :                lb_max, lb_min, npgfa, npgfb, nsgfa, nsgfb, p_block, sphi_a, &
    1694           0 :                sphi_b, zeta, zetb, first_sgfa, first_sgfb, tasks, pabt, workt)
    1695             : 
    1696             :       ! by default, the full density is calculated
    1697           0 :       my_soft = .FALSE.
    1698           0 :       IF (PRESENT(soft_valid)) my_soft = soft_valid
    1699             : 
    1700           0 :       IF (PRESENT(basis_type)) THEN
    1701           0 :          my_basis_type = basis_type
    1702             :       ELSE
    1703           0 :          my_basis_type = "ORB"
    1704             :       END IF
    1705             : 
    1706             :       CALL get_qs_env(qs_env=qs_env, &
    1707             :                       qs_kind_set=qs_kind_set, &
    1708             :                       cell=cell, &
    1709             :                       dft_control=dft_control, &
    1710             :                       particle_set=particle_set, &
    1711             :                       sab_orb=sab_orb, &
    1712           0 :                       pw_env=pw_env)
    1713             : 
    1714           0 :       SELECT CASE (my_basis_type)
    1715             :       CASE ("ORB")
    1716             :          CALL get_qs_env(qs_env=qs_env, &
    1717             :                          task_list=task_list, &
    1718           0 :                          task_list_soft=task_list_soft)
    1719             :       CASE ("AUX_FIT")
    1720             :          CALL get_qs_env(qs_env=qs_env, &
    1721           0 :                          task_list_soft=task_list_soft)
    1722           0 :          CALL get_admm_env(qs_env%admm_env, task_list_aux_fit=task_list)
    1723             :       END SELECT
    1724             : 
    1725             :       ! *** assign from pw_env
    1726           0 :       gridlevel_info => pw_env%gridlevel_info
    1727             : 
    1728             :       !   *** Allocate work storage ***
    1729           0 :       nthread = 1
    1730             :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
    1731             :                            maxco=maxco, &
    1732             :                            maxsgf_set=maxsgf_set, &
    1733           0 :                            basis_type=my_basis_type)
    1734           0 :       CALL reallocate(pabt, 1, maxco, 1, maxco, 0, nthread - 1)
    1735           0 :       CALL reallocate(workt, 1, maxco, 1, maxsgf_set, 0, nthread - 1)
    1736             : 
    1737             :       ! find maximum numbers
    1738           0 :       nimages = dft_control%nimages
    1739           0 :       CPASSERT(nimages == 1 .OR. do_kp)
    1740             : 
    1741           0 :       natoms = SIZE(particle_set)
    1742             : 
    1743             :       ! get the task lists
    1744           0 :       IF (my_soft) task_list => task_list_soft
    1745           0 :       CPASSERT(ASSOCIATED(task_list))
    1746           0 :       tasks => task_list%tasks
    1747           0 :       atom_pair_send => task_list%atom_pair_send
    1748           0 :       atom_pair_recv => task_list%atom_pair_recv
    1749           0 :       ntasks = task_list%ntasks
    1750             : 
    1751             :       ! *** set up the rs multi-grids
    1752           0 :       CPASSERT(ASSOCIATED(pw_env))
    1753           0 :       CALL pw_env_get(pw_env, rs_descs=rs_descs, rs_grids=rs_rho)
    1754           0 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    1755           0 :          distributed_rs_grids = rs_rho(igrid_level)%desc%distributed
    1756             :       END DO
    1757             : 
    1758           0 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    1759             : 
    1760             :       !   *** Initialize working density matrix ***
    1761             :       ! distributed rs grids require a matrix that will be changed
    1762             :       ! whereas this is not the case for replicated grids
    1763           0 :       ALLOCATE (deltap(nimages))
    1764           0 :       IF (distributed_rs_grids) THEN
    1765           0 :          DO img = 1, nimages
    1766             :          END DO
    1767             :          ! this matrix has no strict sparsity pattern in parallel
    1768             :          ! deltap%sparsity_id=-1
    1769           0 :          IF (do_kp) THEN
    1770           0 :             DO img = 1, nimages
    1771             :                CALL dbcsr_copy(deltap(img)%matrix, matrix_p_kp(img)%matrix, &
    1772           0 :                                name="DeltaP")
    1773             :             END DO
    1774             :          ELSE
    1775           0 :             CALL dbcsr_copy(deltap(1)%matrix, matrix_p, name="DeltaP")
    1776             :          END IF
    1777             :       ELSE
    1778           0 :          IF (do_kp) THEN
    1779           0 :             DO img = 1, nimages
    1780           0 :                deltap(img)%matrix => matrix_p_kp(img)%matrix
    1781             :             END DO
    1782             :          ELSE
    1783           0 :             deltap(1)%matrix => matrix_p
    1784             :          END IF
    1785             :       END IF
    1786             : 
    1787             :       ! distribute the matrix
    1788           0 :       IF (distributed_rs_grids) THEN
    1789             :          CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltap, &
    1790             :                                    atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
    1791           0 :                                    nimages=nimages, scatter=.TRUE.)
    1792             :       END IF
    1793             : 
    1794             :       ! map all tasks on the grids
    1795             : 
    1796           0 :       ithread = 0
    1797           0 :       pab => pabt(:, :, ithread)
    1798           0 :       work => workt(:, :, ithread)
    1799             : 
    1800           0 :       loop_xyz: DO idir = 1, 3
    1801             : 
    1802           0 :          DO igrid_level = 1, gridlevel_info%ngrid_levels
    1803           0 :             CALL rs_grid_zero(rs_rho(igrid_level))
    1804             :          END DO
    1805             : 
    1806             :          iatom_old = -1; jatom_old = -1; iset_old = -1; jset_old = -1
    1807             :          ikind_old = -1; jkind_old = -1; img_old = -1
    1808           0 :          loop_tasks: DO itask = 1, ntasks
    1809             : 
    1810             :             !decode the atom pair and basis info
    1811           0 :             igrid_level = tasks(itask)%grid_level
    1812           0 :             img = tasks(itask)%image
    1813           0 :             iatom = tasks(itask)%iatom
    1814           0 :             jatom = tasks(itask)%jatom
    1815           0 :             iset = tasks(itask)%iset
    1816           0 :             jset = tasks(itask)%jset
    1817           0 :             ipgf = tasks(itask)%ipgf
    1818           0 :             jpgf = tasks(itask)%jpgf
    1819             : 
    1820           0 :             ikind = particle_set(iatom)%atomic_kind%kind_number
    1821           0 :             jkind = particle_set(jatom)%atomic_kind%kind_number
    1822             : 
    1823           0 :             IF (iatom .NE. iatom_old .OR. jatom .NE. jatom_old .OR. img .NE. img_old) THEN
    1824             : 
    1825           0 :                IF (iatom .NE. iatom_old) ra(:) = pbc(particle_set(iatom)%r, cell)
    1826             : 
    1827           0 :                IF (iatom <= jatom) THEN
    1828           0 :                   brow = iatom
    1829           0 :                   bcol = jatom
    1830             :                ELSE
    1831           0 :                   brow = jatom
    1832           0 :                   bcol = iatom
    1833             :                END IF
    1834             : 
    1835           0 :                IF (ikind .NE. ikind_old) THEN
    1836           0 :                   IF (my_soft) THEN
    1837             :                      CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
    1838           0 :                                       basis_type="ORB_SOFT")
    1839             :                   ELSE
    1840             :                      CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
    1841           0 :                                       basis_type=my_basis_type)
    1842             :                   END IF
    1843             :                   CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    1844             :                                          first_sgf=first_sgfa, &
    1845             :                                          lmax=la_max, &
    1846             :                                          lmin=la_min, &
    1847             :                                          npgf=npgfa, &
    1848             :                                          nset=nseta, &
    1849             :                                          nsgf_set=nsgfa, &
    1850             :                                          sphi=sphi_a, &
    1851           0 :                                          zet=zeta)
    1852             :                END IF
    1853             : 
    1854           0 :                IF (jkind .NE. jkind_old) THEN
    1855           0 :                   IF (my_soft) THEN
    1856             :                      CALL get_qs_kind(qs_kind_set(jkind), basis_set=orb_basis_set, &
    1857           0 :                                       basis_type="ORB_SOFT")
    1858             :                   ELSE
    1859             :                      CALL get_qs_kind(qs_kind_set(jkind), basis_set=orb_basis_set, &
    1860           0 :                                       basis_type=my_basis_type)
    1861             :                   END IF
    1862             :                   CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    1863             :                                          first_sgf=first_sgfb, &
    1864             :                                          lmax=lb_max, &
    1865             :                                          lmin=lb_min, &
    1866             :                                          npgf=npgfb, &
    1867             :                                          nset=nsetb, &
    1868             :                                          nsgf_set=nsgfb, &
    1869             :                                          sphi=sphi_b, &
    1870           0 :                                          zet=zetb)
    1871             :                END IF
    1872             : 
    1873             :                CALL dbcsr_get_block_p(matrix=deltap(img)%matrix, &
    1874           0 :                                       row=brow, col=bcol, BLOCK=p_block, found=found)
    1875           0 :                CPASSERT(found)
    1876             : 
    1877             :                iatom_old = iatom
    1878             :                jatom_old = jatom
    1879             :                ikind_old = ikind
    1880             :                jkind_old = jkind
    1881             :                img_old = img
    1882             :                atom_pair_changed = .TRUE.
    1883             : 
    1884             :             ELSE
    1885             : 
    1886             :                atom_pair_changed = .FALSE.
    1887             : 
    1888             :             END IF
    1889             : 
    1890           0 :             IF (atom_pair_changed .OR. iset_old .NE. iset .OR. jset_old .NE. jset) THEN
    1891             : 
    1892           0 :                ncoa = npgfa(iset)*ncoset(la_max(iset))
    1893           0 :                sgfa = first_sgfa(1, iset)
    1894           0 :                ncob = npgfb(jset)*ncoset(lb_max(jset))
    1895           0 :                sgfb = first_sgfb(1, jset)
    1896             : 
    1897           0 :                IF (iatom <= jatom) THEN
    1898             :                   CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
    1899             :                              1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
    1900             :                              p_block(sgfa, sgfb), SIZE(p_block, 1), &
    1901           0 :                              0.0_dp, work(1, 1), maxco)
    1902             :                   CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
    1903             :                              1.0_dp, work(1, 1), maxco, &
    1904             :                              sphi_b(1, sgfb), SIZE(sphi_b, 1), &
    1905           0 :                              0.0_dp, pab(1, 1), maxco)
    1906             :                ELSE
    1907             :                   CALL dgemm("N", "N", ncob, nsgfa(iset), nsgfb(jset), &
    1908             :                              1.0_dp, sphi_b(1, sgfb), SIZE(sphi_b, 1), &
    1909             :                              p_block(sgfb, sgfa), SIZE(p_block, 1), &
    1910           0 :                              0.0_dp, work(1, 1), maxco)
    1911             :                   CALL dgemm("N", "T", ncob, ncoa, nsgfa(iset), &
    1912             :                              1.0_dp, work(1, 1), maxco, &
    1913             :                              sphi_a(1, sgfa), SIZE(sphi_a, 1), &
    1914           0 :                              0.0_dp, pab(1, 1), maxco)
    1915             :                END IF
    1916             : 
    1917             :                iset_old = iset
    1918             :                jset_old = jset
    1919             : 
    1920             :             END IF
    1921             : 
    1922           0 :             rab(:) = tasks(itask)%rab
    1923           0 :             rb(:) = ra(:) + rab(:)
    1924           0 :             zetp = zeta(ipgf, iset) + zetb(jpgf, jset)
    1925             : 
    1926           0 :             f = zetb(jpgf, jset)/zetp
    1927           0 :             rp(:) = ra(:) + f*rab(:)
    1928           0 :             prefactor = EXP(-zeta(ipgf, iset)*f*DOT_PRODUCT(rab, rab))
    1929             :             radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
    1930             :                                               lb_min=lb_min(jset), lb_max=lb_max(jset), &
    1931             :                                               ra=ra, rb=rb, rp=rp, &
    1932             :                                               zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
    1933           0 :                                               prefactor=prefactor, cutoff=1.0_dp)
    1934             : 
    1935           0 :             na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
    1936           0 :             na2 = ipgf*ncoset(la_max(iset))
    1937           0 :             nb1 = (jpgf - 1)*ncoset(lb_max(jset)) + 1
    1938           0 :             nb2 = jpgf*ncoset(lb_max(jset))
    1939             : 
    1940             :             ! takes the density matrix symmetry in account, i.e. off-diagonal blocks need to be mapped 'twice'
    1941           0 :             IF (iatom == jatom .AND. img == 1) THEN
    1942           0 :                scale = 1.0_dp
    1943             :             ELSE
    1944           0 :                scale = 2.0_dp
    1945             :             END IF
    1946             : 
    1947             :             ! check whether we need to use fawzi's generalised collocation scheme
    1948           0 :             IF (rs_rho(igrid_level)%desc%distributed) THEN
    1949             :                !tasks(4,:) is 0 for replicated, 1 for distributed 2 for exceptional distributed tasks
    1950           0 :                IF (tasks(itask)%dist_type .EQ. 2) THEN
    1951           0 :                   use_subpatch = .TRUE.
    1952             :                ELSE
    1953           0 :                   use_subpatch = .FALSE.
    1954             :                END IF
    1955             :             ELSE
    1956           0 :                use_subpatch = .FALSE.
    1957             :             END IF
    1958             : 
    1959           0 :             SELECT CASE (idir)
    1960             :             CASE (1)
    1961           0 :                dabqadb_func = GRID_FUNC_DABpADB_X
    1962             :             CASE (2)
    1963           0 :                dabqadb_func = GRID_FUNC_DABpADB_Y
    1964             :             CASE (3)
    1965           0 :                dabqadb_func = GRID_FUNC_DABpADB_Z
    1966             :             CASE DEFAULT
    1967           0 :                CPABORT("invalid idir")
    1968             :             END SELECT
    1969             : 
    1970           0 :             IF (iatom <= jatom) THEN
    1971             :                CALL collocate_pgf_product( &
    1972             :                   la_max(iset), zeta(ipgf, iset), la_min(iset), &
    1973             :                   lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
    1974             :                   ra, rab, scale, pab, na1 - 1, nb1 - 1, &
    1975             :                   rs_rho(igrid_level), &
    1976             :                   radius=radius, ga_gb_function=dabqadb_func, &
    1977           0 :                   use_subpatch=use_subpatch, subpatch_pattern=tasks(itask)%subpatch_pattern)
    1978             :             ELSE
    1979           0 :                rab_inv = -rab
    1980             :                CALL collocate_pgf_product( &
    1981             :                   lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
    1982             :                   la_max(iset), zeta(ipgf, iset), la_min(iset), &
    1983             :                   rb, rab_inv, scale, pab, nb1 - 1, na1 - 1, &
    1984             :                   rs_rho(igrid_level), &
    1985             :                   radius=radius, ga_gb_function=dabqadb_func, &
    1986           0 :                   use_subpatch=use_subpatch, subpatch_pattern=tasks(itask)%subpatch_pattern)
    1987             :             END IF
    1988             : 
    1989             :          END DO loop_tasks
    1990             : 
    1991           0 :          CALL density_rs2pw(pw_env, rs_rho, drho(idir), drho_gspace(idir))
    1992             : 
    1993             :       END DO loop_xyz
    1994             : 
    1995             :       !   *** Release work storage ***
    1996           0 :       IF (distributed_rs_grids) THEN
    1997           0 :          CALL dbcsr_deallocate_matrix_set(deltap)
    1998             :       ELSE
    1999           0 :          DO img = 1, nimages
    2000           0 :             NULLIFY (deltap(img)%matrix)
    2001             :          END DO
    2002           0 :          DEALLOCATE (deltap)
    2003             :       END IF
    2004             : 
    2005           0 :       DEALLOCATE (pabt, workt)
    2006             : 
    2007           0 :       CALL timestop(handle)
    2008             : 
    2009           0 :    END SUBROUTINE calculate_drho_elec
    2010             : 
    2011             : ! **************************************************************************************************
    2012             : !> \brief Computes the gradient wrt. nuclear coordinates of a density on the grid
    2013             : !>        The density is given in terms of the density matrix_p
    2014             : !> \param matrix_p Density matrix
    2015             : !> \param matrix_p_kp ...
    2016             : !> \param drho Density gradient on the grid
    2017             : !> \param drho_gspace Density gradient on the reciprocal grid
    2018             : !> \param qs_env ...
    2019             : !> \param soft_valid ...
    2020             : !> \param basis_type ...
    2021             : !> \param beta Derivative direction
    2022             : !> \param lambda Atom index
    2023             : !> \note SL, ED 2021
    2024             : !>       Adapted from calculate_drho_elec
    2025             : ! **************************************************************************************************
    2026         126 :    SUBROUTINE calculate_drho_elec_dR(matrix_p, matrix_p_kp, drho, drho_gspace, qs_env, &
    2027             :                                      soft_valid, basis_type, beta, lambda)
    2028             : 
    2029             :       TYPE(dbcsr_type), OPTIONAL, TARGET                 :: matrix_p
    2030             :       TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
    2031             :          POINTER                                         :: matrix_p_kp
    2032             :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                       :: drho
    2033             :       TYPE(pw_c1d_gs_type), INTENT(INOUT) :: drho_gspace
    2034             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2035             :       LOGICAL, INTENT(IN), OPTIONAL                      :: soft_valid
    2036             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: basis_type
    2037             :       INTEGER, INTENT(IN)                                :: beta, lambda
    2038             : 
    2039             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_drho_elec_dR'
    2040             : 
    2041             :       CHARACTER(LEN=default_string_length)               :: my_basis_type
    2042             :       INTEGER :: bcol, brow, dabqadb_func, handle, iatom, iatom_old, igrid_level, ikind, &
    2043             :                  ikind_old, img, img_old, ipgf, iset, iset_old, itask, ithread, jatom, jatom_old, jkind, &
    2044             :                  jkind_old, jpgf, jset, jset_old, maxco, maxsgf_set, na1, na2, natoms, nb1, nb2, ncoa, &
    2045             :                  ncob, nimages, nseta, nsetb, ntasks, nthread, sgfa, sgfb
    2046         126 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, npgfa, &
    2047         126 :                                                             npgfb, nsgfa, nsgfb
    2048         126 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
    2049             :       LOGICAL                                            :: atom_pair_changed, distributed_rs_grids, &
    2050             :                                                             do_kp, found, my_soft, use_subpatch
    2051             :       REAL(KIND=dp)                                      :: eps_rho_rspace, f, prefactor, radius, &
    2052             :                                                             scale, zetp
    2053             :       REAL(KIND=dp), DIMENSION(3)                        :: ra, rab, rab_inv, rb, rp
    2054         126 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: p_block, pab, sphi_a, sphi_b, work, &
    2055         126 :                                                             zeta, zetb
    2056         126 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: pabt, workt
    2057         126 :       TYPE(atom_pair_type), DIMENSION(:), POINTER        :: atom_pair_recv, atom_pair_send
    2058             :       TYPE(cell_type), POINTER                           :: cell
    2059         126 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: deltap
    2060             :       TYPE(dft_control_type), POINTER                    :: dft_control
    2061             :       TYPE(gridlevel_info_type), POINTER                 :: gridlevel_info
    2062             :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    2063         126 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2064             :       TYPE(pw_env_type), POINTER                         :: pw_env
    2065         126 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    2066             :       TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
    2067         126 :          POINTER                                         :: rs_descs
    2068         126 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_rho
    2069             :       TYPE(task_list_type), POINTER                      :: task_list, task_list_soft
    2070         126 :       TYPE(task_type), DIMENSION(:), POINTER             :: tasks
    2071             : 
    2072         126 :       CALL timeset(routineN, handle)
    2073             : 
    2074         126 :       CPASSERT(PRESENT(matrix_p) .OR. PRESENT(matrix_p_kp))
    2075         126 :       do_kp = PRESENT(matrix_p_kp)
    2076             : 
    2077         126 :       NULLIFY (cell, dft_control, orb_basis_set, deltap, qs_kind_set, &
    2078         126 :                particle_set, rs_rho, pw_env, rs_descs, la_max, la_min, lb_max, &
    2079         126 :                lb_min, npgfa, npgfb, nsgfa, nsgfb, p_block, sphi_a, sphi_b, &
    2080         126 :                zeta, zetb, first_sgfa, first_sgfb, tasks, pabt, workt)
    2081             : 
    2082             :       ! by default, the full density is calculated
    2083         126 :       my_soft = .FALSE.
    2084         126 :       IF (PRESENT(soft_valid)) my_soft = soft_valid
    2085             : 
    2086         126 :       IF (PRESENT(basis_type)) THEN
    2087           0 :          my_basis_type = basis_type
    2088             :       ELSE
    2089         126 :          my_basis_type = "ORB"
    2090             :       END IF
    2091             : 
    2092             :       CALL get_qs_env(qs_env=qs_env, &
    2093             :                       qs_kind_set=qs_kind_set, &
    2094             :                       cell=cell, &
    2095             :                       dft_control=dft_control, &
    2096             :                       particle_set=particle_set, &
    2097         126 :                       pw_env=pw_env)
    2098             : 
    2099         126 :       SELECT CASE (my_basis_type)
    2100             :       CASE ("ORB")
    2101             :          CALL get_qs_env(qs_env=qs_env, &
    2102             :                          task_list=task_list, &
    2103         126 :                          task_list_soft=task_list_soft)
    2104             :       CASE ("AUX_FIT")
    2105             :          CALL get_qs_env(qs_env=qs_env, &
    2106           0 :                          task_list_soft=task_list_soft)
    2107         126 :          CALL get_admm_env(qs_env%admm_env, task_list_aux_fit=task_list)
    2108             :       END SELECT
    2109             : 
    2110             :       ! *** assign from pw_env
    2111         126 :       gridlevel_info => pw_env%gridlevel_info
    2112             : 
    2113             :       !   *** Allocate work storage ***
    2114         126 :       nthread = 1
    2115             :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
    2116             :                            maxco=maxco, &
    2117             :                            maxsgf_set=maxsgf_set, &
    2118         126 :                            basis_type=my_basis_type)
    2119         126 :       CALL reallocate(pabt, 1, maxco, 1, maxco, 0, nthread - 1)
    2120         126 :       CALL reallocate(workt, 1, maxco, 1, maxsgf_set, 0, nthread - 1)
    2121             : 
    2122             :       ! find maximum numbers
    2123         126 :       nimages = dft_control%nimages
    2124         126 :       CPASSERT(nimages == 1 .OR. do_kp)
    2125             : 
    2126         126 :       natoms = SIZE(particle_set)
    2127             : 
    2128             :       ! get the task lists
    2129         126 :       IF (my_soft) task_list => task_list_soft
    2130         126 :       CPASSERT(ASSOCIATED(task_list))
    2131         126 :       tasks => task_list%tasks
    2132         126 :       atom_pair_send => task_list%atom_pair_send
    2133         126 :       atom_pair_recv => task_list%atom_pair_recv
    2134         126 :       ntasks = task_list%ntasks
    2135             : 
    2136             :       ! *** set up the rs multi-grids
    2137         126 :       CPASSERT(ASSOCIATED(pw_env))
    2138         126 :       CALL pw_env_get(pw_env, rs_descs=rs_descs, rs_grids=rs_rho)
    2139         414 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    2140         414 :          distributed_rs_grids = rs_rho(igrid_level)%desc%distributed
    2141             :       END DO
    2142             : 
    2143         126 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    2144             : 
    2145             :       !   *** Initialize working density matrix ***
    2146             :       ! distributed rs grids require a matrix that will be changed
    2147             :       ! whereas this is not the case for replicated grids
    2148         504 :       ALLOCATE (deltap(nimages))
    2149         126 :       IF (distributed_rs_grids) THEN
    2150           0 :          DO img = 1, nimages
    2151             :          END DO
    2152             :          ! this matrix has no strict sparsity pattern in parallel
    2153             :          ! deltap%sparsity_id=-1
    2154           0 :          IF (do_kp) THEN
    2155           0 :             DO img = 1, nimages
    2156             :                CALL dbcsr_copy(deltap(img)%matrix, matrix_p_kp(img)%matrix, &
    2157           0 :                                name="DeltaP")
    2158             :             END DO
    2159             :          ELSE
    2160           0 :             CALL dbcsr_copy(deltap(1)%matrix, matrix_p, name="DeltaP")
    2161             :          END IF
    2162             :       ELSE
    2163         126 :          IF (do_kp) THEN
    2164           0 :             DO img = 1, nimages
    2165           0 :                deltap(img)%matrix => matrix_p_kp(img)%matrix
    2166             :             END DO
    2167             :          ELSE
    2168         126 :             deltap(1)%matrix => matrix_p
    2169             :          END IF
    2170             :       END IF
    2171             : 
    2172             :       ! distribute the matrix
    2173         126 :       IF (distributed_rs_grids) THEN
    2174             :          CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltap, &
    2175             :                                    atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
    2176           0 :                                    nimages=nimages, scatter=.TRUE.)
    2177             :       END IF
    2178             : 
    2179             :       ! map all tasks on the grids
    2180             : 
    2181         126 :       ithread = 0
    2182         126 :       pab => pabt(:, :, ithread)
    2183         126 :       work => workt(:, :, ithread)
    2184             : 
    2185         414 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    2186         414 :          CALL rs_grid_zero(rs_rho(igrid_level))
    2187             :       END DO
    2188             : 
    2189             :       iatom_old = -1; jatom_old = -1; iset_old = -1; jset_old = -1
    2190             :       ikind_old = -1; jkind_old = -1; img_old = -1
    2191       10413 :       loop_tasks: DO itask = 1, ntasks
    2192             : 
    2193             :          !decode the atom pair and basis info
    2194       10287 :          igrid_level = tasks(itask)%grid_level
    2195       10287 :          img = tasks(itask)%image
    2196       10287 :          iatom = tasks(itask)%iatom
    2197       10287 :          jatom = tasks(itask)%jatom
    2198       10287 :          iset = tasks(itask)%iset
    2199       10287 :          jset = tasks(itask)%jset
    2200       10287 :          ipgf = tasks(itask)%ipgf
    2201       10287 :          jpgf = tasks(itask)%jpgf
    2202             : 
    2203       10287 :          ikind = particle_set(iatom)%atomic_kind%kind_number
    2204       10287 :          jkind = particle_set(jatom)%atomic_kind%kind_number
    2205             : 
    2206       10287 :          IF (iatom .NE. iatom_old .OR. jatom .NE. jatom_old .OR. img .NE. img_old) THEN
    2207             : 
    2208         702 :             IF (iatom .NE. iatom_old) ra(:) = pbc(particle_set(iatom)%r, cell)
    2209             : 
    2210         702 :             IF (iatom <= jatom) THEN
    2211         468 :                brow = iatom
    2212         468 :                bcol = jatom
    2213             :             ELSE
    2214         234 :                brow = jatom
    2215         234 :                bcol = iatom
    2216             :             END IF
    2217             : 
    2218         702 :             IF (ikind .NE. ikind_old) THEN
    2219         126 :                IF (my_soft) THEN
    2220             :                   CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
    2221           0 :                                    basis_type="ORB_SOFT")
    2222             :                ELSE
    2223             :                   CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
    2224         126 :                                    basis_type=my_basis_type)
    2225             :                END IF
    2226             :                CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    2227             :                                       first_sgf=first_sgfa, &
    2228             :                                       lmax=la_max, &
    2229             :                                       lmin=la_min, &
    2230             :                                       npgf=npgfa, &
    2231             :                                       nset=nseta, &
    2232             :                                       nsgf_set=nsgfa, &
    2233             :                                       sphi=sphi_a, &
    2234         126 :                                       zet=zeta)
    2235             :             END IF
    2236             : 
    2237         702 :             IF (jkind .NE. jkind_old) THEN
    2238         468 :                IF (my_soft) THEN
    2239             :                   CALL get_qs_kind(qs_kind_set(jkind), basis_set=orb_basis_set, &
    2240           0 :                                    basis_type="ORB_SOFT")
    2241             :                ELSE
    2242             :                   CALL get_qs_kind(qs_kind_set(jkind), basis_set=orb_basis_set, &
    2243         468 :                                    basis_type=my_basis_type)
    2244             :                END IF
    2245             :                CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    2246             :                                       first_sgf=first_sgfb, &
    2247             :                                       lmax=lb_max, &
    2248             :                                       lmin=lb_min, &
    2249             :                                       npgf=npgfb, &
    2250             :                                       nset=nsetb, &
    2251             :                                       nsgf_set=nsgfb, &
    2252             :                                       sphi=sphi_b, &
    2253         468 :                                       zet=zetb)
    2254             :             END IF
    2255             : 
    2256             :             CALL dbcsr_get_block_p(matrix=deltap(img)%matrix, &
    2257         702 :                                    row=brow, col=bcol, BLOCK=p_block, found=found)
    2258         702 :             CPASSERT(found)
    2259             : 
    2260             :             iatom_old = iatom
    2261             :             jatom_old = jatom
    2262             :             ikind_old = ikind
    2263             :             jkind_old = jkind
    2264             :             img_old = img
    2265             :             atom_pair_changed = .TRUE.
    2266             : 
    2267             :          ELSE
    2268             : 
    2269             :             atom_pair_changed = .FALSE.
    2270             : 
    2271             :          END IF
    2272             : 
    2273       10287 :          IF (atom_pair_changed .OR. iset_old .NE. iset .OR. jset_old .NE. jset) THEN
    2274             : 
    2275         702 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
    2276         702 :             sgfa = first_sgfa(1, iset)
    2277         702 :             ncob = npgfb(jset)*ncoset(lb_max(jset))
    2278         702 :             sgfb = first_sgfb(1, jset)
    2279             : 
    2280         702 :             IF (iatom <= jatom) THEN
    2281             :                CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
    2282             :                           1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
    2283             :                           p_block(sgfa, sgfb), SIZE(p_block, 1), &
    2284         468 :                           0.0_dp, work(1, 1), maxco)
    2285             :                CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
    2286             :                           1.0_dp, work(1, 1), maxco, &
    2287             :                           sphi_b(1, sgfb), SIZE(sphi_b, 1), &
    2288         468 :                           0.0_dp, pab(1, 1), maxco)
    2289             :             ELSE
    2290             :                CALL dgemm("N", "N", ncob, nsgfa(iset), nsgfb(jset), &
    2291             :                           1.0_dp, sphi_b(1, sgfb), SIZE(sphi_b, 1), &
    2292             :                           p_block(sgfb, sgfa), SIZE(p_block, 1), &
    2293         234 :                           0.0_dp, work(1, 1), maxco)
    2294             :                CALL dgemm("N", "T", ncob, ncoa, nsgfa(iset), &
    2295             :                           1.0_dp, work(1, 1), maxco, &
    2296             :                           sphi_a(1, sgfa), SIZE(sphi_a, 1), &
    2297         234 :                           0.0_dp, pab(1, 1), maxco)
    2298             :             END IF
    2299             : 
    2300             :             iset_old = iset
    2301             :             jset_old = jset
    2302             : 
    2303             :          END IF
    2304             : 
    2305       41148 :          rab(:) = tasks(itask)%rab
    2306       41148 :          rb(:) = ra(:) + rab(:)
    2307       10287 :          zetp = zeta(ipgf, iset) + zetb(jpgf, jset)
    2308             : 
    2309       10287 :          f = zetb(jpgf, jset)/zetp
    2310       41148 :          rp(:) = ra(:) + f*rab(:)
    2311       41148 :          prefactor = EXP(-zeta(ipgf, iset)*f*DOT_PRODUCT(rab, rab))
    2312             :          radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
    2313             :                                            lb_min=lb_min(jset), lb_max=lb_max(jset), &
    2314             :                                            ra=ra, rb=rb, rp=rp, &
    2315             :                                            zetp=zetp, eps=eps_rho_rspace, &
    2316       10287 :                                            prefactor=prefactor, cutoff=1.0_dp)
    2317             : 
    2318       10287 :          na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
    2319       10287 :          na2 = ipgf*ncoset(la_max(iset))
    2320       10287 :          nb1 = (jpgf - 1)*ncoset(lb_max(jset)) + 1
    2321       10287 :          nb2 = jpgf*ncoset(lb_max(jset))
    2322             : 
    2323             :          ! takes the density matrix symmetry in account, i.e. off-diagonal blocks need to be mapped 'twice'
    2324       10287 :          IF (iatom == jatom .AND. img == 1) THEN
    2325        5076 :             scale = 1.0_dp
    2326             :          ELSE
    2327        5211 :             scale = 2.0_dp
    2328             :          END IF
    2329             : 
    2330             :          ! check whether we need to use fawzi's generalised collocation scheme
    2331       10287 :          IF (rs_rho(igrid_level)%desc%distributed) THEN
    2332             :             !tasks(4,:) is 0 for replicated, 1 for distributed 2 for exceptional distributed tasks
    2333           0 :             IF (tasks(itask)%dist_type .EQ. 2) THEN
    2334           0 :                use_subpatch = .TRUE.
    2335             :             ELSE
    2336           0 :                use_subpatch = .FALSE.
    2337             :             END IF
    2338             :          ELSE
    2339       10287 :             use_subpatch = .FALSE.
    2340             :          END IF
    2341             : 
    2342       13716 :          SELECT CASE (beta)
    2343             :          CASE (1)
    2344        3429 :             dabqadb_func = GRID_FUNC_DAB_X
    2345             :          CASE (2)
    2346        3429 :             dabqadb_func = GRID_FUNC_DAB_Y
    2347             :          CASE (3)
    2348        3429 :             dabqadb_func = GRID_FUNC_DAB_Z
    2349             :          CASE DEFAULT
    2350       10287 :             CPABORT("invalid beta")
    2351             :          END SELECT
    2352             : 
    2353       10413 :          IF (iatom <= jatom) THEN
    2354        6822 :             IF (iatom == lambda) &
    2355             :                CALL collocate_pgf_product( &
    2356             :                la_max(iset), zeta(ipgf, iset), la_min(iset), &
    2357             :                lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
    2358             :                ra, rab, scale, pab, na1 - 1, nb1 - 1, &
    2359             :                rsgrid=rs_rho(igrid_level), &
    2360             :                ga_gb_function=dabqadb_func, radius=radius, &
    2361             :                use_subpatch=use_subpatch, &
    2362        2274 :                subpatch_pattern=tasks(itask)%subpatch_pattern)
    2363        6822 :             IF (jatom == lambda) &
    2364             :                CALL collocate_pgf_product( &
    2365             :                la_max(iset), zeta(ipgf, iset), la_min(iset), &
    2366             :                lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
    2367             :                ra, rab, scale, pab, na1 - 1, nb1 - 1, &
    2368             :                rsgrid=rs_rho(igrid_level), &
    2369             :                ga_gb_function=dabqadb_func + 3, radius=radius, &
    2370             :                use_subpatch=use_subpatch, &
    2371        2274 :                subpatch_pattern=tasks(itask)%subpatch_pattern)
    2372             :          ELSE
    2373       13860 :             rab_inv = -rab
    2374        3465 :             IF (jatom == lambda) &
    2375             :                CALL collocate_pgf_product( &
    2376             :                lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
    2377             :                la_max(iset), zeta(ipgf, iset), la_min(iset), &
    2378             :                rb, rab_inv, scale, pab, nb1 - 1, na1 - 1, &
    2379             :                rs_rho(igrid_level), &
    2380             :                ga_gb_function=dabqadb_func, radius=radius, &
    2381             :                use_subpatch=use_subpatch, &
    2382        1155 :                subpatch_pattern=tasks(itask)%subpatch_pattern)
    2383        3465 :             IF (iatom == lambda) &
    2384             :                CALL collocate_pgf_product( &
    2385             :                lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
    2386             :                la_max(iset), zeta(ipgf, iset), la_min(iset), &
    2387             :                rb, rab_inv, scale, pab, nb1 - 1, na1 - 1, &
    2388             :                rs_rho(igrid_level), &
    2389             :                ga_gb_function=dabqadb_func + 3, radius=radius, &
    2390             :                use_subpatch=use_subpatch, &
    2391        1155 :                subpatch_pattern=tasks(itask)%subpatch_pattern)
    2392             :          END IF
    2393             : 
    2394             :       END DO loop_tasks
    2395             : 
    2396         126 :       CALL density_rs2pw(pw_env, rs_rho, drho, drho_gspace)
    2397             : 
    2398             :       !   *** Release work storage ***
    2399         126 :       IF (distributed_rs_grids) THEN
    2400           0 :          CALL dbcsr_deallocate_matrix_set(deltap)
    2401             :       ELSE
    2402         252 :          DO img = 1, nimages
    2403         252 :             NULLIFY (deltap(img)%matrix)
    2404             :          END DO
    2405         126 :          DEALLOCATE (deltap)
    2406             :       END IF
    2407             : 
    2408         126 :       DEALLOCATE (pabt, workt)
    2409             : 
    2410         126 :       CALL timestop(handle)
    2411             : 
    2412         252 :    END SUBROUTINE calculate_drho_elec_dR
    2413             : 
    2414             : ! **************************************************************************************************
    2415             : !> \brief maps a single gaussian on the grid
    2416             : !> \param rho ...
    2417             : !> \param rho_gspace ...
    2418             : !> \param atomic_kind_set ...
    2419             : !> \param qs_kind_set ...
    2420             : !> \param cell ...
    2421             : !> \param dft_control ...
    2422             : !> \param particle_set ...
    2423             : !> \param pw_env ...
    2424             : !> \param required_function ...
    2425             : !> \param basis_type ...
    2426             : !> \par History
    2427             : !>      08.2022 created from calculate_wavefunction
    2428             : !> \note
    2429             : !>      modified calculate_wave function assuming that the collocation of only a single Gaussian is required.
    2430             : !>      chooses a basis function (in contrast to calculate_rho_core or calculate_rho_single_gaussian)
    2431             : ! **************************************************************************************************
    2432       26981 :    SUBROUTINE collocate_single_gaussian(rho, rho_gspace, &
    2433             :                                         atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, &
    2434             :                                         pw_env, required_function, basis_type)
    2435             : 
    2436             :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                       :: rho
    2437             :       TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_gspace
    2438             :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2439             :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    2440             :       TYPE(cell_type), POINTER                           :: cell
    2441             :       TYPE(dft_control_type), POINTER                    :: dft_control
    2442             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2443             :       TYPE(pw_env_type), POINTER                         :: pw_env
    2444             :       INTEGER, INTENT(IN)                                :: required_function
    2445             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: basis_type
    2446             : 
    2447             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'collocate_single_gaussian'
    2448             : 
    2449             :       CHARACTER(LEN=default_string_length)               :: my_basis_type
    2450             :       INTEGER :: group_size, handle, i, iatom, igrid_level, ikind, ipgf, iset, maxco, maxsgf_set, &
    2451             :                  my_index, my_pos, na1, na2, natom, ncoa, nseta, offset, sgfa
    2452       26981 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: where_is_the_point
    2453       26981 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, npgfa, nsgfa
    2454       26981 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa
    2455             :       LOGICAL                                            :: found
    2456             :       REAL(KIND=dp)                                      :: dab, eps_rho_rspace, radius, scale
    2457             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
    2458       26981 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab, sphi_a, zeta
    2459             :       TYPE(gridlevel_info_type), POINTER                 :: gridlevel_info
    2460             :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    2461             :       TYPE(mp_comm_type)                                 :: group
    2462       26981 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
    2463       26981 :       TYPE(pw_c1d_gs_type), ALLOCATABLE, DIMENSION(:) :: mgrid_gspace
    2464       26981 :       TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:)           ::  mgrid_rspace
    2465       26981 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_rho
    2466             : 
    2467       26981 :       IF (PRESENT(basis_type)) THEN
    2468       26981 :          my_basis_type = basis_type
    2469             :       ELSE
    2470           0 :          my_basis_type = "ORB"
    2471             :       END IF
    2472             : 
    2473       26981 :       CALL timeset(routineN, handle)
    2474             : 
    2475       26981 :       NULLIFY (orb_basis_set, pab, la_max, la_min, npgfa, nsgfa, sphi_a, &
    2476       26981 :                zeta, first_sgfa, rs_rho, pw_pools)
    2477             : 
    2478             :       ! *** set up the pw multi-grids
    2479       26981 :       CPASSERT(ASSOCIATED(pw_env))
    2480             :       CALL pw_env_get(pw_env, rs_grids=rs_rho, pw_pools=pw_pools, &
    2481       26981 :                       gridlevel_info=gridlevel_info)
    2482             : 
    2483       26981 :       CALL pw_pools_create_pws(pw_pools, mgrid_gspace)
    2484       26981 :       CALL pw_pools_create_pws(pw_pools, mgrid_rspace)
    2485             : 
    2486             :       ! *** set up rs multi-grids
    2487      134905 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    2488      134905 :          CALL rs_grid_zero(rs_rho(igrid_level))
    2489             :       END DO
    2490             : 
    2491       26981 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    2492             : !   *** Allocate work storage ***
    2493       26981 :       CALL get_atomic_kind_set(atomic_kind_set, natom=natom)
    2494             :       CALL get_qs_kind_set(qs_kind_set, &
    2495             :                            maxco=maxco, &
    2496             :                            maxsgf_set=maxsgf_set, &
    2497       26981 :                            basis_type=my_basis_type)
    2498             : 
    2499       80943 :       ALLOCATE (pab(maxco, 1))
    2500             : 
    2501       26981 :       offset = 0
    2502       26981 :       group = mgrid_rspace(1)%pw_grid%para%group
    2503       26981 :       my_pos = mgrid_rspace(1)%pw_grid%para%my_pos
    2504       26981 :       group_size = mgrid_rspace(1)%pw_grid%para%group_size
    2505       80943 :       ALLOCATE (where_is_the_point(0:group_size - 1))
    2506             : 
    2507      110976 :       DO iatom = 1, natom
    2508       83995 :          ikind = particle_set(iatom)%atomic_kind%kind_number
    2509       83995 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=my_basis_type)
    2510             :          CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    2511             :                                 first_sgf=first_sgfa, &
    2512             :                                 lmax=la_max, &
    2513             :                                 lmin=la_min, &
    2514             :                                 npgf=npgfa, &
    2515             :                                 nset=nseta, &
    2516             :                                 nsgf_set=nsgfa, &
    2517             :                                 sphi=sphi_a, &
    2518       83995 :                                 zet=zeta)
    2519       83995 :          ra(:) = pbc(particle_set(iatom)%r, cell)
    2520       83995 :          dab = 0.0_dp
    2521             : 
    2522      989219 :          DO iset = 1, nseta
    2523             : 
    2524      794248 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
    2525      794248 :             sgfa = first_sgfa(1, iset)
    2526             : 
    2527      794248 :             found = .FALSE.
    2528      794248 :             my_index = 0
    2529     3000507 :             DO i = 1, nsgfa(iset)
    2530     3000507 :                IF (offset + i == required_function) THEN
    2531             :                   my_index = i
    2532             :                   found = .TRUE.
    2533             :                   EXIT
    2534             :                END IF
    2535             :             END DO
    2536             : 
    2537             :             IF (found) THEN
    2538             : 
    2539      495899 :                pab(1:ncoa, 1) = sphi_a(1:ncoa, sgfa + my_index - 1)
    2540             : 
    2541       55018 :                DO ipgf = 1, npgfa(iset)
    2542             : 
    2543       28037 :                   na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
    2544       28037 :                   na2 = ipgf*ncoset(la_max(iset))
    2545             : 
    2546       28037 :                   scale = 1.0_dp
    2547       28037 :                   igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
    2548             : 
    2549       55018 :                   IF (map_gaussian_here(rs_rho(igrid_level), cell%h_inv, ra, offset, group_size, my_pos)) THEN
    2550             :                      radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
    2551             :                                                        lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
    2552             :                                                        zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
    2553       26280 :                                                        prefactor=1.0_dp, cutoff=1.0_dp)
    2554             : 
    2555             :                      CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), la_min(iset), &
    2556             :                                                 0, 0.0_dp, 0, &
    2557             :                                                 ra, (/0.0_dp, 0.0_dp, 0.0_dp/), &
    2558             :                                                 scale, pab, na1 - 1, 0, rs_rho(igrid_level), &
    2559       26280 :                                                 radius=radius, ga_gb_function=GRID_FUNC_AB)
    2560             :                   END IF
    2561             : 
    2562             :                END DO
    2563             : 
    2564             :             END IF
    2565             : 
    2566      878243 :             offset = offset + nsgfa(iset)
    2567             : 
    2568             :          END DO
    2569             : 
    2570             :       END DO
    2571             : 
    2572      134905 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    2573             :          CALL transfer_rs2pw(rs_rho(igrid_level), &
    2574      134905 :                              mgrid_rspace(igrid_level))
    2575             :       END DO
    2576             : 
    2577       26981 :       CALL pw_zero(rho_gspace)
    2578      134905 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    2579             :          CALL pw_transfer(mgrid_rspace(igrid_level), &
    2580      107924 :                           mgrid_gspace(igrid_level))
    2581      134905 :          CALL pw_axpy(mgrid_gspace(igrid_level), rho_gspace)
    2582             :       END DO
    2583             : 
    2584       26981 :       CALL pw_transfer(rho_gspace, rho)
    2585             : 
    2586             :       ! Release work storage
    2587       26981 :       DEALLOCATE (pab)
    2588             : 
    2589             :       ! give back the pw multi-grids
    2590       26981 :       CALL pw_pools_give_back_pws(pw_pools, mgrid_gspace)
    2591       26981 :       CALL pw_pools_give_back_pws(pw_pools, mgrid_rspace)
    2592             : 
    2593       26981 :       CALL timestop(handle)
    2594             : 
    2595      161886 :    END SUBROUTINE collocate_single_gaussian
    2596             : 
    2597             : ! **************************************************************************************************
    2598             : !> \brief maps a given wavefunction on the grid
    2599             : !> \param mo_vectors ...
    2600             : !> \param ivector ...
    2601             : !> \param rho ...
    2602             : !> \param rho_gspace ...
    2603             : !> \param atomic_kind_set ...
    2604             : !> \param qs_kind_set ...
    2605             : !> \param cell ...
    2606             : !> \param dft_control ...
    2607             : !> \param particle_set ...
    2608             : !> \param pw_env ...
    2609             : !> \param basis_type ...
    2610             : !> \param external_vector ...
    2611             : !> \par History
    2612             : !>      08.2002 created [Joost VandeVondele]
    2613             : !>      03.2006 made independent of qs_env [Joost VandeVondele]
    2614             : !> \note
    2615             : !>      modified calculate_rho_elec, should write the wavefunction represented by
    2616             : !>      it's presumably dominated by the FFT and the rs->pw and back routines
    2617             : !>
    2618             : !>    BUGS ???
    2619             : !>      does it take correctly the periodic images of the basis functions into account
    2620             : !>      i.e. is only correct if the basis functions are localised enough to be just in 1 cell ?
    2621             : ! **************************************************************************************************
    2622       18594 :    SUBROUTINE calculate_wavefunction(mo_vectors, ivector, rho, rho_gspace, &
    2623             :                                      atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, &
    2624       17156 :                                      pw_env, basis_type, external_vector)
    2625             : 
    2626             :       TYPE(cp_fm_type), INTENT(IN)                       :: mo_vectors
    2627             :       INTEGER, INTENT(IN)                                :: ivector
    2628             :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                       :: rho
    2629             :       TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_gspace
    2630             :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2631             :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    2632             :       TYPE(cell_type), POINTER                           :: cell
    2633             :       TYPE(dft_control_type), POINTER                    :: dft_control
    2634             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2635             :       TYPE(pw_env_type), POINTER                         :: pw_env
    2636             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: basis_type
    2637             :       REAL(KIND=dp), DIMENSION(:), OPTIONAL              :: external_vector
    2638             : 
    2639             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_wavefunction'
    2640             : 
    2641             :       CHARACTER(LEN=default_string_length)               :: my_basis_type
    2642             :       INTEGER :: group_size, handle, i, iatom, igrid_level, ikind, ipgf, iset, maxco, maxsgf_set, &
    2643             :                  my_pos, na1, na2, nao, natom, ncoa, nseta, offset, sgfa
    2644       18594 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: where_is_the_point
    2645       18594 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, npgfa, nsgfa
    2646       18594 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa
    2647             :       LOGICAL                                            :: local
    2648             :       REAL(KIND=dp)                                      :: dab, eps_rho_rspace, radius, scale
    2649             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
    2650       18594 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: eigenvector
    2651       18594 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab, sphi_a, work, zeta
    2652             :       TYPE(gridlevel_info_type), POINTER                 :: gridlevel_info
    2653             :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    2654             :       TYPE(mp_comm_type)                                 :: group
    2655       18594 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
    2656       18594 :       TYPE(pw_c1d_gs_type), ALLOCATABLE, DIMENSION(:) :: mgrid_gspace
    2657       18594 :       TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:)           ::  mgrid_rspace
    2658       18594 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_rho
    2659             : 
    2660       18594 :       IF (PRESENT(basis_type)) THEN
    2661       16852 :          my_basis_type = basis_type
    2662             :       ELSE
    2663        1742 :          my_basis_type = "ORB"
    2664             :       END IF
    2665             : 
    2666       18594 :       CALL timeset(routineN, handle)
    2667             : 
    2668       18594 :       NULLIFY (eigenvector, orb_basis_set, pab, work, la_max, la_min, &
    2669       18594 :                npgfa, nsgfa, sphi_a, zeta, first_sgfa, rs_rho, pw_pools)
    2670             : 
    2671       18594 :       IF (PRESENT(external_vector)) THEN
    2672       17156 :          nao = SIZE(external_vector)
    2673       51468 :          ALLOCATE (eigenvector(nao))
    2674     1450081 :          eigenvector = external_vector
    2675             :       ELSE
    2676        1438 :          CALL cp_fm_get_info(matrix=mo_vectors, nrow_global=nao)
    2677        4314 :          ALLOCATE (eigenvector(nao))
    2678       26828 :          DO i = 1, nao
    2679       25390 :             CALL cp_fm_get_element(mo_vectors, i, ivector, eigenvector(i), local)
    2680             :          END DO
    2681             :       END IF
    2682             : 
    2683             :       ! *** set up the pw multi-grids
    2684       18594 :       CPASSERT(ASSOCIATED(pw_env))
    2685             :       CALL pw_env_get(pw_env, rs_grids=rs_rho, pw_pools=pw_pools, &
    2686       18594 :                       gridlevel_info=gridlevel_info)
    2687             : 
    2688       18594 :       CALL pw_pools_create_pws(pw_pools, mgrid_gspace)
    2689       18594 :       CALL pw_pools_create_pws(pw_pools, mgrid_rspace)
    2690             : 
    2691             :       ! *** set up rs multi-grids
    2692       92814 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    2693       92814 :          CALL rs_grid_zero(rs_rho(igrid_level))
    2694             :       END DO
    2695             : 
    2696       18594 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    2697             : !   *** Allocate work storage ***
    2698       18594 :       CALL get_atomic_kind_set(atomic_kind_set, natom=natom)
    2699             :       CALL get_qs_kind_set(qs_kind_set, &
    2700             :                            maxco=maxco, &
    2701             :                            maxsgf_set=maxsgf_set, &
    2702       18594 :                            basis_type=my_basis_type)
    2703             : 
    2704       55782 :       ALLOCATE (pab(maxco, 1))
    2705       55782 :       ALLOCATE (work(maxco, 1))
    2706             : 
    2707       18594 :       offset = 0
    2708       18594 :       group = mgrid_rspace(1)%pw_grid%para%group
    2709       18594 :       my_pos = mgrid_rspace(1)%pw_grid%para%my_pos
    2710       18594 :       group_size = mgrid_rspace(1)%pw_grid%para%group_size
    2711       55782 :       ALLOCATE (where_is_the_point(0:group_size - 1))
    2712             : 
    2713       76685 :       DO iatom = 1, natom
    2714       58091 :          ikind = particle_set(iatom)%atomic_kind%kind_number
    2715       58091 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=my_basis_type)
    2716             :          CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    2717             :                                 first_sgf=first_sgfa, &
    2718             :                                 lmax=la_max, &
    2719             :                                 lmin=la_min, &
    2720             :                                 npgf=npgfa, &
    2721             :                                 nset=nseta, &
    2722             :                                 nsgf_set=nsgfa, &
    2723             :                                 sphi=sphi_a, &
    2724       58091 :                                 zet=zeta)
    2725       58091 :          ra(:) = pbc(particle_set(iatom)%r, cell)
    2726       58091 :          dab = 0.0_dp
    2727             : 
    2728      643119 :          DO iset = 1, nseta
    2729             : 
    2730      508343 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
    2731      508343 :             sgfa = first_sgfa(1, iset)
    2732             : 
    2733     1965220 :             DO i = 1, nsgfa(iset)
    2734     1965220 :                work(i, 1) = eigenvector(offset + i)
    2735             :             END DO
    2736             : 
    2737             :             CALL dgemm("N", "N", ncoa, 1, nsgfa(iset), &
    2738             :                        1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
    2739             :                        work(1, 1), SIZE(work, 1), &
    2740      508343 :                        0.0_dp, pab(1, 1), SIZE(pab, 1))
    2741             : 
    2742     1039419 :             DO ipgf = 1, npgfa(iset)
    2743             : 
    2744      531076 :                na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
    2745      531076 :                na2 = ipgf*ncoset(la_max(iset))
    2746             : 
    2747      531076 :                scale = 1.0_dp
    2748      531076 :                igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
    2749             : 
    2750     1039419 :                IF (map_gaussian_here(rs_rho(igrid_level), cell%h_inv, ra, offset, group_size, my_pos)) THEN
    2751             :                   radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
    2752             :                                                     lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
    2753             :                                                     zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
    2754      483330 :                                                     prefactor=1.0_dp, cutoff=1.0_dp)
    2755             : 
    2756             :                   CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), la_min(iset), &
    2757             :                                              0, 0.0_dp, 0, &
    2758             :                                              ra, (/0.0_dp, 0.0_dp, 0.0_dp/), &
    2759             :                                              scale, pab, na1 - 1, 0, rs_rho(igrid_level), &
    2760      483330 :                                              radius=radius, ga_gb_function=GRID_FUNC_AB)
    2761             :                END IF
    2762             : 
    2763             :             END DO
    2764             : 
    2765      566434 :             offset = offset + nsgfa(iset)
    2766             : 
    2767             :          END DO
    2768             : 
    2769             :       END DO
    2770             : 
    2771       92814 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    2772             :          CALL transfer_rs2pw(rs_rho(igrid_level), &
    2773       92814 :                              mgrid_rspace(igrid_level))
    2774             :       END DO
    2775             : 
    2776       18594 :       CALL pw_zero(rho_gspace)
    2777       92814 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    2778             :          CALL pw_transfer(mgrid_rspace(igrid_level), &
    2779       74220 :                           mgrid_gspace(igrid_level))
    2780       92814 :          CALL pw_axpy(mgrid_gspace(igrid_level), rho_gspace)
    2781             :       END DO
    2782             : 
    2783       18594 :       CALL pw_transfer(rho_gspace, rho)
    2784             : 
    2785             :       ! Release work storage
    2786       18594 :       DEALLOCATE (eigenvector)
    2787             : 
    2788       18594 :       DEALLOCATE (pab)
    2789             : 
    2790       18594 :       DEALLOCATE (work)
    2791             : 
    2792             :       ! give back the pw multi-grids
    2793       18594 :       CALL pw_pools_give_back_pws(pw_pools, mgrid_gspace)
    2794       18594 :       CALL pw_pools_give_back_pws(pw_pools, mgrid_rspace)
    2795             : 
    2796       18594 :       CALL timestop(handle)
    2797             : 
    2798      128720 :    END SUBROUTINE calculate_wavefunction
    2799             : 
    2800             : END MODULE qs_collocate_density

Generated by: LCOV version 1.15