LCOV - code coverage report
Current view: top level - src - qs_rho0_ggrid.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:123285f) Lines: 95.7 % 325 311
Test Date: 2026-11-04 00:58:17 Functions: 100.0 % 3 3

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : ! **************************************************************************************************
       8              : MODULE qs_rho0_ggrid
       9              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      10              :                                               get_atomic_kind
      11              :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      12              :                                               gto_basis_set_type
      13              :    USE cell_types,                      ONLY: cell_type,&
      14              :                                               pbc
      15              :    USE cp_control_types,                ONLY: dft_control_type
      16              :    USE gaussian_gridlevels,             ONLY: gaussian_gridlevel
      17              :    USE grid_api,                        ONLY: GRID_FUNC_AB,&
      18              :                                               collocate_pgf_product
      19              :    USE kinds,                           ONLY: dp
      20              :    USE memory_utilities,                ONLY: reallocate
      21              :    USE message_passing,                 ONLY: mp_para_env_type
      22              :    USE orbital_pointers,                ONLY: indco,&
      23              :                                               nco,&
      24              :                                               ncoset,&
      25              :                                               nso,&
      26              :                                               nsoset
      27              :    USE orbital_transformation_matrices, ONLY: orbtramat
      28              :    USE particle_types,                  ONLY: particle_type
      29              :    USE pw_env_types,                    ONLY: pw_env_get,&
      30              :                                               pw_env_type
      31              :    USE pw_methods,                      ONLY: pw_axpy,&
      32              :                                               pw_copy,&
      33              :                                               pw_integrate_function,&
      34              :                                               pw_scale,&
      35              :                                               pw_transfer,&
      36              :                                               pw_zero
      37              :    USE pw_pool_types,                   ONLY: pw_pool_p_type,&
      38              :                                               pw_pool_type
      39              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      40              :                                               pw_r3d_rs_type
      41              :    USE qs_cneo_ggrid,                   ONLY: integrate_vhgg_rspace,&
      42              :                                               rhoz_cneo_s_grid_create
      43              :    USE qs_cneo_types,                   ONLY: cneo_potential_type,&
      44              :                                               rhoz_cneo_type
      45              :    USE qs_environment_types,            ONLY: get_qs_env,&
      46              :                                               qs_environment_type
      47              :    USE qs_force_types,                  ONLY: qs_force_type
      48              :    USE qs_harmonics_atom,               ONLY: get_none0_cg_list,&
      49              :                                               harmonics_atom_type
      50              :    USE qs_integrate_potential,          ONLY: integrate_pgf_product
      51              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      52              :                                               qs_kind_type
      53              :    USE qs_local_rho_types,              ONLY: get_local_rho,&
      54              :                                               local_rho_type
      55              :    USE qs_rho0_types,                   ONLY: get_rho0_mpole,&
      56              :                                               rho0_mpole_type
      57              :    USE qs_rho_atom_types,               ONLY: get_rho_atom,&
      58              :                                               rho_atom_coeff,&
      59              :                                               rho_atom_type
      60              :    USE realspace_grid_types,            ONLY: realspace_grid_desc_p_type,&
      61              :                                               realspace_grid_desc_type,&
      62              :                                               realspace_grid_type,&
      63              :                                               rs_grid_create,&
      64              :                                               rs_grid_release,&
      65              :                                               rs_grid_zero,&
      66              :                                               transfer_pw2rs,&
      67              :                                               transfer_rs2pw
      68              :    USE util,                            ONLY: get_limit
      69              :    USE virial_types,                    ONLY: virial_type
      70              : #include "./base/base_uses.f90"
      71              : 
      72              :    IMPLICIT NONE
      73              : 
      74              :    PRIVATE
      75              : 
      76              :    ! Global parameters (only in this module)
      77              : 
      78              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_rho0_ggrid'
      79              : 
      80              :    ! Public subroutines
      81              : 
      82              :    PUBLIC :: put_rho0_on_grid, rho0_s_grid_create, integrate_vhg0_rspace
      83              : 
      84              : CONTAINS
      85              : 
      86              : ! **************************************************************************************************
      87              : !> \brief ...
      88              : !> \param qs_env ...
      89              : !> \param rho0 ...
      90              : !> \param tot_rs_int ...
      91              : !> \param my_pools ...
      92              : !> \param my_rs_grids ...
      93              : !> \param my_rs_descs ...
      94              : ! **************************************************************************************************
      95        31924 :    SUBROUTINE put_rho0_on_grid(qs_env, rho0, tot_rs_int, my_pools, my_rs_grids, my_rs_descs)
      96              : 
      97              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      98              :       TYPE(rho0_mpole_type), POINTER                     :: rho0
      99              :       REAL(KIND=dp), INTENT(OUT)                         :: tot_rs_int
     100              :       TYPE(pw_pool_p_type), DIMENSION(:), OPTIONAL, &
     101              :          POINTER                                         :: my_pools
     102              :       TYPE(realspace_grid_type), DIMENSION(:), &
     103              :          OPTIONAL, POINTER                               :: my_rs_grids
     104              :       TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
     105              :          OPTIONAL, POINTER                               :: my_rs_descs
     106              : 
     107              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'put_rho0_on_grid'
     108              : 
     109              :       INTEGER                                            :: auxbas_grid, handle, iat, iatom, igrid, &
     110              :                                                             ikind, ithread, j, l0_ikind, lmax0, &
     111              :                                                             nat, nch_ik, nch_max, npme
     112        31924 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores
     113              :       LOGICAL                                            :: paw_atom
     114              :       REAL(KIND=dp)                                      :: eps_rho_rspace, rpgf0, zet0
     115              :       REAL(KIND=dp), DIMENSION(3)                        :: ra
     116        31924 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: Qlm_c
     117        31924 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
     118        31924 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     119              :       TYPE(cell_type), POINTER                           :: cell
     120              :       TYPE(dft_control_type), POINTER                    :: dft_control
     121              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     122        31924 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     123              :       TYPE(pw_c1d_gs_type)                               :: coeff_gspace
     124              :       TYPE(pw_c1d_gs_type), POINTER                      :: rho0_s_gs
     125              :       TYPE(pw_env_type), POINTER                         :: pw_env
     126        31924 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
     127              :       TYPE(pw_pool_type), POINTER                        :: pw_pool
     128              :       TYPE(pw_r3d_rs_type)                               :: coeff_rspace
     129              :       TYPE(pw_r3d_rs_type), POINTER                      :: rho0_s_rs
     130        31924 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     131              :       TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
     132        31924 :          POINTER                                         :: descs
     133              :       TYPE(realspace_grid_desc_type), POINTER            :: desc
     134        31924 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: grids
     135              :       TYPE(realspace_grid_type), POINTER                 :: rs_grid
     136              : 
     137        31924 :       CALL timeset(routineN, handle)
     138              : 
     139        31924 :       NULLIFY (atomic_kind_set, qs_kind_set, cores, pab, Qlm_c)
     140              : 
     141        31924 :       NULLIFY (dft_control, pw_env, particle_set, para_env, cell, rho0_s_gs, rho0_s_rs)
     142              :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, &
     143              :                       particle_set=particle_set, &
     144              :                       atomic_kind_set=atomic_kind_set, &
     145              :                       qs_kind_set=qs_kind_set, &
     146              :                       para_env=para_env, &
     147        31924 :                       pw_env=pw_env, cell=cell)
     148        31924 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     149              : 
     150        31924 :       NULLIFY (descs, pw_pools)
     151        31924 :       CALL pw_env_get(pw_env=pw_env, rs_descs=descs, rs_grids=grids, pw_pools=pw_pools)
     152        31924 :       auxbas_grid = pw_env%auxbas_grid
     153              : 
     154        31924 :       NULLIFY (rho0_s_gs, rho0_s_rs)
     155              :       CALL get_rho0_mpole(rho0_mpole=rho0, lmax_0=lmax0, &
     156              :                           zet0_h=zet0, igrid_zet0_s=igrid, &
     157              :                           rho0_s_gs=rho0_s_gs, &
     158        31924 :                           rho0_s_rs=rho0_s_rs)
     159              : 
     160              :       ! *** set up the rs grid at level igrid
     161        31924 :       NULLIFY (rs_grid, desc, pw_pool)
     162              :       ! IF present, overwrite qs grid for new pool
     163        31924 :       IF (PRESENT(my_pools)) THEN
     164         2288 :          desc => my_rs_descs(igrid)%rs_desc
     165         2288 :          rs_grid => my_rs_grids(igrid)
     166         2288 :          pw_pool => my_pools(igrid)%pool
     167              :       ELSE
     168        29636 :          desc => descs(igrid)%rs_desc
     169        29636 :          rs_grid => grids(igrid)
     170        29636 :          pw_pool => pw_pools(igrid)%pool
     171              :       END IF
     172              : 
     173        31924 :       CPASSERT(ASSOCIATED(desc))
     174        31924 :       CPASSERT(ASSOCIATED(pw_pool))
     175              : 
     176        31924 :       IF (igrid /= auxbas_grid) THEN
     177           12 :          CALL pw_pool%create_pw(coeff_rspace)
     178           12 :          CALL pw_pool%create_pw(coeff_gspace)
     179              :       END IF
     180        31924 :       CALL rs_grid_zero(rs_grid)
     181              : 
     182        31924 :       nch_max = ncoset(lmax0)
     183              : 
     184        95772 :       ALLOCATE (pab(nch_max, 1))
     185              : 
     186        93080 :       DO ikind = 1, SIZE(atomic_kind_set)
     187        61156 :          CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=nat)
     188        61156 :          CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom)
     189              : 
     190        61156 :          IF (.NOT. paw_atom .AND. dft_control%qs_control%gapw_control%nopaw_as_gpw) CYCLE
     191              : 
     192              :          CALL get_rho0_mpole(rho0_mpole=rho0, ikind=ikind, l0_ikind=l0_ikind, &
     193        57704 :                              rpgf0_s=rpgf0)
     194              : 
     195        57704 :          nch_ik = ncoset(l0_ikind)
     196       730954 :          pab = 0.0_dp
     197              : 
     198        57704 :          CALL reallocate(cores, 1, nat)
     199        57704 :          npme = 0
     200       148280 :          cores = 0
     201              : 
     202       148280 :          DO iat = 1, nat
     203        90576 :             iatom = atom_list(iat)
     204        90576 :             ra(:) = pbc(particle_set(iatom)%r, cell)
     205       148280 :             IF (rs_grid%desc%parallel .AND. .NOT. rs_grid%desc%distributed) THEN
     206              :                ! replicated realspace grid, split the atoms up between procs
     207        90576 :                IF (MODULO(iatom, rs_grid%desc%group_size) == rs_grid%desc%my_pos) THEN
     208        45288 :                   npme = npme + 1
     209        45288 :                   cores(npme) = iat
     210              :                END IF
     211              :             ELSE
     212            0 :                npme = npme + 1
     213            0 :                cores(npme) = iat
     214              :             END IF
     215              : 
     216              :          END DO
     217              : 
     218              :          ithread = 0
     219       253776 :          DO j = 1, npme
     220              : 
     221        45288 :             iat = cores(j)
     222        45288 :             iatom = atom_list(iat)
     223              : 
     224        45288 :             CALL get_rho0_mpole(rho0_mpole=rho0, iat=iatom, Qlm_car=Qlm_c)
     225              : 
     226       882074 :             pab(1:nch_ik, 1) = Qlm_c(1:nch_ik)
     227              : 
     228        45288 :             ra(:) = pbc(particle_set(iatom)%r, cell)
     229              : 
     230              :             CALL collocate_pgf_product( &
     231              :                l0_ikind, zet0, 0, 0, 0.0_dp, 0, &
     232              :                ra, [0.0_dp, 0.0_dp, 0.0_dp], 1.0_dp, pab, 0, 0, &
     233              :                rs_grid, ga_gb_function=GRID_FUNC_AB, radius=rpgf0, &
     234       106444 :                use_subpatch=.TRUE., subpatch_pattern=0)
     235              : 
     236              :          END DO ! j
     237              : 
     238              :       END DO ! ikind
     239              : 
     240        31924 :       IF (ASSOCIATED(cores)) THEN
     241        30680 :          DEALLOCATE (cores)
     242              :       END IF
     243              : 
     244        31924 :       DEALLOCATE (pab)
     245              : 
     246        31924 :       IF (igrid /= auxbas_grid) THEN
     247           12 :          CALL transfer_rs2pw(rs_grid, coeff_rspace)
     248           12 :          CALL pw_zero(rho0_s_gs)
     249           12 :          CALL pw_transfer(coeff_rspace, coeff_gspace)
     250           12 :          CALL pw_axpy(coeff_gspace, rho0_s_gs)
     251              : 
     252           12 :          tot_rs_int = pw_integrate_function(coeff_rspace, isign=-1)
     253              : 
     254           12 :          CALL pw_pool%give_back_pw(coeff_rspace)
     255           12 :          CALL pw_pool%give_back_pw(coeff_gspace)
     256              :       ELSE
     257        31912 :          IF (ASSOCIATED(rs_grid%desc%pw, rho0_s_rs%pw_grid)) THEN
     258        31912 :             CALL transfer_rs2pw(rs_grid, rho0_s_rs)
     259        31912 :             tot_rs_int = pw_integrate_function(rho0_s_rs, isign=-1)
     260              :          ELSE
     261              :             ! Custom pools may use a distinct grid descriptor at the same level.
     262            0 :             CALL pw_pool%create_pw(coeff_rspace)
     263            0 :             CALL transfer_rs2pw(rs_grid, coeff_rspace)
     264            0 :             tot_rs_int = pw_integrate_function(coeff_rspace, isign=-1)
     265            0 :             CALL pw_transfer(coeff_rspace, rho0_s_rs)
     266            0 :             CALL pw_pool%give_back_pw(coeff_rspace)
     267              :          END IF
     268              : 
     269        31912 :          CALL pw_zero(rho0_s_gs)
     270        31912 :          CALL pw_transfer(rho0_s_rs, rho0_s_gs)
     271              :       END IF
     272        31924 :       CALL timestop(handle)
     273              : 
     274        63848 :    END SUBROUTINE put_rho0_on_grid
     275              : 
     276              : ! **************************************************************************************************
     277              : !> \brief ...
     278              : !> \param pw_env ...
     279              : !> \param rho0_mpole ...
     280              : ! **************************************************************************************************
     281         5294 :    SUBROUTINE rho0_s_grid_create(pw_env, rho0_mpole)
     282              : 
     283              :       TYPE(pw_env_type), POINTER                         :: pw_env
     284              :       TYPE(rho0_mpole_type), POINTER                     :: rho0_mpole
     285              : 
     286              :       CHARACTER(len=*), PARAMETER :: routineN = 'rho0_s_grid_create'
     287              : 
     288              :       INTEGER                                            :: handle
     289              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     290              : 
     291         5294 :       CALL timeset(routineN, handle)
     292              : 
     293         5294 :       CPASSERT(ASSOCIATED(pw_env))
     294              : 
     295         5294 :       NULLIFY (auxbas_pw_pool)
     296         5294 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     297         5294 :       CPASSERT(ASSOCIATED(auxbas_pw_pool))
     298              : 
     299              :       ! reallocate rho0 on the global grid in real and reciprocal space
     300         5294 :       CPASSERT(ASSOCIATED(rho0_mpole))
     301              : 
     302              :       ! rho0 density in real space
     303         5294 :       IF (ASSOCIATED(rho0_mpole%rho0_s_rs)) THEN
     304         1480 :          CALL rho0_mpole%rho0_s_rs%release()
     305              :       ELSE
     306         3814 :          ALLOCATE (rho0_mpole%rho0_s_rs)
     307              :       END IF
     308         5294 :       CALL auxbas_pw_pool%create_pw(rho0_mpole%rho0_s_rs)
     309              : 
     310              :       ! rho0 density in reciprocal space
     311         5294 :       IF (ASSOCIATED(rho0_mpole%rho0_s_gs)) THEN
     312         1480 :          CALL rho0_mpole%rho0_s_gs%release()
     313              :       ELSE
     314         3814 :          ALLOCATE (rho0_mpole%rho0_s_gs)
     315              :       END IF
     316         5294 :       CALL auxbas_pw_pool%create_pw(rho0_mpole%rho0_s_gs)
     317              : 
     318              :       ! Find the grid level suitable for rho0_soft
     319         5294 :       rho0_mpole%igrid_zet0_s = gaussian_gridlevel(pw_env%gridlevel_info, 2.0_dp*rho0_mpole%zet0_h)
     320              : 
     321         5294 :       CALL timestop(handle)
     322              : 
     323         5294 :       IF (rho0_mpole%do_cneo) THEN
     324           16 :          CALL rhoz_cneo_s_grid_create(pw_env, rho0_mpole)
     325              :       END IF
     326              : 
     327         5294 :    END SUBROUTINE rho0_s_grid_create
     328              : 
     329              : ! **************************************************************************************************
     330              : !> \brief ...
     331              : !> \param qs_env ...
     332              : !> \param v_rspace ...
     333              : !> \param para_env ...
     334              : !> \param calculate_forces ...
     335              : !> \param local_rho_set ...
     336              : !> \param local_rho_set_2nd ...
     337              : !> \param atener ...
     338              : !> \param kforce ...
     339              : !> \param my_pools ...
     340              : !> \param my_rs_descs ...
     341              : ! **************************************************************************************************
     342        29254 :    SUBROUTINE integrate_vhg0_rspace(qs_env, v_rspace, para_env, calculate_forces, local_rho_set, &
     343        29254 :                                     local_rho_set_2nd, atener, kforce, my_pools, my_rs_descs)
     344              : 
     345              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     346              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: v_rspace
     347              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     348              :       LOGICAL, INTENT(IN)                                :: calculate_forces
     349              :       TYPE(local_rho_type), OPTIONAL, POINTER            :: local_rho_set, local_rho_set_2nd
     350              :       REAL(KIND=dp), DIMENSION(:), OPTIONAL              :: atener
     351              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: kforce
     352              :       TYPE(pw_pool_p_type), DIMENSION(:), OPTIONAL, &
     353              :          POINTER                                         :: my_pools
     354              :       TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
     355              :          OPTIONAL, POINTER                               :: my_rs_descs
     356              : 
     357              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'integrate_vhg0_rspace'
     358              : 
     359              :       INTEGER :: auxbas_grid, bo(2), handle, i, iat, iatom, ic, icg, ico, ig1, ig2, igrid, ii, &
     360              :          ikind, ipgf1, ipgf2, is, iset1, iset2, iso, iso1, iso2, ispin, j, l0_ikind, llmax, &
     361              :          llmax_nuc, lmax0, lshell, lx, ly, lz, m1, m2, max_iso_not0_local, max_s_harm, &
     362              :          max_s_harm_nuc, maxl, maxl_nuc, maxso, maxso_nuc, mepos, n1, n2, nat, nch_ik, nch_max, &
     363              :          ncurr, nset, nset_nuc, nsotot, nsotot_nuc, nspins, num_pe
     364        29254 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: cg_n_list
     365        29254 :       INTEGER, ALLOCATABLE, DIMENSION(:, :, :)           :: cg_list
     366        29254 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, lmax, lmax_nuc, lmin, &
     367        29254 :                                                             lmin_nuc, npgf, npgf_nuc
     368              :       LOGICAL                                            :: direct_transfer, grid_distributed, &
     369              :                                                             paw_atom, use_virial
     370              :       REAL(KIND=dp)                                      :: eps_rho_rspace, force_tmp(3), fscale, &
     371              :                                                             ra(3), rpgf0, zet0
     372              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: my_virial_a, my_virial_b
     373        29254 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: hab_sph, norm_l, Qlm
     374        29254 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: hab, hdab_sph, intloc, intloc_nuc, pab
     375        29254 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: a_hdab_sph, hdab, Qlm_gg
     376        29254 :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: a_hdab
     377        29254 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     378              :       TYPE(cell_type), POINTER                           :: cell
     379              :       TYPE(cneo_potential_type), POINTER                 :: cneo_potential
     380              :       TYPE(dft_control_type), POINTER                    :: dft_control
     381              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c_set, nuc_basis_set
     382              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
     383        29254 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     384              :       TYPE(pw_c1d_gs_type)                               :: coeff_gaux, coeff_gspace
     385              :       TYPE(pw_env_type), POINTER                         :: pw_env
     386        29254 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
     387              :       TYPE(pw_pool_type), POINTER                        :: pw_aux, pw_pool
     388              :       TYPE(pw_r3d_rs_type)                               :: coeff_rspace
     389        29254 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     390        29254 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     391              :       TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
     392        29254 :          POINTER                                         :: rs_descs
     393              :       TYPE(realspace_grid_desc_type), POINTER            :: rs_desc
     394       585080 :       TYPE(realspace_grid_type)                          :: rs_v
     395              :       TYPE(rho0_mpole_type), POINTER                     :: rho0_mpole
     396        29254 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: int_local_h, int_local_s
     397        29254 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho_atom_set
     398              :       TYPE(rho_atom_type), POINTER                       :: rho_atom
     399        29254 :       TYPE(rhoz_cneo_type), DIMENSION(:), POINTER        :: rhoz_cneo_set
     400              :       TYPE(rhoz_cneo_type), POINTER                      :: rhoz_cneo
     401              :       TYPE(virial_type), POINTER                         :: virial
     402              : 
     403        29254 :       CALL timeset(routineN, handle)
     404              : 
     405              :       ! In case of the external density computed forces probably also
     406              :       ! need to be stored outside qs_env. We can then remove the
     407              :       ! attribute 'OPTIONAL' from the argument 'local_rho_set'.
     408              : 
     409              :       ! CPASSERT(.NOT. (calculate_forces .AND. PRESENT(local_rho_set)))
     410              : !      IF (calculate_forces .AND. PRESENT(local_rho_set)) THEN
     411              : !         CPWARN("Forces and External Density!")
     412              : !      END IF
     413              : 
     414        29254 :       NULLIFY (atomic_kind_set, qs_kind_set, dft_control, particle_set)
     415        29254 :       NULLIFY (cell, force, pw_env, rho0_mpole, rho_atom_set, rhoz_cneo_set)
     416              : 
     417              :       CALL get_qs_env(qs_env=qs_env, &
     418              :                       atomic_kind_set=atomic_kind_set, &
     419              :                       qs_kind_set=qs_kind_set, &
     420              :                       cell=cell, &
     421              :                       dft_control=dft_control, &
     422              :                       force=force, pw_env=pw_env, &
     423              :                       rho0_mpole=rho0_mpole, &
     424              :                       rho_atom_set=rho_atom_set, &
     425              :                       rhoz_cneo_set=rhoz_cneo_set, &
     426              :                       particle_set=particle_set, &
     427        29254 :                       virial=virial)
     428              : 
     429        29254 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     430              : 
     431        29254 :       nspins = dft_control%nspins
     432              : 
     433              :       ! The aim of the following code was to return immediately if the subroutine
     434              :       ! was called for triplet excited states in spin-restricted case. This check
     435              :       ! is also performed before invocation of this subroutine. It should be save
     436              :       ! to remove the optional argument 'do_triplet' from the subroutine interface.
     437              :       !my_tddft = PRESENT(local_rho_set)
     438              :       !IF (my_tddft) THEN
     439              :       !   IF (PRESENT(do_triplet)) THEN
     440              :       !      IF (nspins == 1 .AND. do_triplet) RETURN
     441              :       !   ELSE
     442              :       !      IF (nspins == 1 .AND. dft_control%tddfpt_control%res_etype /= tddfpt_singlet) RETURN
     443              :       !   END IF
     444              :       !END IF
     445              : 
     446        29254 :       IF (PRESENT(local_rho_set)) THEN
     447              :          CALL get_local_rho(local_rho_set, rho0_mpole=rho0_mpole, rho_atom_set=rho_atom_set, &
     448         4792 :                             rhoz_cneo_set=rhoz_cneo_set)
     449              :       END IF
     450              :       ! Q from rho0_mpole of local_rho_set
     451              :       ! for TDDFT forces we need mixed potential / integral space
     452              :       ! potential stored on local_rho_set_2nd
     453        29254 :       IF (PRESENT(local_rho_set_2nd)) THEN
     454          348 :          CALL get_local_rho(local_rho_set_2nd, rho_atom_set=rho_atom_set)
     455              :       END IF
     456              :       CALL get_rho0_mpole(rho0_mpole=rho0_mpole, lmax_0=lmax0, &
     457              :                           zet0_h=zet0, igrid_zet0_s=igrid, &
     458        29254 :                           norm_g0l_h=norm_l)
     459              : 
     460              :       ! Setup of the potential on the multigrids
     461        29254 :       NULLIFY (rs_descs, pw_pools)
     462        29254 :       CPASSERT(ASSOCIATED(pw_env))
     463        29254 :       CALL pw_env_get(pw_env, rs_descs=rs_descs, pw_pools=pw_pools)
     464              : 
     465              :       ! Assign from pw_env
     466        29254 :       auxbas_grid = pw_env%auxbas_grid
     467              : 
     468              :       ! IF present, overwrite qs grid for new pool
     469              :       ! Get the potential on the right grid
     470        29254 :       IF (PRESENT(my_pools)) THEN
     471           50 :          rs_desc => my_rs_descs(igrid)%rs_desc
     472           50 :          pw_pool => my_pools(igrid)%pool
     473              :       ELSE
     474        29204 :          rs_desc => rs_descs(igrid)%rs_desc
     475        29204 :          pw_pool => pw_pools(igrid)%pool
     476              :       END IF
     477              : 
     478              :       direct_transfer = igrid == auxbas_grid .AND. .NOT. pw_pool%pw_grid%spherical .AND. &
     479        29254 :                         ASSOCIATED(rs_desc%pw, v_rspace%pw_grid)
     480              :       IF (.NOT. direct_transfer) THEN
     481           12 :          CALL pw_pool%create_pw(coeff_rspace)
     482           12 :          IF (igrid /= auxbas_grid .OR. pw_pool%pw_grid%spherical) THEN
     483           12 :             CALL pw_pool%create_pw(coeff_gspace)
     484           12 :             IF (igrid /= auxbas_grid) THEN
     485           12 :                pw_aux => pw_pools(auxbas_grid)%pool
     486           12 :                CALL pw_aux%create_pw(coeff_gaux)
     487           12 :                CALL pw_transfer(v_rspace, coeff_gaux)
     488           12 :                CALL pw_copy(coeff_gaux, coeff_gspace)
     489           12 :                CALL pw_aux%give_back_pw(coeff_gaux)
     490              :             ELSE
     491              :                ! Preserve the reciprocal-space projection on spherical grids.
     492            0 :                CALL pw_transfer(v_rspace, coeff_gspace)
     493              :             END IF
     494           12 :             CALL pw_transfer(coeff_gspace, coeff_rspace)
     495           12 :             CALL pw_pool%give_back_pw(coeff_gspace)
     496           12 :             IF (igrid /= auxbas_grid) THEN
     497           12 :                fscale = coeff_rspace%pw_grid%dvol/pw_aux%pw_grid%dvol
     498           12 :                CALL pw_scale(coeff_rspace, fscale)
     499              :             END IF
     500              :          ELSE
     501            0 :             CALL pw_copy(v_rspace, coeff_rspace)
     502              :          END IF
     503              :       END IF
     504              : 
     505              :       ! Setup the rs grid at level igrid
     506        29254 :       CALL rs_grid_create(rs_v, rs_desc)
     507        29254 :       CALL rs_grid_zero(rs_v)
     508        29254 :       IF (direct_transfer) THEN
     509              :          ! The potential is already on the target grid; no PW copy is needed.
     510        29242 :          CALL transfer_pw2rs(rs_v, v_rspace)
     511              :       ELSE
     512           12 :          CALL transfer_pw2rs(rs_v, coeff_rspace)
     513           12 :          CALL pw_pool%give_back_pw(coeff_rspace)
     514              :       END IF
     515              : 
     516              :       ! Now the potential is on the right grid => integration
     517              : 
     518        29254 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     519              : 
     520              :       ! Allocate work storage
     521              : 
     522        29254 :       NULLIFY (hab, hab_sph, hdab, hdab_sph, pab, a_hdab, a_hdab_sph)
     523        29254 :       nch_max = ncoset(lmax0)
     524        29254 :       CALL reallocate(hab, 1, nch_max, 1, 1)
     525        29254 :       CALL reallocate(hab_sph, 1, nch_max)
     526        29254 :       CALL reallocate(hdab, 1, 3, 1, nch_max, 1, 1)
     527        29254 :       CALL reallocate(hdab_sph, 1, 3, 1, nch_max)
     528        29254 :       CALL reallocate(a_hdab, 1, 3, 1, 3, 1, nch_max, 1, 1)
     529        29254 :       CALL reallocate(a_hdab_sph, 1, 3, 1, 3, 1, nch_max)
     530        29254 :       CALL reallocate(pab, 1, nch_max, 1, 1)
     531              : 
     532        29254 :       ncurr = -1
     533              : 
     534        29254 :       grid_distributed = rs_v%desc%distributed
     535              : 
     536        29254 :       fscale = 1.0_dp
     537        29254 :       IF (PRESENT(kforce)) THEN
     538           88 :          fscale = kforce
     539              :       END IF
     540              : 
     541        84612 :       DO ikind = 1, SIZE(atomic_kind_set, 1)
     542        55358 :          NULLIFY (basis_1c_set, atom_list, harmonics, cneo_potential)
     543        55358 :          CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=nat)
     544              :          CALL get_qs_kind(qs_kind_set(ikind), &
     545              :                           basis_set=basis_1c_set, basis_type="GAPW_1C", &
     546              :                           paw_atom=paw_atom, &
     547              :                           harmonics=harmonics, &
     548        55358 :                           cneo_potential=cneo_potential)
     549              : 
     550        55358 :          IF (.NOT. paw_atom) CYCLE
     551              : 
     552        52004 :          NULLIFY (Qlm_gg, lmax, npgf)
     553              :          CALL get_rho0_mpole(rho0_mpole=rho0_mpole, ikind=ikind, &
     554              :                              l0_ikind=l0_ikind, Qlm_gg=Qlm_gg, &  ! Qs different
     555        52004 :                              rpgf0_s=rpgf0)
     556              : 
     557              :          CALL get_gto_basis_set(gto_basis_set=basis_1c_set, &
     558              :                                 lmax=lmax, lmin=lmin, &
     559              :                                 maxso=maxso, maxl=maxl, &
     560        52004 :                                 nset=nset, npgf=npgf)
     561              : 
     562        52004 :          nsotot = maxso*nset
     563       208016 :          ALLOCATE (intloc(nsotot, nsotot))
     564              : 
     565              :          ! Initialize the local KS integrals
     566              : 
     567        52004 :          nch_ik = ncoset(l0_ikind)
     568       654154 :          pab = 1.0_dp
     569        52004 :          max_s_harm = harmonics%max_s_harm
     570        52004 :          llmax = harmonics%llmax
     571              : 
     572        52004 :          NULLIFY (intloc_nuc)
     573        52004 :          maxl_nuc = -1
     574        52004 :          max_s_harm_nuc = 0
     575        52004 :          llmax_nuc = -1
     576        52004 :          IF (ASSOCIATED(cneo_potential)) THEN
     577           48 :             NULLIFY (nuc_basis_set)
     578              :             CALL get_qs_kind(qs_kind_set(ikind), &
     579              :                              basis_set=nuc_basis_set, &
     580           48 :                              basis_type="NUC")
     581              : 
     582              :             CALL get_gto_basis_set(gto_basis_set=nuc_basis_set, &
     583              :                                    lmax=lmax_nuc, lmin=lmin_nuc, &
     584              :                                    maxso=maxso_nuc, maxl=maxl_nuc, &
     585           48 :                                    nset=nset_nuc, npgf=npgf_nuc)
     586           48 :             nsotot_nuc = maxso_nuc*nset_nuc
     587          192 :             ALLOCATE (intloc_nuc(nsotot_nuc, nsotot_nuc))
     588           48 :             max_s_harm_nuc = cneo_potential%harmonics%max_s_harm
     589           96 :             llmax_nuc = cneo_potential%harmonics%llmax
     590              :          END IF
     591              : 
     592            0 :          ALLOCATE (cg_list(2, nsoset(MAX(maxl, maxl_nuc))**2, &
     593              :                            MAX(max_s_harm, max_s_harm_nuc)), &
     594       312024 :                    cg_n_list(MAX(max_s_harm, max_s_harm_nuc)))
     595              : 
     596        52004 :          num_pe = para_env%num_pe
     597        52004 :          mepos = para_env%mepos
     598       156012 :          DO j = 0, num_pe - 1
     599       104008 :             bo = get_limit(nat, num_pe, j)
     600       104008 :             IF (.NOT. grid_distributed .AND. j /= mepos) CYCLE
     601              : 
     602       145153 :             DO iat = bo(1), bo(2)
     603        41145 :                iatom = atom_list(iat)
     604        41145 :                ra(:) = pbc(particle_set(iatom)%r, cell)
     605              : 
     606        41145 :                NULLIFY (Qlm)
     607        41145 :                CALL get_rho0_mpole(rho0_mpole=rho0_mpole, iat=iatom, Qlm_tot=Qlm)
     608              : 
     609       507254 :                hab = 0.0_dp
     610      1782146 :                hdab = 0.0_dp
     611    137891159 :                intloc = 0._dp
     612        41145 :                IF (use_virial) THEN
     613          949 :                   my_virial_a = 0.0_dp
     614          949 :                   my_virial_b = 0.0_dp
     615       119652 :                   a_hdab = 0.0_dp
     616              :                END IF
     617              : 
     618              :                CALL integrate_pgf_product( &
     619              :                   l0_ikind, zet0, 0, 0, 0.0_dp, 0, &
     620              :                   ra, [0.0_dp, 0.0_dp, 0.0_dp], rs_v, &
     621              :                   hab, pab, o1=0, o2=0, &
     622              :                   radius=rpgf0, &
     623              :                   calculate_forces=calculate_forces, &
     624              :                   use_virial=use_virial, my_virial_a=my_virial_a, my_virial_b=my_virial_b, &
     625        41145 :                   hdab=hdab, a_hdab=a_hdab, use_subpatch=.TRUE., subpatch_pattern=0)
     626              : 
     627              :                ! Convert from cartesian to spherical
     628       150350 :                DO lshell = 0, l0_ikind
     629       468399 :                   DO is = 1, nso(lshell)
     630       318049 :                      iso = is + nsoset(lshell - 1)
     631       318049 :                      hab_sph(iso) = 0.0_dp
     632      1272196 :                      hdab_sph(1:3, iso) = 0.0_dp
     633      4134637 :                      a_hdab_sph(1:3, 1:3, iso) = 0.0_dp
     634      1892347 :                      DO ic = 1, nco(lshell)
     635      1465093 :                         ico = ic + ncoset(lshell - 1)
     636      1465093 :                         lx = indco(1, ico)
     637      1465093 :                         ly = indco(2, ico)
     638      1465093 :                         lz = indco(3, ico)
     639              :                         hab_sph(iso) = hab_sph(iso) + &
     640              :                                        norm_l(lshell)* &
     641              :                                        orbtramat(lshell)%slm(is, ic)* &
     642      1465093 :                                        hab(ico, 1)
     643      1465093 :                         IF (calculate_forces) THEN
     644              :                            hdab_sph(1:3, iso) = hdab_sph(1:3, iso) + &
     645              :                                                 norm_l(lshell)* &
     646              :                                                 orbtramat(lshell)%slm(is, ic)* &
     647       541824 :                                                 hdab(1:3, ico, 1)
     648              :                         END IF
     649      1783142 :                         IF (use_virial) THEN
     650       142792 :                            DO ii = 1, 3
     651       464074 :                            DO i = 1, 3
     652              :                               a_hdab_sph(i, ii, iso) = a_hdab_sph(i, ii, iso) + &
     653              :                                                        norm_l(lshell)* &
     654              :                                                        orbtramat(lshell)%slm(is, ic)* &
     655       428376 :                                                        a_hdab(i, ii, ico, 1)
     656              :                            END DO
     657              :                            END DO
     658              :                         END IF
     659              : 
     660              :                      END DO ! ic
     661              :                   END DO ! is
     662              :                END DO ! lshell
     663              : 
     664              :                m1 = 0
     665       143391 :                DO iset1 = 1, nset
     666              : 
     667              :                   m2 = 0
     668       439816 :                   DO iset2 = 1, nset
     669              :                      CALL get_none0_cg_list(harmonics%my_CG, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
     670       337570 :                                             max_s_harm, llmax, cg_list, cg_n_list, max_iso_not0_local)
     671       337570 :                      n1 = nsoset(lmax(iset1))
     672      1187948 :                      DO ipgf1 = 1, npgf(iset1)
     673       850378 :                         n2 = nsoset(lmax(iset2))
     674      3666475 :                         DO ipgf2 = 1, npgf(iset2)
     675              : 
     676     16538809 :                            DO iso = 1, MIN(nsoset(l0_ikind), max_iso_not0_local)
     677     39980413 :                               DO icg = 1, cg_n_list(iso)
     678     24291982 :                                  iso1 = cg_list(1, icg, iso)
     679     24291982 :                                  iso2 = cg_list(2, icg, iso)
     680              : 
     681     24291982 :                                  ig1 = iso1 + n1*(ipgf1 - 1) + m1
     682     24291982 :                                  ig2 = iso2 + n2*(ipgf2 - 1) + m2
     683              : 
     684     37501886 :                                  intloc(ig1, ig2) = intloc(ig1, ig2) + Qlm_gg(ig1, ig2, iso)*hab_sph(iso) ! potential times Q
     685              : 
     686              :                               END DO ! icg
     687              :                            END DO ! iso
     688              : 
     689              :                         END DO ! ipgf2
     690              :                      END DO ! ipgf1
     691       777386 :                      m2 = m2 + maxso
     692              :                   END DO ! iset2
     693       143391 :                   m1 = m1 + maxso
     694              :                END DO ! iset1
     695              : 
     696        41145 :                IF (ASSOCIATED(cneo_potential)) THEN
     697       305578 :                   intloc_nuc = 0.0_dp
     698           46 :                   m1 = 0
     699          460 :                   DO iset1 = 1, nset_nuc
     700          414 :                      n1 = nsoset(lmax_nuc(iset1))
     701          414 :                      m2 = 0
     702         4140 :                      DO iset2 = 1, nset_nuc
     703         3726 :                         n2 = nsoset(lmax_nuc(iset2))
     704              :                         CALL get_none0_cg_list(cneo_potential%harmonics%my_CG, lmin_nuc(iset1), &
     705              :                                                lmax_nuc(iset1), lmin_nuc(iset2), lmax_nuc(iset2), &
     706              :                                                max_s_harm_nuc, llmax_nuc, cg_list, cg_n_list, &
     707         3726 :                                                max_iso_not0_local)
     708         7452 :                         DO ipgf1 = 1, npgf_nuc(iset1)
     709        11178 :                            DO ipgf2 = 1, npgf_nuc(iset2)
     710              : 
     711        29578 :                               DO iso = 1, MIN(nsoset(l0_ikind), max_iso_not0_local)
     712        50968 :                                  DO icg = 1, cg_n_list(iso)
     713        25116 :                                     iso1 = cg_list(1, icg, iso)
     714        25116 :                                     iso2 = cg_list(2, icg, iso)
     715              : 
     716        25116 :                                     ig1 = iso1 + n1*(ipgf1 - 1) + m1
     717        25116 :                                     ig2 = iso2 + n2*(ipgf2 - 1) + m2
     718              : 
     719              :                                     intloc_nuc(ig1, ig2) = intloc_nuc(ig1, ig2) - cneo_potential%zeff* &
     720        47242 :                                                            cneo_potential%Qlm_gg(ig1, ig2, iso)*hab_sph(iso)
     721              : 
     722              :                                  END DO ! icg
     723              :                               END DO ! iso
     724              : 
     725              :                            END DO ! ipgf2
     726              :                         END DO ! ipgf1
     727         7866 :                         m2 = m2 + maxso_nuc
     728              :                      END DO ! iset2
     729          460 :                      m1 = m1 + maxso_nuc
     730              :                   END DO ! iset1
     731              :                END IF
     732              : 
     733        41145 :                IF (grid_distributed) THEN
     734              :                   ! Sum result over all processors
     735            0 :                   CALL para_env%sum(intloc)
     736            0 :                   IF (ASSOCIATED(cneo_potential)) THEN
     737            0 :                      CALL para_env%sum(intloc_nuc)
     738              :                   END IF
     739              :                END IF
     740              : 
     741        41145 :                IF (j == mepos) THEN
     742        41145 :                   rho_atom => rho_atom_set(iatom)
     743        41145 :                   CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_local_h, ga_Vlocal_gb_s=int_local_s)
     744        88301 :                   DO ispin = 1, nspins
     745    305007172 :                      int_local_h(ispin)%r_coef = int_local_h(ispin)%r_coef + intloc
     746    305048317 :                      int_local_s(ispin)%r_coef = int_local_s(ispin)%r_coef + intloc
     747              :                   END DO
     748        41145 :                   IF (ASSOCIATED(cneo_potential)) THEN
     749           46 :                      rhoz_cneo => rhoz_cneo_set(iatom)
     750       611156 :                      rhoz_cneo%ga_Vlocal_gb_h = rhoz_cneo%ga_Vlocal_gb_h + intloc_nuc
     751       611156 :                      rhoz_cneo%ga_Vlocal_gb_s = rhoz_cneo%ga_Vlocal_gb_s + intloc_nuc
     752              :                   END IF
     753              :                END IF
     754              : 
     755        41145 :                IF (PRESENT(atener)) THEN
     756          178 :                   DO iso = 1, nsoset(l0_ikind)
     757          178 :                      atener(iatom) = atener(iatom) + 0.5_dp*Qlm(iso)*hab_sph(iso)
     758              :                   END DO
     759              :                END IF
     760              : 
     761        41145 :                IF (calculate_forces) THEN
     762         1662 :                   force_tmp(1:3) = 0.0_dp
     763        15860 :                   DO iso = 1, nsoset(l0_ikind)
     764        14198 :                      force_tmp(1) = force_tmp(1) + Qlm(iso)*hdab_sph(1, iso) ! Q here is from local_rho_set
     765        14198 :                      force_tmp(2) = force_tmp(2) + Qlm(iso)*hdab_sph(2, iso)
     766        15860 :                      force_tmp(3) = force_tmp(3) + Qlm(iso)*hdab_sph(3, iso)
     767              :                   END DO
     768         6648 :                   force(ikind)%g0s_Vh_elec(1:3, iat) = force(ikind)%g0s_Vh_elec(1:3, iat) + fscale*force_tmp(1:3)
     769              :                END IF
     770       145153 :                IF (use_virial) THEN
     771          949 :                   my_virial_a = 0.0_dp
     772         9026 :                   DO iso = 1, nsoset(l0_ikind)
     773        33257 :                      DO ii = 1, 3
     774       105001 :                      DO i = 1, 3
     775              :                         ! Q from local_rho_set
     776        72693 :                         virial%pv_gapw(i, ii) = virial%pv_gapw(i, ii) + fscale*Qlm(iso)*a_hdab_sph(i, ii, iso)
     777        96924 :                         virial%pv_virial(i, ii) = virial%pv_virial(i, ii) + fscale*Qlm(iso)*a_hdab_sph(i, ii, iso)
     778              :                      END DO
     779              :                      END DO
     780              :                   END DO
     781              :                END IF
     782              : 
     783              :             END DO
     784              :          END DO
     785              : 
     786        52004 :          DEALLOCATE (intloc)
     787        52004 :          IF (ASSOCIATED(intloc_nuc)) DEALLOCATE (intloc_nuc)
     788       191974 :          DEALLOCATE (cg_list, cg_n_list)
     789              : 
     790              :       END DO ! ikind
     791              : 
     792        29254 :       CALL rs_grid_release(rs_v)
     793              : 
     794        29254 :       DEALLOCATE (hab, hdab, hab_sph, hdab_sph, pab, a_hdab, a_hdab_sph)
     795              : 
     796        29254 :       CALL timestop(handle)
     797              : 
     798        29254 :       IF (rho0_mpole%do_cneo) THEN
     799           48 :          IF (PRESENT(kforce)) THEN
     800              :             CALL integrate_vhgg_rspace(qs_env, v_rspace, para_env, calculate_forces, &
     801            0 :                                        rhoz_cneo_set, kforce)
     802              :          ELSE
     803              :             CALL integrate_vhgg_rspace(qs_env, v_rspace, para_env, calculate_forces, &
     804           48 :                                        rhoz_cneo_set)
     805              :          END IF
     806              :       END IF
     807              : 
     808        58508 :    END SUBROUTINE integrate_vhg0_rspace
     809              : 
     810              : END MODULE qs_rho0_ggrid
        

Generated by: LCOV version 2.0-1