LCOV - code coverage report
Current view: top level - src - qs_integrate_potential_single.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:262480d) Lines: 476 571 83.4 %
Date: 2024-11-22 07:00:40 Functions: 7 7 100.0 %

          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 Build up the plane wave density by collocating the primitive Gaussian
      10             : !>      functions (pgf).
      11             : !> \par History
      12             : !>      Joost VandeVondele (02.2002)
      13             : !>            1) rewrote collocate_pgf for increased accuracy and speed
      14             : !>            2) collocate_core hack for PGI compiler
      15             : !>            3) added multiple grid feature
      16             : !>            4) new way to go over the grid
      17             : !>      Joost VandeVondele (05.2002)
      18             : !>            1) prelim. introduction of the real space grid type
      19             : !>      JGH [30.08.02] multigrid arrays independent from potential
      20             : !>      JGH [17.07.03] distributed real space code
      21             : !>      JGH [23.11.03] refactoring and new loop ordering
      22             : !>      JGH [04.12.03] OpneMP parallelization of main loops
      23             : !>      Joost VandeVondele (12.2003)
      24             : !>           1) modified to compute tau
      25             : !>      Joost removed incremental build feature
      26             : !>      Joost introduced map consistent
      27             : !>      Rewrote grid integration/collocation routines, [Joost VandeVondele,03.2007]
      28             : !> \author Matthias Krack (03.04.2001)
      29             : ! **************************************************************************************************
      30             : MODULE qs_integrate_potential_single
      31             :    USE ao_util,                         ONLY: exp_radius_very_extended
      32             :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      33             :                                               get_atomic_kind,&
      34             :                                               get_atomic_kind_set
      35             :    USE atprop_types,                    ONLY: atprop_array_init,&
      36             :                                               atprop_type
      37             :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      38             :                                               gto_basis_set_type
      39             :    USE cell_types,                      ONLY: cell_type,&
      40             :                                               pbc
      41             :    USE cp_control_types,                ONLY: dft_control_type
      42             :    USE cp_dbcsr_api,                    ONLY: dbcsr_get_block_p,&
      43             :                                               dbcsr_type
      44             :    USE external_potential_types,        ONLY: get_potential,&
      45             :                                               gth_potential_type
      46             :    USE gaussian_gridlevels,             ONLY: gaussian_gridlevel,&
      47             :                                               gridlevel_info_type
      48             :    USE grid_api,                        ONLY: integrate_pgf_product
      49             :    USE kinds,                           ONLY: dp
      50             :    USE lri_environment_types,           ONLY: lri_kind_type
      51             :    USE memory_utilities,                ONLY: reallocate
      52             :    USE message_passing,                 ONLY: mp_para_env_type
      53             :    USE orbital_pointers,                ONLY: coset,&
      54             :                                               ncoset
      55             :    USE particle_types,                  ONLY: particle_type
      56             :    USE pw_env_types,                    ONLY: pw_env_get,&
      57             :                                               pw_env_type
      58             :    USE pw_types,                        ONLY: pw_r3d_rs_type
      59             :    USE qs_environment_types,            ONLY: get_qs_env,&
      60             :                                               qs_environment_type
      61             :    USE qs_force_types,                  ONLY: qs_force_type
      62             :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      63             :                                               get_qs_kind_set,&
      64             :                                               qs_kind_type
      65             :    USE realspace_grid_types,            ONLY: map_gaussian_here,&
      66             :                                               realspace_grid_type,&
      67             :                                               rs_grid_zero,&
      68             :                                               transfer_pw2rs
      69             :    USE rs_pw_interface,                 ONLY: potential_pw2rs
      70             :    USE virial_types,                    ONLY: virial_type
      71             : #include "./base/base_uses.f90"
      72             : 
      73             :    IMPLICIT NONE
      74             : 
      75             :    PRIVATE
      76             : 
      77             :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .FALSE.
      78             : 
      79             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_integrate_potential_single'
      80             : 
      81             : ! *** Public subroutines ***
      82             : ! *** Don't include this routines directly, use the interface to
      83             : ! *** qs_integrate_potential
      84             : 
      85             :    PUBLIC :: integrate_v_rspace_one_center, &
      86             :              integrate_v_rspace_diagonal, &
      87             :              integrate_v_core_rspace, &
      88             :              integrate_v_gaussian_rspace, &
      89             :              integrate_function, &
      90             :              integrate_ppl_rspace, &
      91             :              integrate_rho_nlcc
      92             : 
      93             : CONTAINS
      94             : 
      95             : ! **************************************************************************************************
      96             : !> \brief computes the forces/virial due to the local pseudopotential
      97             : !> \param rho_rspace ...
      98             : !> \param qs_env ...
      99             : ! **************************************************************************************************
     100          14 :    SUBROUTINE integrate_ppl_rspace(rho_rspace, qs_env)
     101             :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: rho_rspace
     102             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     103             : 
     104             :       CHARACTER(len=*), PARAMETER :: routineN = 'integrate_ppl_rspace'
     105             : 
     106             :       INTEGER                                            :: atom_a, handle, iatom, ikind, j, lppl, &
     107             :                                                             n, natom_of_kind, ni, npme
     108          14 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores
     109             :       LOGICAL                                            :: use_virial
     110             :       REAL(KIND=dp)                                      :: alpha, eps_rho_rspace, radius
     111             :       REAL(KIND=dp), DIMENSION(3)                        :: force_a, force_b, ra
     112             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: my_virial_a, my_virial_b
     113          14 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: cexp_ppl
     114          14 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: hab, pab
     115          14 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     116             :       TYPE(cell_type), POINTER                           :: cell
     117             :       TYPE(dft_control_type), POINTER                    :: dft_control
     118             :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     119          14 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     120             :       TYPE(pw_env_type), POINTER                         :: pw_env
     121          14 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     122          14 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     123             :       TYPE(realspace_grid_type), POINTER                 :: rs_v
     124             :       TYPE(virial_type), POINTER                         :: virial
     125             : 
     126          14 :       CALL timeset(routineN, handle)
     127             : 
     128          14 :       NULLIFY (pw_env, cores)
     129             : 
     130          14 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
     131          14 :       CALL pw_env_get(pw_env=pw_env, auxbas_rs_grid=rs_v)
     132             : 
     133          14 :       CALL transfer_pw2rs(rs_v, rho_rspace)
     134             : 
     135             :       CALL get_qs_env(qs_env=qs_env, &
     136             :                       atomic_kind_set=atomic_kind_set, &
     137             :                       qs_kind_set=qs_kind_set, &
     138             :                       cell=cell, &
     139             :                       dft_control=dft_control, &
     140             :                       particle_set=particle_set, &
     141             :                       pw_env=pw_env, &
     142          14 :                       force=force, virial=virial)
     143             : 
     144          14 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     145             : 
     146          14 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     147             : 
     148          34 :       DO ikind = 1, SIZE(atomic_kind_set)
     149             : 
     150          20 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
     151          20 :          CALL get_qs_kind(qs_kind_set(ikind), gth_potential=gth_potential)
     152             : 
     153          20 :          IF (.NOT. ASSOCIATED(gth_potential)) CYCLE
     154          20 :          CALL get_potential(potential=gth_potential, alpha_ppl=alpha, nexp_ppl=lppl, cexp_ppl=cexp_ppl)
     155             : 
     156          20 :          IF (lppl <= 0) CYCLE
     157             : 
     158          20 :          ni = ncoset(2*lppl - 2)
     159         100 :          ALLOCATE (hab(ni, 1), pab(ni, 1))
     160         240 :          pab = 0._dp
     161             : 
     162          20 :          CALL reallocate(cores, 1, natom_of_kind)
     163          20 :          npme = 0
     164          70 :          cores = 0
     165             : 
     166             :          ! prepare core function
     167          60 :          DO j = 1, lppl
     168          20 :             SELECT CASE (j)
     169             :             CASE (1)
     170          20 :                pab(1, 1) = cexp_ppl(1)
     171             :             CASE (2)
     172          20 :                n = coset(2, 0, 0)
     173          20 :                pab(n, 1) = cexp_ppl(2)
     174          20 :                n = coset(0, 2, 0)
     175          20 :                pab(n, 1) = cexp_ppl(2)
     176          20 :                n = coset(0, 0, 2)
     177          20 :                pab(n, 1) = cexp_ppl(2)
     178             :             CASE (3)
     179           0 :                n = coset(4, 0, 0)
     180           0 :                pab(n, 1) = cexp_ppl(3)
     181           0 :                n = coset(0, 4, 0)
     182           0 :                pab(n, 1) = cexp_ppl(3)
     183           0 :                n = coset(0, 0, 4)
     184           0 :                pab(n, 1) = cexp_ppl(3)
     185           0 :                n = coset(2, 2, 0)
     186           0 :                pab(n, 1) = 2._dp*cexp_ppl(3)
     187           0 :                n = coset(2, 0, 2)
     188           0 :                pab(n, 1) = 2._dp*cexp_ppl(3)
     189           0 :                n = coset(0, 2, 2)
     190           0 :                pab(n, 1) = 2._dp*cexp_ppl(3)
     191             :             CASE (4)
     192           0 :                n = coset(6, 0, 0)
     193           0 :                pab(n, 1) = cexp_ppl(4)
     194           0 :                n = coset(0, 6, 0)
     195           0 :                pab(n, 1) = cexp_ppl(4)
     196           0 :                n = coset(0, 0, 6)
     197           0 :                pab(n, 1) = cexp_ppl(4)
     198           0 :                n = coset(4, 2, 0)
     199           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     200           0 :                n = coset(4, 0, 2)
     201           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     202           0 :                n = coset(2, 4, 0)
     203           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     204           0 :                n = coset(2, 0, 4)
     205           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     206           0 :                n = coset(0, 4, 2)
     207           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     208           0 :                n = coset(0, 2, 4)
     209           0 :                pab(n, 1) = 3._dp*cexp_ppl(4)
     210           0 :                n = coset(2, 2, 2)
     211           0 :                pab(n, 1) = 6._dp*cexp_ppl(4)
     212             :             CASE DEFAULT
     213          40 :                CPABORT("")
     214             :             END SELECT
     215             :          END DO
     216             : 
     217          70 :          DO iatom = 1, natom_of_kind
     218          50 :             atom_a = atom_list(iatom)
     219          50 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
     220          70 :             IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
     221             :                ! replicated realspace grid, split the atoms up between procs
     222          50 :                IF (MODULO(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
     223          25 :                   npme = npme + 1
     224          25 :                   cores(npme) = iatom
     225             :                END IF
     226             :             ELSE
     227           0 :                npme = npme + 1
     228           0 :                cores(npme) = iatom
     229             :             END IF
     230             :          END DO
     231             : 
     232          45 :          DO j = 1, npme
     233             : 
     234          25 :             iatom = cores(j)
     235          25 :             atom_a = atom_list(iatom)
     236          25 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
     237         275 :             hab(:, 1) = 0.0_dp
     238          25 :             force_a(:) = 0.0_dp
     239          25 :             force_b(:) = 0.0_dp
     240          25 :             IF (use_virial) THEN
     241           0 :                my_virial_a = 0.0_dp
     242           0 :                my_virial_b = 0.0_dp
     243             :             END IF
     244          25 :             ni = 2*lppl - 2
     245             : 
     246             :             radius = exp_radius_very_extended(la_min=0, la_max=ni, lb_min=0, lb_max=0, &
     247             :                                               ra=ra, rb=ra, rp=ra, &
     248             :                                               zetp=alpha, eps=eps_rho_rspace, &
     249             :                                               pab=pab, o1=0, o2=0, &  ! without map_consistent
     250          25 :                                               prefactor=1.0_dp, cutoff=1.0_dp)
     251             : 
     252             :             CALL integrate_pgf_product(ni, alpha, 0, &
     253             :                                        0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), &
     254             :                                        rs_v, hab, pab=pab, o1=0, o2=0, &
     255             :                                        radius=radius, &
     256             :                                        calculate_forces=.TRUE., force_a=force_a, &
     257             :                                        force_b=force_b, use_virial=use_virial, my_virial_a=my_virial_a, &
     258          25 :                                        my_virial_b=my_virial_b, use_subpatch=.TRUE., subpatch_pattern=0)
     259             : 
     260             :             force(ikind)%gth_ppl(:, iatom) = &
     261         100 :                force(ikind)%gth_ppl(:, iatom) + force_a(:)*rho_rspace%pw_grid%dvol
     262             : 
     263          45 :             IF (use_virial) THEN
     264           0 :                virial%pv_ppl = virial%pv_ppl + my_virial_a*rho_rspace%pw_grid%dvol
     265           0 :                virial%pv_virial = virial%pv_virial + my_virial_a*rho_rspace%pw_grid%dvol
     266           0 :                CPABORT("Virial not debuged for CORE_PPL")
     267             :             END IF
     268             :          END DO
     269             : 
     270          74 :          DEALLOCATE (hab, pab)
     271             : 
     272             :       END DO
     273             : 
     274          14 :       DEALLOCATE (cores)
     275             : 
     276          14 :       CALL timestop(handle)
     277             : 
     278          14 :    END SUBROUTINE integrate_ppl_rspace
     279             : 
     280             : ! **************************************************************************************************
     281             : !> \brief computes the forces/virial due to the nlcc pseudopotential
     282             : !> \param rho_rspace ...
     283             : !> \param qs_env ...
     284             : ! **************************************************************************************************
     285          30 :    SUBROUTINE integrate_rho_nlcc(rho_rspace, qs_env)
     286             :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: rho_rspace
     287             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     288             : 
     289             :       CHARACTER(len=*), PARAMETER :: routineN = 'integrate_rho_nlcc'
     290             : 
     291             :       INTEGER                                            :: atom_a, handle, iatom, iexp_nlcc, ikind, &
     292             :                                                             ithread, j, n, natom, nc, nexp_nlcc, &
     293             :                                                             ni, npme, nthread
     294          30 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores, nct_nlcc
     295             :       LOGICAL                                            :: nlcc, use_virial
     296             :       REAL(KIND=dp)                                      :: alpha, eps_rho_rspace, radius
     297             :       REAL(KIND=dp), DIMENSION(3)                        :: force_a, force_b, ra
     298             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: my_virial_a, my_virial_b
     299          30 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: alpha_nlcc
     300          30 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: cval_nlcc, hab, pab
     301          30 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     302             :       TYPE(cell_type), POINTER                           :: cell
     303             :       TYPE(dft_control_type), POINTER                    :: dft_control
     304             :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     305          30 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     306             :       TYPE(pw_env_type), POINTER                         :: pw_env
     307          30 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     308          30 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     309             :       TYPE(realspace_grid_type), POINTER                 :: rs_v
     310             :       TYPE(virial_type), POINTER                         :: virial
     311             : 
     312          30 :       CALL timeset(routineN, handle)
     313             : 
     314          30 :       NULLIFY (pw_env, cores)
     315             : 
     316          30 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
     317          30 :       CALL pw_env_get(pw_env=pw_env, auxbas_rs_grid=rs_v)
     318             : 
     319          30 :       CALL transfer_pw2rs(rs_v, rho_rspace)
     320             : 
     321             :       CALL get_qs_env(qs_env=qs_env, &
     322             :                       atomic_kind_set=atomic_kind_set, &
     323             :                       qs_kind_set=qs_kind_set, &
     324             :                       cell=cell, &
     325             :                       dft_control=dft_control, &
     326             :                       particle_set=particle_set, &
     327             :                       pw_env=pw_env, &
     328          30 :                       force=force, virial=virial)
     329             : 
     330          30 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     331             : 
     332          30 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     333             : 
     334          74 :       DO ikind = 1, SIZE(atomic_kind_set)
     335             : 
     336          44 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
     337          44 :          CALL get_qs_kind(qs_kind_set(ikind), gth_potential=gth_potential)
     338             : 
     339          44 :          IF (.NOT. ASSOCIATED(gth_potential)) CYCLE
     340             :          CALL get_potential(potential=gth_potential, nlcc_present=nlcc, nexp_nlcc=nexp_nlcc, &
     341          44 :                             alpha_nlcc=alpha_nlcc, nct_nlcc=nct_nlcc, cval_nlcc=cval_nlcc)
     342             : 
     343          44 :          IF (.NOT. nlcc) CYCLE
     344             : 
     345         202 :          DO iexp_nlcc = 1, nexp_nlcc
     346             : 
     347          42 :             alpha = alpha_nlcc(iexp_nlcc)
     348          42 :             nc = nct_nlcc(iexp_nlcc)
     349             : 
     350          42 :             ni = ncoset(2*nc - 2)
     351             : 
     352          42 :             nthread = 1
     353          42 :             ithread = 0
     354             : 
     355         168 :             ALLOCATE (hab(ni, 1), pab(ni, 1))
     356         270 :             pab = 0._dp
     357             : 
     358          42 :             CALL reallocate(cores, 1, natom)
     359          42 :             npme = 0
     360         172 :             cores = 0
     361             : 
     362             :             ! prepare core function
     363         100 :             DO j = 1, nc
     364          42 :                SELECT CASE (j)
     365             :                CASE (1)
     366          42 :                   pab(1, 1) = cval_nlcc(1, iexp_nlcc)
     367             :                CASE (2)
     368          16 :                   n = coset(2, 0, 0)
     369          16 :                   pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
     370          16 :                   n = coset(0, 2, 0)
     371          16 :                   pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
     372          16 :                   n = coset(0, 0, 2)
     373          16 :                   pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
     374             :                CASE (3)
     375           0 :                   n = coset(4, 0, 0)
     376           0 :                   pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
     377           0 :                   n = coset(0, 4, 0)
     378           0 :                   pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
     379           0 :                   n = coset(0, 0, 4)
     380           0 :                   pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
     381           0 :                   n = coset(2, 2, 0)
     382           0 :                   pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
     383           0 :                   n = coset(2, 0, 2)
     384           0 :                   pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
     385           0 :                   n = coset(0, 2, 2)
     386           0 :                   pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
     387             :                CASE (4)
     388           0 :                   n = coset(6, 0, 0)
     389           0 :                   pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
     390           0 :                   n = coset(0, 6, 0)
     391           0 :                   pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
     392           0 :                   n = coset(0, 0, 6)
     393           0 :                   pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
     394           0 :                   n = coset(4, 2, 0)
     395           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     396           0 :                   n = coset(4, 0, 2)
     397           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     398           0 :                   n = coset(2, 4, 0)
     399           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     400           0 :                   n = coset(2, 0, 4)
     401           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     402           0 :                   n = coset(0, 4, 2)
     403           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     404           0 :                   n = coset(0, 2, 4)
     405           0 :                   pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     406           0 :                   n = coset(2, 2, 2)
     407           0 :                   pab(n, 1) = 6._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
     408             :                CASE DEFAULT
     409          58 :                   CPABORT("")
     410             :                END SELECT
     411             :             END DO
     412          42 :             IF (dft_control%nspins == 2) pab = pab*0.5_dp
     413             : 
     414         172 :             DO iatom = 1, natom
     415         130 :                atom_a = atom_list(iatom)
     416         130 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
     417         172 :                IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
     418             :                   ! replicated realspace grid, split the atoms up between procs
     419         130 :                   IF (MODULO(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
     420          65 :                      npme = npme + 1
     421          65 :                      cores(npme) = iatom
     422             :                   END IF
     423             :                ELSE
     424           0 :                   npme = npme + 1
     425           0 :                   cores(npme) = iatom
     426             :                END IF
     427             :             END DO
     428             : 
     429         107 :             DO j = 1, npme
     430             : 
     431          65 :                iatom = cores(j)
     432          65 :                atom_a = atom_list(iatom)
     433          65 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
     434         274 :                hab(:, 1) = 0.0_dp
     435          65 :                force_a(:) = 0.0_dp
     436          65 :                force_b(:) = 0.0_dp
     437          65 :                IF (use_virial) THEN
     438          48 :                   my_virial_a = 0.0_dp
     439          48 :                   my_virial_b = 0.0_dp
     440             :                END IF
     441          65 :                ni = 2*nc - 2
     442             : 
     443             :                radius = exp_radius_very_extended(la_min=0, la_max=ni, lb_min=0, lb_max=0, &
     444             :                                                  ra=ra, rb=ra, rp=ra, &
     445             :                                                  zetp=1/(2*alpha**2), eps=eps_rho_rspace, &
     446             :                                                  pab=pab, o1=0, o2=0, &  ! without map_consistent
     447          65 :                                                  prefactor=1.0_dp, cutoff=1.0_dp)
     448             : 
     449             :                CALL integrate_pgf_product(ni, 1/(2*alpha**2), 0, &
     450             :                                           0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), &
     451             :                                           rs_v, hab, pab=pab, o1=0, o2=0, &
     452             :                                           radius=radius, &
     453             :                                           calculate_forces=.TRUE., force_a=force_a, &
     454             :                                           force_b=force_b, use_virial=use_virial, my_virial_a=my_virial_a, &
     455          65 :                                           my_virial_b=my_virial_b, use_subpatch=.TRUE., subpatch_pattern=0)
     456             : 
     457             :                force(ikind)%gth_nlcc(:, iatom) = &
     458         260 :                   force(ikind)%gth_nlcc(:, iatom) + force_a(:)*rho_rspace%pw_grid%dvol
     459             : 
     460         107 :                IF (use_virial) THEN
     461         624 :                   virial%pv_nlcc = virial%pv_nlcc + my_virial_a*rho_rspace%pw_grid%dvol
     462         624 :                   virial%pv_virial = virial%pv_virial + my_virial_a*rho_rspace%pw_grid%dvol
     463             :                END IF
     464             :             END DO
     465             : 
     466          86 :             DEALLOCATE (hab, pab)
     467             : 
     468             :          END DO
     469             : 
     470             :       END DO
     471             : 
     472          30 :       DEALLOCATE (cores)
     473             : 
     474          30 :       CALL timestop(handle)
     475             : 
     476          30 :    END SUBROUTINE integrate_rho_nlcc
     477             : 
     478             : ! **************************************************************************************************
     479             : !> \brief computes the forces/virial due to the ionic cores with a potential on
     480             : !>      grid
     481             : !> \param v_rspace ...
     482             : !> \param qs_env ...
     483             : !> \param atecc ...
     484             : ! **************************************************************************************************
     485        7263 :    SUBROUTINE integrate_v_core_rspace(v_rspace, qs_env, atecc)
     486             :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: v_rspace
     487             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     488             :       REAL(KIND=dp), DIMENSION(:), OPTIONAL              :: atecc
     489             : 
     490             :       CHARACTER(len=*), PARAMETER :: routineN = 'integrate_v_core_rspace'
     491             : 
     492             :       INTEGER                                            :: atom_a, handle, iatom, ikind, j, natom, &
     493             :                                                             natom_of_kind, npme
     494        7263 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores
     495             :       LOGICAL                                            :: paw_atom, skip_fcore, use_virial
     496             :       REAL(KIND=dp)                                      :: alpha_core_charge, ccore_charge, &
     497             :                                                             eps_rho_rspace, radius
     498             :       REAL(KIND=dp), DIMENSION(3)                        :: force_a, force_b, ra
     499             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: my_virial_a, my_virial_b
     500        7263 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: hab, pab
     501        7263 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     502             :       TYPE(atprop_type), POINTER                         :: atprop
     503             :       TYPE(cell_type), POINTER                           :: cell
     504             :       TYPE(dft_control_type), POINTER                    :: dft_control
     505        7263 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     506             :       TYPE(pw_env_type), POINTER                         :: pw_env
     507        7263 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     508        7263 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     509             :       TYPE(realspace_grid_type), POINTER                 :: rs_v
     510             :       TYPE(virial_type), POINTER                         :: virial
     511             : 
     512        7263 :       CALL timeset(routineN, handle)
     513        7263 :       NULLIFY (virial, force, atprop, dft_control)
     514             : 
     515        7263 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
     516             : 
     517             :       !If gapw, check for gpw kinds
     518        7263 :       skip_fcore = .FALSE.
     519        7263 :       IF (dft_control%qs_control%gapw) THEN
     520         496 :          IF (.NOT. dft_control%qs_control%gapw_control%nopaw_as_gpw) skip_fcore = .TRUE.
     521             :       END IF
     522             : 
     523             :       IF (.NOT. skip_fcore) THEN
     524        6823 :          NULLIFY (pw_env)
     525        6823 :          ALLOCATE (cores(1))
     526        6823 :          ALLOCATE (hab(1, 1))
     527        6823 :          ALLOCATE (pab(1, 1))
     528             : 
     529        6823 :          CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
     530        6823 :          CALL pw_env_get(pw_env=pw_env, auxbas_rs_grid=rs_v)
     531             : 
     532        6823 :          CALL transfer_pw2rs(rs_v, v_rspace)
     533             : 
     534             :          CALL get_qs_env(qs_env=qs_env, &
     535             :                          atomic_kind_set=atomic_kind_set, &
     536             :                          qs_kind_set=qs_kind_set, &
     537             :                          cell=cell, &
     538             :                          dft_control=dft_control, &
     539             :                          particle_set=particle_set, &
     540             :                          pw_env=pw_env, &
     541             :                          force=force, &
     542             :                          virial=virial, &
     543        6823 :                          atprop=atprop)
     544             : 
     545             :          ! atomic energy contributions
     546        6823 :          natom = SIZE(particle_set)
     547        6823 :          IF (ASSOCIATED(atprop)) THEN
     548        6823 :             CALL atprop_array_init(atprop%ateb, natom)
     549             :          END IF
     550             : 
     551        6823 :          use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     552             : 
     553        6823 :          eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     554             : 
     555       18799 :          DO ikind = 1, SIZE(atomic_kind_set)
     556             : 
     557       11976 :             CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
     558             :             CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom, &
     559             :                              alpha_core_charge=alpha_core_charge, &
     560       11976 :                              ccore_charge=ccore_charge)
     561             : 
     562       11976 :             IF (dft_control%qs_control%gapw .AND. paw_atom) CYCLE
     563             : 
     564       11914 :             pab(1, 1) = -ccore_charge
     565       11914 :             IF (alpha_core_charge == 0.0_dp .OR. pab(1, 1) == 0.0_dp) CYCLE
     566             : 
     567       11878 :             CALL reallocate(cores, 1, natom_of_kind)
     568       11878 :             npme = 0
     569       36015 :             cores = 0
     570             : 
     571       36015 :             DO iatom = 1, natom_of_kind
     572       24137 :                atom_a = atom_list(iatom)
     573       24137 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
     574       36015 :                IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
     575             :                   ! replicated realspace grid, split the atoms up between procs
     576       23388 :                   IF (MODULO(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
     577       11694 :                      npme = npme + 1
     578       11694 :                      cores(npme) = iatom
     579             :                   END IF
     580             :                ELSE
     581         749 :                   npme = npme + 1
     582         749 :                   cores(npme) = iatom
     583             :                END IF
     584             :             END DO
     585             : 
     586       43120 :             DO j = 1, npme
     587             : 
     588       12443 :                iatom = cores(j)
     589       12443 :                atom_a = atom_list(iatom)
     590       12443 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
     591       12443 :                hab(1, 1) = 0.0_dp
     592       12443 :                force_a(:) = 0.0_dp
     593       12443 :                force_b(:) = 0.0_dp
     594       12443 :                IF (use_virial) THEN
     595        1558 :                   my_virial_a = 0.0_dp
     596        1558 :                   my_virial_b = 0.0_dp
     597             :                END IF
     598             : 
     599             :                radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
     600             :                                                  ra=ra, rb=ra, rp=ra, &
     601             :                                                  zetp=alpha_core_charge, eps=eps_rho_rspace, &
     602             :                                                  pab=pab, o1=0, o2=0, &  ! without map_consistent
     603       12443 :                                                  prefactor=1.0_dp, cutoff=1.0_dp)
     604             : 
     605             :                CALL integrate_pgf_product(0, alpha_core_charge, 0, &
     606             :                                           0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), &
     607             :                                           rs_v, hab, pab=pab, o1=0, o2=0, &
     608             :                                           radius=radius, &
     609             :                                           calculate_forces=.TRUE., force_a=force_a, &
     610             :                                           force_b=force_b, use_virial=use_virial, my_virial_a=my_virial_a, &
     611       12443 :                                           my_virial_b=my_virial_b, use_subpatch=.TRUE., subpatch_pattern=0)
     612             : 
     613       12443 :                IF (ASSOCIATED(force)) THEN
     614       49384 :                   force(ikind)%rho_core(:, iatom) = force(ikind)%rho_core(:, iatom) + force_a(:)
     615             :                END IF
     616       12443 :                IF (use_virial) THEN
     617       20254 :                   virial%pv_ehartree = virial%pv_ehartree + my_virial_a
     618       20254 :                   virial%pv_virial = virial%pv_virial + my_virial_a
     619             :                END IF
     620       12443 :                IF (ASSOCIATED(atprop)) THEN
     621       12443 :                   atprop%ateb(atom_a) = atprop%ateb(atom_a) + 0.5_dp*hab(1, 1)*pab(1, 1)
     622             :                END IF
     623       24419 :                IF (PRESENT(atecc)) THEN
     624          47 :                   atecc(atom_a) = atecc(atom_a) + 0.5_dp*hab(1, 1)*pab(1, 1)
     625             :                END IF
     626             : 
     627             :             END DO
     628             : 
     629             :          END DO
     630             : 
     631        6823 :          DEALLOCATE (hab, pab, cores)
     632             : 
     633             :       END IF
     634             : 
     635        7263 :       CALL timestop(handle)
     636             : 
     637        7263 :    END SUBROUTINE integrate_v_core_rspace
     638             : 
     639             : ! **************************************************************************************************
     640             : !> \brief computes the overlap of a set of Gaussians with a potential on grid
     641             : !> \param v_rspace ...
     642             : !> \param qs_env ...
     643             : !> \param alpha ...
     644             : !> \param ccore ...
     645             : !> \param atecc ...
     646             : ! **************************************************************************************************
     647           2 :    SUBROUTINE integrate_v_gaussian_rspace(v_rspace, qs_env, alpha, ccore, atecc)
     648             :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: v_rspace
     649             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     650             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: alpha, ccore
     651             :       REAL(KIND=dp), DIMENSION(:)                        :: atecc
     652             : 
     653             :       CHARACTER(len=*), PARAMETER :: routineN = 'integrate_v_gaussian_rspace'
     654             : 
     655             :       INTEGER                                            :: atom_a, handle, iatom, ikind, j, natom, &
     656             :                                                             natom_of_kind, npme
     657           2 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores
     658             :       REAL(KIND=dp)                                      :: alpha_core_charge, eps_rho_rspace, radius
     659             :       REAL(KIND=dp), DIMENSION(3)                        :: ra
     660           2 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: hab, pab
     661           2 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     662             :       TYPE(cell_type), POINTER                           :: cell
     663             :       TYPE(dft_control_type), POINTER                    :: dft_control
     664           2 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     665             :       TYPE(pw_env_type), POINTER                         :: pw_env
     666           2 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     667             :       TYPE(realspace_grid_type), POINTER                 :: rs_v
     668             : 
     669           2 :       CALL timeset(routineN, handle)
     670             : 
     671           2 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
     672             : 
     673             :       !If gapw, check for gpw kinds
     674           2 :       CPASSERT(.NOT. dft_control%qs_control%gapw)
     675             : 
     676           2 :       NULLIFY (pw_env)
     677           2 :       ALLOCATE (cores(1))
     678           2 :       ALLOCATE (hab(1, 1))
     679           2 :       ALLOCATE (pab(1, 1))
     680             : 
     681           2 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
     682           2 :       CALL pw_env_get(pw_env=pw_env, auxbas_rs_grid=rs_v)
     683             : 
     684           2 :       CALL transfer_pw2rs(rs_v, v_rspace)
     685             : 
     686             :       CALL get_qs_env(qs_env=qs_env, &
     687             :                       atomic_kind_set=atomic_kind_set, &
     688             :                       qs_kind_set=qs_kind_set, &
     689             :                       cell=cell, &
     690             :                       dft_control=dft_control, &
     691             :                       particle_set=particle_set, &
     692           2 :                       pw_env=pw_env)
     693             : 
     694             :       ! atomic energy contributions
     695           2 :       natom = SIZE(particle_set)
     696           2 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     697             : 
     698           6 :       DO ikind = 1, SIZE(atomic_kind_set)
     699             : 
     700           4 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
     701           4 :          pab(1, 1) = -ccore(ikind)
     702           4 :          alpha_core_charge = alpha(ikind)
     703           4 :          IF (alpha_core_charge == 0.0_dp .OR. pab(1, 1) == 0.0_dp) CYCLE
     704             : 
     705           4 :          CALL reallocate(cores, 1, natom_of_kind)
     706           4 :          npme = 0
     707          10 :          cores = 0
     708             : 
     709          10 :          DO iatom = 1, natom_of_kind
     710           6 :             atom_a = atom_list(iatom)
     711           6 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
     712          10 :             IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
     713             :                ! replicated realspace grid, split the atoms up between procs
     714           6 :                IF (MODULO(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
     715           3 :                   npme = npme + 1
     716           3 :                   cores(npme) = iatom
     717             :                END IF
     718             :             ELSE
     719           0 :                npme = npme + 1
     720           0 :                cores(npme) = iatom
     721             :             END IF
     722             :          END DO
     723             : 
     724          13 :          DO j = 1, npme
     725             : 
     726           3 :             iatom = cores(j)
     727           3 :             atom_a = atom_list(iatom)
     728           3 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
     729           3 :             hab(1, 1) = 0.0_dp
     730             : 
     731             :             radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
     732             :                                               ra=ra, rb=ra, rp=ra, &
     733             :                                               zetp=alpha_core_charge, eps=eps_rho_rspace, &
     734             :                                               pab=pab, o1=0, o2=0, &  ! without map_consistent
     735           3 :                                               prefactor=1.0_dp, cutoff=1.0_dp)
     736             : 
     737             :             CALL integrate_pgf_product(0, alpha_core_charge, 0, &
     738             :                                        0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), &
     739             :                                        rs_v, hab, pab=pab, o1=0, o2=0, &
     740             :                                        radius=radius, calculate_forces=.FALSE., &
     741           3 :                                        use_subpatch=.TRUE., subpatch_pattern=0)
     742           7 :             atecc(atom_a) = atecc(atom_a) + 0.5_dp*hab(1, 1)*pab(1, 1)
     743             : 
     744             :          END DO
     745             : 
     746             :       END DO
     747             : 
     748           2 :       DEALLOCATE (hab, pab, cores)
     749             : 
     750           2 :       CALL timestop(handle)
     751             : 
     752           2 :    END SUBROUTINE integrate_v_gaussian_rspace
     753             : ! **************************************************************************************************
     754             : !> \brief computes integrals of product of v_rspace times a one-center function
     755             : !>        required for LRIGPW
     756             : !> \param v_rspace ...
     757             : !> \param qs_env ...
     758             : !> \param int_res ...
     759             : !> \param calculate_forces ...
     760             : !> \param basis_type ...
     761             : !> \param atomlist ...
     762             : !> \author Dorothea Golze
     763             : ! **************************************************************************************************
     764         862 :    SUBROUTINE integrate_v_rspace_one_center(v_rspace, qs_env, int_res, &
     765         862 :                                             calculate_forces, basis_type, atomlist)
     766             :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: v_rspace
     767             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     768             :       TYPE(lri_kind_type), DIMENSION(:), POINTER         :: int_res
     769             :       LOGICAL, INTENT(IN)                                :: calculate_forces
     770             :       CHARACTER(len=*), INTENT(IN)                       :: basis_type
     771             :       INTEGER, DIMENSION(:), OPTIONAL                    :: atomlist
     772             : 
     773             :       CHARACTER(len=*), PARAMETER :: routineN = 'integrate_v_rspace_one_center'
     774             : 
     775             :       INTEGER :: atom_a, group_size, handle, i, iatom, igrid_level, ikind, ipgf, iset, m1, maxco, &
     776             :          maxsgf_set, my_pos, na1, natom_of_kind, ncoa, nkind, nseta, offset, sgfa
     777         862 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, la_max, la_min, npgfa, &
     778         862 :                                                             nsgf_seta
     779         862 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa
     780             :       LOGICAL                                            :: use_virial
     781         862 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: map_it
     782             :       REAL(KIND=dp)                                      :: eps_rho_rspace, radius
     783             :       REAL(KIND=dp), DIMENSION(3)                        :: force_a, force_b, ra
     784             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: my_virial_a, my_virial_b
     785         862 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a
     786         862 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: hab, pab, rpgfa, sphi_a, work_f, work_i, &
     787         862 :                                                             zeta
     788         862 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     789             :       TYPE(cell_type), POINTER                           :: cell
     790             :       TYPE(dft_control_type), POINTER                    :: dft_control
     791             :       TYPE(gridlevel_info_type), POINTER                 :: gridlevel_info
     792             :       TYPE(gto_basis_set_type), POINTER                  :: lri_basis_set
     793         862 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     794             :       TYPE(pw_env_type), POINTER                         :: pw_env
     795         862 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     796         862 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_v
     797             :       TYPE(realspace_grid_type), POINTER                 :: rs_grid
     798             :       TYPE(virial_type), POINTER                         :: virial
     799             : 
     800         862 :       CALL timeset(routineN, handle)
     801             : 
     802         862 :       NULLIFY (atomic_kind_set, qs_kind_set, atom_list, cell, dft_control, &
     803         862 :                first_sgfa, gridlevel_info, hab, la_max, la_min, lri_basis_set, &
     804         862 :                npgfa, nsgf_seta, pab, particle_set, pw_env, rpgfa, &
     805         862 :                rs_grid, rs_v, virial, set_radius_a, sphi_a, work_f, &
     806         862 :                work_i, zeta)
     807             : 
     808         862 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
     809             : 
     810         862 :       CALL pw_env_get(pw_env, rs_grids=rs_v)
     811        4280 :       DO i = 1, SIZE(rs_v)
     812        4280 :          CALL rs_grid_zero(rs_v(i))
     813             :       END DO
     814             : 
     815         862 :       gridlevel_info => pw_env%gridlevel_info
     816             : 
     817         862 :       CALL potential_pw2rs(rs_v, v_rspace, pw_env)
     818             : 
     819             :       CALL get_qs_env(qs_env=qs_env, &
     820             :                       atomic_kind_set=atomic_kind_set, &
     821             :                       qs_kind_set=qs_kind_set, &
     822             :                       cell=cell, &
     823             :                       dft_control=dft_control, &
     824             :                       nkind=nkind, &
     825             :                       particle_set=particle_set, &
     826             :                       pw_env=pw_env, &
     827         862 :                       virial=virial)
     828             : 
     829         862 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     830             : 
     831         862 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     832             : 
     833         862 :       offset = 0
     834         862 :       my_pos = v_rspace%pw_grid%para%group%mepos
     835         862 :       group_size = v_rspace%pw_grid%para%group%num_pe
     836             : 
     837        2570 :       DO ikind = 1, nkind
     838             : 
     839        1708 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
     840        1708 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=lri_basis_set, basis_type=basis_type)
     841             :          CALL get_gto_basis_set(gto_basis_set=lri_basis_set, &
     842             :                                 first_sgf=first_sgfa, &
     843             :                                 lmax=la_max, &
     844             :                                 lmin=la_min, &
     845             :                                 maxco=maxco, &
     846             :                                 maxsgf_set=maxsgf_set, &
     847             :                                 npgf=npgfa, &
     848             :                                 nset=nseta, &
     849             :                                 nsgf_set=nsgf_seta, &
     850             :                                 pgf_radius=rpgfa, &
     851             :                                 set_radius=set_radius_a, &
     852             :                                 sphi=sphi_a, &
     853        1708 :                                 zet=zeta)
     854             : 
     855        6832 :          ALLOCATE (hab(maxco, 1), pab(maxco, 1))
     856       45412 :          hab = 0._dp
     857       43704 :          pab(:, 1) = 0._dp
     858             : 
     859        4950 :          DO iatom = 1, natom_of_kind
     860             : 
     861        3242 :             atom_a = atom_list(iatom)
     862        3242 :             IF (PRESENT(atomlist)) THEN
     863         400 :                IF (atomlist(atom_a) == 0) CYCLE
     864             :             END IF
     865        3042 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
     866        3042 :             force_a(:) = 0._dp
     867        3042 :             force_b(:) = 0._dp
     868        3042 :             my_virial_a(:, :) = 0._dp
     869        3042 :             my_virial_b(:, :) = 0._dp
     870             : 
     871       44304 :             m1 = MAXVAL(npgfa(1:nseta))
     872        9126 :             ALLOCATE (map_it(m1))
     873             : 
     874       44304 :             DO iset = 1, nseta
     875             :                !
     876       86728 :                map_it = .FALSE.
     877       86536 :                DO ipgf = 1, npgfa(iset)
     878       45274 :                   igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
     879       45274 :                   rs_grid => rs_v(igrid_level)
     880       86536 :                   map_it(ipgf) = map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)
     881             :                END DO
     882       41262 :                offset = offset + 1
     883             :                !
     884       66941 :                IF (ANY(map_it(1:npgfa(iset)))) THEN
     885       20631 :                   sgfa = first_sgfa(1, iset)
     886       20631 :                   ncoa = npgfa(iset)*ncoset(la_max(iset))
     887      435578 :                   hab(:, 1) = 0._dp
     888       61893 :                   ALLOCATE (work_i(nsgf_seta(iset), 1))
     889      202340 :                   work_i = 0.0_dp
     890             : 
     891             :                   ! get fit coefficients for forces
     892       20631 :                   IF (calculate_forces) THEN
     893         895 :                      m1 = sgfa + nsgf_seta(iset) - 1
     894        1790 :                      ALLOCATE (work_f(nsgf_seta(iset), 1))
     895        6465 :                      work_f(1:nsgf_seta(iset), 1) = int_res(ikind)%acoef(iatom, sgfa:m1)
     896             :                      CALL dgemm("N", "N", ncoa, 1, nsgf_seta(iset), 1.0_dp, sphi_a(1, sgfa), &
     897             :                                 SIZE(sphi_a, 1), work_f(1, 1), SIZE(work_f, 1), 0.0_dp, pab(1, 1), &
     898         895 :                                 SIZE(pab, 1))
     899         895 :                      DEALLOCATE (work_f)
     900             :                   END IF
     901             : 
     902       43268 :                   DO ipgf = 1, npgfa(iset)
     903       22637 :                      na1 = (ipgf - 1)*ncoset(la_max(iset))
     904       22637 :                      igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
     905       22637 :                      rs_grid => rs_v(igrid_level)
     906             : 
     907             :                      radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
     908             :                                                        lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
     909             :                                                        zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
     910       22637 :                                                        prefactor=1.0_dp, cutoff=1.0_dp)
     911             : 
     912       43268 :                      IF (map_it(ipgf)) THEN
     913       22637 :                         IF (.NOT. calculate_forces) THEN
     914             :                            CALL integrate_pgf_product(la_max=la_max(iset), &
     915             :                                                       zeta=zeta(ipgf, iset), la_min=la_min(iset), &
     916             :                                                       lb_max=0, zetb=0.0_dp, lb_min=0, &
     917             :                                                       ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
     918             :                                                       rsgrid=rs_grid, &
     919             :                                                       hab=hab, o1=na1, o2=0, radius=radius, &
     920       21378 :                                                       calculate_forces=calculate_forces)
     921             :                         ELSE
     922             :                            CALL integrate_pgf_product(la_max=la_max(iset), &
     923             :                                                       zeta=zeta(ipgf, iset), la_min=la_min(iset), &
     924             :                                                       lb_max=0, zetb=0.0_dp, lb_min=0, &
     925             :                                                       ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
     926             :                                                       rsgrid=rs_grid, &
     927             :                                                       hab=hab, pab=pab, o1=na1, o2=0, radius=radius, &
     928             :                                                       calculate_forces=calculate_forces, &
     929             :                                                       force_a=force_a, force_b=force_b, &
     930             :                                                       use_virial=use_virial, &
     931        1259 :                                                       my_virial_a=my_virial_a, my_virial_b=my_virial_b)
     932             :                         END IF
     933             :                      END IF
     934             :                   END DO
     935             :                   ! contract hab
     936             :                   CALL dgemm("T", "N", nsgf_seta(iset), 1, ncoa, 1.0_dp, sphi_a(1, sgfa), &
     937       20631 :                              SIZE(sphi_a, 1), hab(1, 1), SIZE(hab, 1), 0.0_dp, work_i(1, 1), SIZE(work_i, 1))
     938             : 
     939             :                   int_res(ikind)%v_int(iatom, sgfa:sgfa - 1 + nsgf_seta(iset)) = &
     940      342787 :                      int_res(ikind)%v_int(iatom, sgfa:sgfa - 1 + nsgf_seta(iset)) + work_i(1:nsgf_seta(iset), 1)
     941       20631 :                   DEALLOCATE (work_i)
     942             :                END IF
     943             :             END DO
     944             :             !
     945        3042 :             IF (calculate_forces) THEN
     946         568 :                int_res(ikind)%v_dfdr(iatom, :) = int_res(ikind)%v_dfdr(iatom, :) + force_a(:)
     947         142 :                IF (use_virial) THEN
     948         156 :                   virial%pv_lrigpw = virial%pv_lrigpw + my_virial_a
     949         156 :                   virial%pv_virial = virial%pv_virial + my_virial_a
     950             :                END IF
     951             :             END IF
     952             : 
     953        4950 :             DEALLOCATE (map_it)
     954             : 
     955             :          END DO
     956             : 
     957        5986 :          DEALLOCATE (hab, pab)
     958             :       END DO
     959             : 
     960         862 :       CALL timestop(handle)
     961             : 
     962        1724 :    END SUBROUTINE integrate_v_rspace_one_center
     963             : 
     964             : ! **************************************************************************************************
     965             : !> \brief computes integrals of product of v_rspace times the diagonal block basis functions
     966             : !>        required for LRIGPW with exact 1c terms
     967             : !> \param v_rspace ...
     968             : !> \param ksmat ...
     969             : !> \param pmat ...
     970             : !> \param qs_env ...
     971             : !> \param calculate_forces ...
     972             : !> \param basis_type ...
     973             : !> \author JGH
     974             : ! **************************************************************************************************
     975          36 :    SUBROUTINE integrate_v_rspace_diagonal(v_rspace, ksmat, pmat, qs_env, calculate_forces, basis_type)
     976             :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: v_rspace
     977             :       TYPE(dbcsr_type), INTENT(INOUT)                    :: ksmat, pmat
     978             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     979             :       LOGICAL, INTENT(IN)                                :: calculate_forces
     980             :       CHARACTER(len=*), INTENT(IN)                       :: basis_type
     981             : 
     982             :       CHARACTER(len=*), PARAMETER :: routineN = 'integrate_v_rspace_diagonal'
     983             : 
     984             :       INTEGER :: atom_a, group_size, handle, iatom, igrid_level, ikind, ipgf, iset, jpgf, jset, &
     985             :          m1, maxco, maxsgf_set, my_pos, na1, na2, natom_of_kind, nb1, nb2, ncoa, ncob, nkind, &
     986             :          nseta, nsgfa, offset, sgfa, sgfb
     987          36 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, la_max, la_min, npgfa, &
     988          36 :                                                             nsgf_seta
     989          36 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa
     990             :       LOGICAL                                            :: found, use_virial
     991          36 :       LOGICAL, ALLOCATABLE, DIMENSION(:, :)              :: map_it2
     992             :       REAL(KIND=dp)                                      :: eps_rho_rspace, radius, zetp
     993             :       REAL(KIND=dp), DIMENSION(3)                        :: force_a, force_b, ra
     994             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: my_virial_a, my_virial_b
     995          36 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a
     996          36 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: h_block, hab, hmat, p_block, pab, pblk, &
     997          36 :                                                             rpgfa, sphi_a, work, zeta
     998          36 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     999             :       TYPE(cell_type), POINTER                           :: cell
    1000             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1001             :       TYPE(gridlevel_info_type), POINTER                 :: gridlevel_info
    1002             :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1003             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1004          36 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1005             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1006          36 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    1007          36 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1008          36 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_v
    1009             :       TYPE(realspace_grid_type), POINTER                 :: rs_grid
    1010             :       TYPE(virial_type), POINTER                         :: virial
    1011             : 
    1012          36 :       CALL timeset(routineN, handle)
    1013             : 
    1014          36 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
    1015          36 :       CALL pw_env_get(pw_env, rs_grids=rs_v)
    1016          36 :       CALL potential_pw2rs(rs_v, v_rspace, pw_env)
    1017             : 
    1018          36 :       gridlevel_info => pw_env%gridlevel_info
    1019             : 
    1020             :       CALL get_qs_env(qs_env=qs_env, &
    1021             :                       atomic_kind_set=atomic_kind_set, &
    1022             :                       qs_kind_set=qs_kind_set, &
    1023             :                       cell=cell, &
    1024             :                       dft_control=dft_control, &
    1025             :                       nkind=nkind, &
    1026             :                       particle_set=particle_set, &
    1027             :                       force=force, &
    1028             :                       virial=virial, &
    1029          36 :                       para_env=para_env)
    1030             : 
    1031          36 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    1032          36 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
    1033             : 
    1034          36 :       offset = 0
    1035          36 :       my_pos = v_rspace%pw_grid%para%group%mepos
    1036          36 :       group_size = v_rspace%pw_grid%para%group%num_pe
    1037             : 
    1038         108 :       DO ikind = 1, nkind
    1039             : 
    1040          72 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
    1041          72 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=basis_type)
    1042             :          CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    1043             :                                 lmax=la_max, lmin=la_min, maxco=maxco, maxsgf_set=maxsgf_set, &
    1044             :                                 npgf=npgfa, nset=nseta, nsgf_set=nsgf_seta, nsgf=nsgfa, &
    1045             :                                 first_sgf=first_sgfa, pgf_radius=rpgfa, set_radius=set_radius_a, &
    1046          72 :                                 sphi=sphi_a, zet=zeta)
    1047             : 
    1048         720 :          ALLOCATE (hab(maxco, maxco), work(maxco, maxsgf_set), hmat(nsgfa, nsgfa))
    1049          72 :          IF (calculate_forces) ALLOCATE (pab(maxco, maxco), pblk(nsgfa, nsgfa))
    1050             : 
    1051         288 :          DO iatom = 1, natom_of_kind
    1052         216 :             atom_a = atom_list(iatom)
    1053         216 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
    1054       17640 :             hmat = 0.0_dp
    1055         216 :             IF (calculate_forces) THEN
    1056           0 :                CALL dbcsr_get_block_p(matrix=pmat, row=atom_a, col=atom_a, BLOCK=p_block, found=found)
    1057           0 :                IF (found) THEN
    1058           0 :                   pblk(1:nsgfa, 1:nsgfa) = p_block(1:nsgfa, 1:nsgfa)
    1059             :                ELSE
    1060           0 :                   pblk = 0.0_dp
    1061             :                END IF
    1062           0 :                CALL para_env%sum(pblk)
    1063           0 :                force_a(:) = 0._dp
    1064           0 :                force_b(:) = 0._dp
    1065           0 :                IF (use_virial) THEN
    1066           0 :                   my_virial_a = 0.0_dp
    1067           0 :                   my_virial_b = 0.0_dp
    1068             :                END IF
    1069             :             END IF
    1070         432 :             m1 = MAXVAL(npgfa(1:nseta))
    1071         864 :             ALLOCATE (map_it2(m1, m1))
    1072         432 :             DO iset = 1, nseta
    1073         216 :                sgfa = first_sgfa(1, iset)
    1074         216 :                ncoa = npgfa(iset)*ncoset(la_max(iset))
    1075         648 :                DO jset = 1, nseta
    1076         216 :                   sgfb = first_sgfa(1, jset)
    1077         216 :                   ncob = npgfa(jset)*ncoset(la_max(jset))
    1078             :                   !
    1079       12312 :                   map_it2 = .FALSE.
    1080        1728 :                   DO ipgf = 1, npgfa(iset)
    1081       12312 :                      DO jpgf = 1, npgfa(jset)
    1082       10584 :                         zetp = zeta(ipgf, iset) + zeta(jpgf, jset)
    1083       10584 :                         igrid_level = gaussian_gridlevel(gridlevel_info, zetp)
    1084       10584 :                         rs_grid => rs_v(igrid_level)
    1085       12096 :                         map_it2(ipgf, jpgf) = map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)
    1086             :                      END DO
    1087             :                   END DO
    1088         216 :                   offset = offset + 1
    1089             :                   !
    1090        6480 :                   IF (ANY(map_it2(1:npgfa(iset), 1:npgfa(jset)))) THEN
    1091      237492 :                      hab(:, :) = 0._dp
    1092         108 :                      IF (calculate_forces) THEN
    1093             :                         CALL dgemm("N", "N", ncoa, nsgf_seta(jset), nsgf_seta(iset), &
    1094             :                                    1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
    1095             :                                    pblk(sgfa, sgfb), SIZE(pblk, 1), &
    1096           0 :                                    0.0_dp, work(1, 1), SIZE(work, 1))
    1097             :                         CALL dgemm("N", "T", ncoa, ncob, nsgf_seta(jset), &
    1098             :                                    1.0_dp, work(1, 1), SIZE(work, 1), &
    1099             :                                    sphi_a(1, sgfb), SIZE(sphi_a, 1), &
    1100           0 :                                    0.0_dp, pab(1, 1), SIZE(pab, 1))
    1101             :                      END IF
    1102             : 
    1103         864 :                      DO ipgf = 1, npgfa(iset)
    1104         756 :                         na1 = (ipgf - 1)*ncoset(la_max(iset))
    1105         756 :                         na2 = ipgf*ncoset(la_max(iset))
    1106        6156 :                         DO jpgf = 1, npgfa(jset)
    1107        5292 :                            nb1 = (jpgf - 1)*ncoset(la_max(jset))
    1108        5292 :                            nb2 = jpgf*ncoset(la_max(jset))
    1109        5292 :                            zetp = zeta(ipgf, iset) + zeta(jpgf, jset)
    1110        5292 :                            igrid_level = gaussian_gridlevel(gridlevel_info, zetp)
    1111        5292 :                            rs_grid => rs_v(igrid_level)
    1112             : 
    1113             :                            radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
    1114             :                                                              lb_min=la_min(jset), lb_max=la_max(jset), &
    1115             :                                                              ra=ra, rb=ra, rp=ra, &
    1116             :                                                              zetp=zetp, eps=eps_rho_rspace, &
    1117        5292 :                                                              prefactor=1.0_dp, cutoff=1.0_dp)
    1118             : 
    1119        6048 :                            IF (map_it2(ipgf, jpgf)) THEN
    1120        5292 :                               IF (calculate_forces) THEN
    1121             :                                  CALL integrate_pgf_product( &
    1122             :                                     la_max(iset), zeta(ipgf, iset), la_min(iset), &
    1123             :                                     la_max(jset), zeta(jpgf, jset), la_min(jset), &
    1124             :                                     ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
    1125             :                                     rsgrid=rs_v(igrid_level), &
    1126             :                                     hab=hab, pab=pab, o1=na1, o2=nb1, &
    1127             :                                     radius=radius, &
    1128             :                                     calculate_forces=.TRUE., &
    1129             :                                     force_a=force_a, force_b=force_b, &
    1130           0 :                                     use_virial=use_virial, my_virial_a=my_virial_a, my_virial_b=my_virial_b)
    1131             :                               ELSE
    1132             :                                  CALL integrate_pgf_product( &
    1133             :                                     la_max(iset), zeta(ipgf, iset), la_min(iset), &
    1134             :                                     la_max(jset), zeta(jpgf, jset), la_min(jset), &
    1135             :                                     ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
    1136             :                                     rsgrid=rs_v(igrid_level), &
    1137             :                                     hab=hab, o1=na1, o2=nb1, &
    1138             :                                     radius=radius, &
    1139        5292 :                                     calculate_forces=.FALSE.)
    1140             :                               END IF
    1141             :                            END IF
    1142             :                         END DO
    1143             :                      END DO
    1144             :                      ! contract hab
    1145             :                      CALL dgemm("N", "N", ncoa, nsgf_seta(jset), ncob, &
    1146             :                                 1.0_dp, hab(1, 1), SIZE(hab, 1), &
    1147             :                                 sphi_a(1, sgfb), SIZE(sphi_a, 1), &
    1148         108 :                                 0.0_dp, work(1, 1), SIZE(work, 1))
    1149             :                      CALL dgemm("T", "N", nsgf_seta(iset), nsgf_seta(jset), ncoa, &
    1150             :                                 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
    1151             :                                 work(1, 1), SIZE(work, 1), &
    1152         108 :                                 1.0_dp, hmat(sgfa, sgfb), SIZE(hmat, 1))
    1153             :                   END IF
    1154             :                END DO
    1155             :             END DO
    1156         216 :             DEALLOCATE (map_it2)
    1157             :             ! update KS matrix
    1158       35064 :             CALL para_env%sum(hmat)
    1159         216 :             CALL dbcsr_get_block_p(matrix=ksmat, row=atom_a, col=atom_a, BLOCK=h_block, found=found)
    1160         216 :             IF (found) THEN
    1161       17532 :                h_block(1:nsgfa, 1:nsgfa) = h_block(1:nsgfa, 1:nsgfa) + hmat(1:nsgfa, 1:nsgfa)
    1162             :             END IF
    1163         504 :             IF (calculate_forces) THEN
    1164           0 :                force(ikind)%rho_elec(:, iatom) = force(ikind)%rho_elec(:, iatom) + 2.0_dp*force_a(:)
    1165           0 :                IF (use_virial) THEN
    1166             :                   IF (use_virial .AND. calculate_forces) THEN
    1167           0 :                      virial%pv_lrigpw = virial%pv_lrigpw + 2.0_dp*my_virial_a
    1168           0 :                      virial%pv_virial = virial%pv_virial + 2.0_dp*my_virial_a
    1169             :                   END IF
    1170             :                END IF
    1171             :             END IF
    1172             :          END DO
    1173          72 :          DEALLOCATE (hab, work, hmat)
    1174         252 :          IF (calculate_forces) DEALLOCATE (pab, pblk)
    1175             :       END DO
    1176             : 
    1177          36 :       CALL timestop(handle)
    1178             : 
    1179          72 :    END SUBROUTINE integrate_v_rspace_diagonal
    1180             : 
    1181             : ! **************************************************************************************************
    1182             : !> \brief computes integrals of product of v_rspace times a basis function (vector function)
    1183             : !>        and possible forces
    1184             : !> \param qs_env ...
    1185             : !> \param v_rspace ...
    1186             : !> \param f_coef ...
    1187             : !> \param f_integral ...
    1188             : !> \param calculate_forces ...
    1189             : !> \param basis_type ...
    1190             : !> \author JGH [8.2024]
    1191             : ! **************************************************************************************************
    1192           4 :    SUBROUTINE integrate_function(qs_env, v_rspace, f_coef, f_integral, calculate_forces, basis_type)
    1193             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1194             :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: v_rspace
    1195             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: f_coef
    1196             :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: f_integral
    1197             :       LOGICAL, INTENT(IN)                                :: calculate_forces
    1198             :       CHARACTER(len=*), INTENT(IN)                       :: basis_type
    1199             : 
    1200             :       CHARACTER(len=*), PARAMETER :: routineN = 'integrate_function'
    1201             : 
    1202             :       INTEGER :: atom_a, group_size, handle, i, iatom, igrid_level, ikind, ipgf, iset, maxco, &
    1203             :          maxsgf_set, my_pos, na1, natom, ncoa, nkind, nseta, offset, sgfa
    1204           4 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind
    1205           4 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, npgfa, nsgfa
    1206           4 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa
    1207             :       LOGICAL                                            :: use_virial
    1208             :       REAL(KIND=dp)                                      :: eps_rho_rspace, radius
    1209             :       REAL(KIND=dp), DIMENSION(3)                        :: force_a, force_b, ra
    1210             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: my_virial_a, my_virial_b
    1211           4 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: hab, pab, sphi_a, work, zeta
    1212           4 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1213             :       TYPE(cell_type), POINTER                           :: cell
    1214             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1215             :       TYPE(gridlevel_info_type), POINTER                 :: gridlevel_info
    1216             :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1217           4 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1218             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1219           4 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    1220           4 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1221           4 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_v
    1222             :       TYPE(realspace_grid_type), POINTER                 :: rs_grid
    1223             :       TYPE(virial_type), POINTER                         :: virial
    1224             : 
    1225           4 :       CALL timeset(routineN, handle)
    1226             : 
    1227           4 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
    1228           4 :       gridlevel_info => pw_env%gridlevel_info
    1229             : 
    1230           4 :       CALL pw_env_get(pw_env, rs_grids=rs_v)
    1231           4 :       CALL potential_pw2rs(rs_v, v_rspace, pw_env)
    1232             : 
    1233             :       CALL get_qs_env(qs_env=qs_env, &
    1234             :                       atomic_kind_set=atomic_kind_set, &
    1235             :                       qs_kind_set=qs_kind_set, &
    1236             :                       force=force, &
    1237             :                       cell=cell, &
    1238             :                       dft_control=dft_control, &
    1239             :                       nkind=nkind, &
    1240             :                       natom=natom, &
    1241             :                       particle_set=particle_set, &
    1242             :                       pw_env=pw_env, &
    1243           4 :                       virial=virial)
    1244           4 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
    1245             : 
    1246           4 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
    1247           4 :       IF (use_virial) THEN
    1248           0 :          CPABORT("Virial NYA")
    1249             :       END IF
    1250             : 
    1251           4 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    1252             : 
    1253             :       CALL get_qs_kind_set(qs_kind_set, &
    1254           4 :                            maxco=maxco, maxsgf_set=maxsgf_set, basis_type=basis_type)
    1255          20 :       ALLOCATE (hab(maxco, 1), pab(maxco, 1), work(maxco, 1))
    1256             : 
    1257           4 :       offset = 0
    1258           4 :       my_pos = v_rspace%pw_grid%para%group%mepos
    1259           4 :       group_size = v_rspace%pw_grid%para%group%num_pe
    1260             : 
    1261          20 :       DO iatom = 1, natom
    1262          16 :          ikind = particle_set(iatom)%atomic_kind%kind_number
    1263          16 :          atom_a = atom_of_kind(iatom)
    1264          16 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=basis_type)
    1265             :          CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    1266             :                                 first_sgf=first_sgfa, &
    1267             :                                 lmax=la_max, &
    1268             :                                 lmin=la_min, &
    1269             :                                 npgf=npgfa, &
    1270             :                                 nset=nseta, &
    1271             :                                 nsgf_set=nsgfa, &
    1272             :                                 sphi=sphi_a, &
    1273          16 :                                 zet=zeta)
    1274          16 :          ra(:) = pbc(particle_set(iatom)%r, cell)
    1275             : 
    1276          16 :          force_a(:) = 0._dp
    1277          16 :          force_b(:) = 0._dp
    1278          16 :          my_virial_a(:, :) = 0._dp
    1279          16 :          my_virial_b(:, :) = 0._dp
    1280             : 
    1281          32 :          DO iset = 1, nseta
    1282             : 
    1283          16 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
    1284          16 :             sgfa = first_sgfa(1, iset)
    1285             : 
    1286         144 :             hab = 0._dp
    1287         144 :             pab = 0._dp
    1288             : 
    1289         120 :             DO i = 1, nsgfa(iset)
    1290         120 :                work(i, 1) = f_coef(offset + i)
    1291             :             END DO
    1292             : 
    1293             :             CALL dgemm("N", "N", ncoa, 1, nsgfa(iset), &
    1294             :                        1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
    1295             :                        work(1, 1), SIZE(work, 1), &
    1296          16 :                        0.0_dp, pab(1, 1), SIZE(pab, 1))
    1297             : 
    1298         120 :             DO ipgf = 1, npgfa(iset)
    1299             : 
    1300         104 :                na1 = (ipgf - 1)*ncoset(la_max(iset))
    1301             : 
    1302         104 :                igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
    1303         104 :                rs_grid => rs_v(igrid_level)
    1304             : 
    1305         120 :                IF (map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)) THEN
    1306             :                   radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
    1307             :                                                     lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
    1308             :                                                     zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
    1309          52 :                                                     prefactor=1.0_dp, cutoff=1.0_dp)
    1310             : 
    1311          52 :                   IF (calculate_forces) THEN
    1312             :                      CALL integrate_pgf_product(la_max=la_max(iset), &
    1313             :                                                 zeta=zeta(ipgf, iset), la_min=la_min(iset), &
    1314             :                                                 lb_max=0, zetb=0.0_dp, lb_min=0, &
    1315             :                                                 ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
    1316             :                                                 rsgrid=rs_grid, &
    1317             :                                                 hab=hab, pab=pab, o1=na1, o2=0, radius=radius, &
    1318             :                                                 calculate_forces=.TRUE., &
    1319             :                                                 force_a=force_a, force_b=force_b, &
    1320             :                                                 use_virial=use_virial, &
    1321          52 :                                                 my_virial_a=my_virial_a, my_virial_b=my_virial_b)
    1322             :                   ELSE
    1323             :                      CALL integrate_pgf_product(la_max=la_max(iset), &
    1324             :                                                 zeta=zeta(ipgf, iset), la_min=la_min(iset), &
    1325             :                                                 lb_max=0, zetb=0.0_dp, lb_min=0, &
    1326             :                                                 ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
    1327             :                                                 rsgrid=rs_grid, &
    1328             :                                                 hab=hab, o1=na1, o2=0, radius=radius, &
    1329           0 :                                                 calculate_forces=.FALSE.)
    1330             :                   END IF
    1331             : 
    1332             :                END IF
    1333             : 
    1334             :             END DO
    1335             :             !
    1336             :             CALL dgemm("T", "N", nsgfa(iset), 1, ncoa, 1.0_dp, sphi_a(1, sgfa), &
    1337          16 :                        SIZE(sphi_a, 1), hab(1, 1), SIZE(hab, 1), 0.0_dp, work(1, 1), SIZE(work, 1))
    1338         120 :             DO i = 1, nsgfa(iset)
    1339         120 :                f_integral(offset + i) = work(i, 1)
    1340             :             END DO
    1341             : 
    1342          32 :             offset = offset + nsgfa(iset)
    1343             : 
    1344             :          END DO
    1345             : 
    1346          36 :          IF (calculate_forces) THEN
    1347          64 :             force(ikind)%rho_elec(:, atom_a) = force(ikind)%rho_elec(:, atom_a) + force_a(:)
    1348          16 :             IF (use_virial) THEN
    1349           0 :                virial%pv_virial = virial%pv_virial + my_virial_a
    1350             :             END IF
    1351             :          END IF
    1352             : 
    1353             :       END DO
    1354             : 
    1355           4 :       DEALLOCATE (hab, pab, work)
    1356             : 
    1357           4 :       CALL timestop(handle)
    1358             : 
    1359          12 :    END SUBROUTINE integrate_function
    1360             : 
    1361             : END MODULE qs_integrate_potential_single

Generated by: LCOV version 1.15