LCOV - code coverage report
Current view: top level - src - accint_weights_forces.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:92574dc) Lines: 88.5 % 356 315
Test Date: 2026-09-24 01:27:39 Functions: 100.0 % 8 8

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief
      10              : !> \author JGH (01.2026)
      11              : ! **************************************************************************************************
      12              : MODULE accint_weights_forces
      13              :    USE ao_util,                         ONLY: exp_radius_very_extended
      14              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      15              :                                               get_atomic_kind
      16              :    USE cell_types,                      ONLY: cell_type,&
      17              :                                               pbc
      18              :    USE cp_control_types,                ONLY: dft_control_type
      19              :    USE cp_log_handling,                 ONLY: cp_logger_get_default_io_unit
      20              :    USE grid_api,                        ONLY: GRID_FUNC_AB,&
      21              :                                               collocate_pgf_product,&
      22              :                                               integrate_pgf_product
      23              :    USE input_constants,                 ONLY: sic_none,&
      24              :                                               xc_none
      25              :    USE input_section_types,             ONLY: section_vals_type,&
      26              :                                               section_vals_val_get
      27              :    USE kinds,                           ONLY: dp
      28              :    USE message_passing,                 ONLY: mp_para_env_type
      29              :    USE orbital_pointers,                ONLY: coset,&
      30              :                                               ncoset
      31              :    USE particle_types,                  ONLY: particle_type
      32              :    USE pw_env_types,                    ONLY: pw_env_get,&
      33              :                                               pw_env_type
      34              :    USE pw_grids,                        ONLY: pw_grid_compare
      35              :    USE pw_methods,                      ONLY: pw_axpy,&
      36              :                                               pw_multiply_with,&
      37              :                                               pw_scale,&
      38              :                                               pw_transfer,&
      39              :                                               pw_zero
      40              :    USE pw_pool_types,                   ONLY: pw_pool_p_type,&
      41              :                                               pw_pool_type
      42              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      43              :                                               pw_r3d_rs_type
      44              :    USE qs_environment_types,            ONLY: get_qs_env,&
      45              :                                               qs_environment_type
      46              :    USE qs_force_types,                  ONLY: qs_force_type
      47              :    USE qs_fxc,                          ONLY: qs_fxc_create
      48              :    USE qs_kind_types,                   ONLY: qs_kind_type
      49              :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      50              :    USE qs_rho_atom_types,               ONLY: rho_atom_type
      51              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      52              :                                               qs_rho_type
      53              :    USE realspace_grid_types,            ONLY: realspace_grid_type,&
      54              :                                               rs_grid_zero,&
      55              :                                               transfer_pw2rs,&
      56              :                                               transfer_rs2pw
      57              :    USE skala_gpw_functional,            ONLY: native_skala_gapw_atom_composite_requested,&
      58              :                                               native_skala_gapw_composite_reference,&
      59              :                                               native_skala_uses_atom_composite_grid,&
      60              :                                               skala_gapw_representation,&
      61              :                                               skala_gpw_weight_derivative,&
      62              :                                               xc_section_uses_native_skala_grid
      63              :    USE virial_types,                    ONLY: virial_type
      64              :    USE xc,                              ONLY: xc_exc_pw_create,&
      65              :                                               xc_vxc_pw_create
      66              :    USE xc_gauxc_functional,             ONLY: gauxc_gapw_has_paw_pseudopotentials
      67              :    USE xc_input_constants,              ONLY: skala_gapw_paw_one_center
      68              : #include "./base/base_uses.f90"
      69              : 
      70              :    IMPLICIT NONE
      71              : 
      72              :    PRIVATE
      73              : 
      74              :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .FALSE.
      75              : 
      76              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'accint_weights_forces'
      77              : 
      78              :    PUBLIC :: accint_weight_force, weight_function_pwgrid
      79              : 
      80              : CONTAINS
      81              : 
      82              : ! **************************************************************************************************
      83              : !> \brief ...
      84              : !> \param qs_env ...
      85              : !> \param rho ...
      86              : !> \param rho1 ...
      87              : !> \param order ...
      88              : !> \param xc_section ...
      89              : !> \param triplet ...
      90              : !> \param force_scale ...
      91              : ! **************************************************************************************************
      92         1548 :    SUBROUTINE accint_weight_force(qs_env, rho, rho1, order, xc_section, triplet, force_scale)
      93              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      94              :       TYPE(qs_rho_type), POINTER                         :: rho, rho1
      95              :       INTEGER, INTENT(IN)                                :: order
      96              :       TYPE(section_vals_type), POINTER                   :: xc_section
      97              :       LOGICAL, INTENT(IN), OPTIONAL                      :: triplet
      98              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: force_scale
      99              : 
     100              :       CHARACTER(len=*), PARAMETER :: routineN = 'accint_weight_force'
     101              : 
     102              :       INTEGER                                            :: atom_a, handle, i, iatom, ikind, natom, &
     103              :                                                             natom_of_kind, nkind, ounit, oweight
     104         1548 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     105              :       LOGICAL                                            :: composite_reference, lr_triplet, &
     106              :                                                             native_grid_diagnostics, &
     107              :                                                             native_skala_grid, uf_grid, use_virial
     108              :       REAL(KIND=dp)                                      :: my_force_scale
     109         1548 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: calpha, cvalue
     110         1548 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: aforce
     111              :       REAL(KIND=dp), DIMENSION(3)                        :: tforce
     112              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: avirial
     113         1548 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     114              :       TYPE(dft_control_type), POINTER                    :: dft_control
     115              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     116              :       TYPE(pw_env_type), POINTER                         :: pw_env
     117              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, xc_pw_pool
     118              :       TYPE(pw_r3d_rs_type)                               :: e_force_rspace, e_rspace
     119         1548 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     120         1548 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     121              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     122              :       TYPE(virial_type), POINTER                         :: virial
     123              : 
     124         1548 :       CALL timeset(routineN, handle)
     125              : 
     126         1548 :       CALL get_qs_env(qs_env, dft_control=dft_control, qs_kind_set=qs_kind_set)
     127              : 
     128              :       ! Composite references replace the PW XC quadrature and its Gaussian weight derivative.
     129              :       ! The public selector applies only when a pseudopotential kind actually uses PAW one-center
     130              :       ! data; it must not change all-electron GAPW integration.
     131              :       composite_reference = native_skala_gapw_composite_reference(xc_section) .OR. &
     132         1548 :                             native_skala_gapw_atom_composite_requested(xc_section)
     133              :       IF (.NOT. composite_reference) THEN
     134              :          composite_reference = skala_gapw_representation(xc_section) == &
     135              :             skala_gapw_paw_one_center .AND. &
     136         1548 :             gauxc_gapw_has_paw_pseudopotentials(qs_kind_set)
     137              :       END IF
     138         1520 :       IF (.NOT. composite_reference .AND. xc_section_uses_native_skala_grid(xc_section)) THEN
     139           24 :          composite_reference = native_skala_uses_atom_composite_grid(xc_section)
     140              :       END IF
     141         1520 :       IF (composite_reference) THEN
     142           52 :          CALL timestop(handle)
     143           52 :          RETURN
     144              :       END IF
     145              : 
     146         1496 :       IF (dft_control%qs_control%gapw_control%accurate_xcint) THEN
     147              : 
     148          406 :          CALL get_qs_env(qs_env=qs_env, force=force, virial=virial)
     149          406 :          use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     150              : 
     151          406 :          ounit = cp_logger_get_default_io_unit()
     152              : 
     153          406 :          CALL get_qs_env(qs_env, natom=natom, nkind=nkind)
     154         1218 :          ALLOCATE (aforce(3, natom))
     155         1624 :          ALLOCATE (calpha(nkind), cvalue(nkind))
     156         1236 :          cvalue = 1.0_dp
     157         1236 :          calpha(1:nkind) = dft_control%qs_control%gapw_control%aw(1:nkind)
     158          406 :          oweight = dft_control%qs_control%gapw_control%oweights
     159              : 
     160          406 :          CALL get_qs_env(qs_env, ks_env=ks_env, pw_env=pw_env)
     161          406 :          CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
     162          406 :          uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
     163          406 :          IF (uf_grid) THEN
     164           44 :             CALL xc_pw_pool%create_pw(e_rspace)
     165              :          ELSE
     166          362 :             CALL auxbas_pw_pool%create_pw(e_rspace)
     167              :          END IF
     168              : 
     169          406 :          lr_triplet = .FALSE.
     170          406 :          IF (PRESENT(triplet)) lr_triplet = triplet
     171          406 :          my_force_scale = 1.0_dp
     172          406 :          IF (PRESENT(force_scale)) my_force_scale = force_scale
     173              : 
     174          406 :          CALL xc_density(qs_env, rho, rho1, order, xc_section, lr_triplet, e_rspace)
     175              : 
     176          406 :          IF (uf_grid) THEN
     177           44 :             CALL auxbas_pw_pool%create_pw(e_force_rspace)
     178              :             BLOCK
     179              :                TYPE(pw_c1d_gs_type) :: e_g_aux, e_g_xc
     180           44 :                CALL xc_pw_pool%create_pw(e_g_xc)
     181           44 :                CALL auxbas_pw_pool%create_pw(e_g_aux)
     182           44 :                CALL pw_transfer(e_rspace, e_g_xc)
     183           44 :                CALL pw_transfer(e_g_xc, e_g_aux)
     184           44 :                CALL pw_transfer(e_g_aux, e_force_rspace)
     185           44 :                CALL auxbas_pw_pool%give_back_pw(e_g_aux)
     186           88 :                CALL xc_pw_pool%give_back_pw(e_g_xc)
     187              :             END BLOCK
     188           44 :             CALL pw_scale(e_force_rspace, e_force_rspace%pw_grid%dvol)
     189              :             ! integrate energy field to get force
     190           44 :             CALL gauss_grid_force(e_force_rspace, qs_env, oweight, calpha, cvalue, aforce, avirial)
     191              :             !
     192           44 :             CALL auxbas_pw_pool%give_back_pw(e_force_rspace)
     193              :          ELSE
     194          362 :             CALL pw_scale(e_rspace, e_rspace%pw_grid%dvol)
     195          362 :             CALL gauss_grid_force(e_rspace, qs_env, oweight, calpha, cvalue, aforce, avirial)
     196              :          END IF
     197              : 
     198          406 :          IF (uf_grid) THEN
     199           44 :             CALL xc_pw_pool%give_back_pw(e_rspace)
     200              :          ELSE
     201          362 :             CALL auxbas_pw_pool%give_back_pw(e_rspace)
     202              :          END IF
     203              : 
     204          406 :          CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
     205          406 :          native_skala_grid = xc_section_uses_native_skala_grid(xc_section)
     206          406 :          native_grid_diagnostics = .FALSE.
     207          406 :          IF (native_skala_grid) THEN
     208              :             CALL section_vals_val_get(xc_section, "XC_FUNCTIONAL%GAUXC%NATIVE_GRID_DIAGNOSTICS", &
     209            0 :                                       l_val=native_grid_diagnostics)
     210              :          END IF
     211         1236 :          DO ikind = 1, nkind
     212          830 :             CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
     213         2482 :             DO iatom = 1, natom_of_kind
     214         1246 :                atom_a = atom_list(iatom)
     215         1246 :                IF (native_grid_diagnostics) THEN
     216            0 :                   IF (ounit > 0) THEN
     217              :                      WRITE (UNIT=ounit, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
     218            0 :                         "SKALA_GPW| Accurate-XCINT atom force", atom_a, my_force_scale*aforce(:, atom_a)
     219              :                   END IF
     220              :                END IF
     221              :                force(ikind)%rho_elec(1:3, iatom) = &
     222         5814 :                   force(ikind)%rho_elec(1:3, iatom) + my_force_scale*aforce(1:3, atom_a)
     223              :             END DO
     224              :          END DO
     225          406 :          IF (use_virial) THEN
     226          754 :             virial%pv_exc = virial%pv_exc + my_force_scale*avirial
     227          754 :             virial%pv_virial = virial%pv_virial + my_force_scale*avirial
     228              :          END IF
     229              : 
     230              :          IF (debug_this_module) THEN
     231              :             CALL get_qs_env(qs_env, para_env=para_env)
     232              :             CALL para_env%sum(aforce)
     233              :             IF (ounit > 0) THEN
     234              :                WRITE (UNIT=ounit, FMT="(/,T2,A)") "ACCINT| Debug Accurate-XCINT atom force [a.u.]"
     235              :                DO i = 1, 3
     236              :                   tforce(i) = my_force_scale*SUM(aforce(i, :))
     237              :                END DO
     238              :                DO iatom = 1, natom
     239              :                   WRITE (UNIT=ounit, FMT="(T2,A,1X,I0,T24,3(1X,F18.12))") &
     240              :                      "ACCINT| ", iatom, my_force_scale*aforce(1:3, iatom)
     241              :                END DO
     242              :                WRITE (UNIT=ounit, FMT="(T2,A,T24,3(1X,F18.12))") &
     243              :                   "ACCINT| Total force ", tforce(1:3)
     244              :             END IF
     245              :             IF (use_virial) THEN
     246              :                CALL para_env%sum(avirial)
     247              :                IF (ounit > 0) THEN
     248              :                   WRITE (UNIT=ounit, FMT="(/,T2,A)") "ACCINT| Debug Accurate-XCINT virial"
     249              :                   DO i = 1, 3
     250              :                      WRITE (UNIT=ounit, FMT="(T2,A,T24,3(1X,F18.8))") &
     251              :                         "ACCINT| [a.u.] ", my_force_scale*avirial(i, 1:3)
     252              :                   END DO
     253              :                END IF
     254              :             END IF
     255              :          END IF
     256              : 
     257          406 :          DEALLOCATE (aforce, calpha, cvalue)
     258              : 
     259              :       END IF
     260              : 
     261         1496 :       CALL timestop(handle)
     262              : 
     263         3096 :    END SUBROUTINE accint_weight_force
     264              : 
     265              : ! **************************************************************************************************
     266              : !> \brief computes the forces/virial due to atomic centered Gaussian functions
     267              : !> \param e_rspace Energy density
     268              : !> \param qs_env ...
     269              : !> \param order ...
     270              : !> \param calpha ...
     271              : !> \param cvalue ...
     272              : !> \param aforce ...
     273              : !> \param avirial ...
     274              : ! **************************************************************************************************
     275          406 :    SUBROUTINE gauss_grid_force(e_rspace, qs_env, order, calpha, cvalue, aforce, avirial)
     276              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: e_rspace
     277              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     278              :       INTEGER, INTENT(IN)                                :: order
     279              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: calpha, cvalue
     280              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT)        :: aforce
     281              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT)        :: avirial
     282              : 
     283              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'gauss_grid_force'
     284              : 
     285              :       INTEGER                                            :: atom_a, handle, iatom, igrid, ikind, j, &
     286              :                                                             natom_of_kind, ni, npme, on
     287          406 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: cores
     288          406 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     289              :       LOGICAL                                            :: use_virial
     290              :       REAL(KIND=dp)                                      :: alpha, eps_rho_rspace, radius
     291              :       REAL(KIND=dp), DIMENSION(3)                        :: force_a, force_b, ra
     292              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: my_virial_a, my_virial_b
     293          406 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: hab, pab
     294          406 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     295              :       TYPE(cell_type), POINTER                           :: cell
     296              :       TYPE(dft_control_type), POINTER                    :: dft_control
     297          406 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     298              :       TYPE(pw_env_type), POINTER                         :: pw_env
     299          406 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
     300          406 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_grids
     301              :       TYPE(realspace_grid_type), POINTER                 :: rs_v
     302              : 
     303          406 :       CALL timeset(routineN, handle)
     304              : 
     305          406 :       on = 2*order
     306          406 :       ni = ncoset(on)
     307         1218 :       ALLOCATE (hab(ni, 1))
     308          812 :       ALLOCATE (pab(ni, 1))
     309              : 
     310          406 :       NULLIFY (pw_pools, rs_grids, rs_v)
     311              : 
     312          406 :       CALL get_qs_env(qs_env, pw_env=pw_env)
     313          406 :       CALL pw_env_get(pw_env, pw_pools=pw_pools, rs_grids=rs_grids)
     314          406 :       DO igrid = 1, SIZE(pw_pools)
     315          406 :          IF (pw_grid_compare(e_rspace%pw_grid, pw_pools(igrid)%pool%pw_grid)) THEN
     316          406 :             rs_v => rs_grids(igrid)
     317          406 :             EXIT
     318              :          END IF
     319              :       END DO
     320          406 :       IF (.NOT. ASSOCIATED(rs_v)) THEN
     321            0 :          CPABORT("No realspace grid for Accurate-XCINT weight force")
     322              :       END IF
     323              : 
     324          406 :       CALL transfer_pw2rs(rs_v, e_rspace)
     325              : 
     326              :       CALL get_qs_env(qs_env, &
     327              :                       atomic_kind_set=atomic_kind_set, &
     328              :                       cell=cell, &
     329              :                       dft_control=dft_control, &
     330          406 :                       particle_set=particle_set)
     331              : 
     332          406 :       use_virial = .TRUE.
     333          406 :       avirial = 0.0_dp
     334         5390 :       aforce = 0.0_dp
     335              : 
     336          406 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     337              : 
     338         1236 :       DO ikind = 1, SIZE(atomic_kind_set)
     339              : 
     340          830 :          alpha = calpha(ikind)
     341          830 :          IF (alpha == 0.0_dp) CYCLE
     342              : 
     343          810 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
     344              : 
     345          810 :          CALL set_polynom_coefs(pab(:, 1), order, alpha)
     346         1688 :          pab(:, 1) = -cvalue(ikind)*pab(:, 1)
     347              : 
     348         2430 :          ALLOCATE (cores(natom_of_kind))
     349          810 :          npme = 0
     350          810 :          cores = 0
     351              : 
     352         2024 :          DO iatom = 1, natom_of_kind
     353         1214 :             atom_a = atom_list(iatom)
     354         1214 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
     355         2024 :             IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
     356              :                ! replicated realspace grid, split the atoms up between procs
     357         1214 :                IF (MODULO(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
     358          607 :                   npme = npme + 1
     359          607 :                   cores(npme) = iatom
     360              :                END IF
     361              :             ELSE
     362            0 :                npme = npme + 1
     363            0 :                cores(npme) = iatom
     364              :             END IF
     365              :          END DO
     366              : 
     367         1417 :          DO j = 1, npme
     368              : 
     369          607 :             iatom = cores(j)
     370          607 :             atom_a = atom_list(iatom)
     371          607 :             ra(:) = pbc(particle_set(atom_a)%r, cell)
     372         1282 :             hab(:, 1) = 0.0_dp
     373          607 :             force_a(:) = 0.0_dp
     374          607 :             force_b(:) = 0.0_dp
     375          607 :             my_virial_a = 0.0_dp
     376          607 :             my_virial_b = 0.0_dp
     377              : 
     378              :             radius = exp_radius_very_extended(la_min=0, la_max=on, lb_min=0, lb_max=0, &
     379              :                                               ra=ra, rb=ra, rp=ra, &
     380              :                                               zetp=alpha, eps=eps_rho_rspace, &
     381              :                                               pab=pab, o1=0, o2=0, &
     382          607 :                                               prefactor=1.0_dp, cutoff=1.0_dp)
     383              : 
     384              :             CALL integrate_pgf_product(on, alpha, 0, &
     385              :                                        0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], &
     386              :                                        rs_v, hab, pab=pab, o1=0, o2=0, &
     387              :                                        radius=radius, &
     388              :                                        calculate_forces=.TRUE., force_a=force_a, &
     389              :                                        force_b=force_b, use_virial=use_virial, my_virial_a=my_virial_a, &
     390          607 :                                        my_virial_b=my_virial_b, use_subpatch=.TRUE., subpatch_pattern=0)
     391              : 
     392         2428 :             aforce(1:3, atom_a) = aforce(1:3, atom_a) + force_a(1:3)
     393         8701 :             avirial = avirial + my_virial_a
     394              : 
     395              :          END DO
     396         2046 :          DEALLOCATE (cores)
     397              : 
     398              :       END DO
     399              : 
     400          406 :       DEALLOCATE (hab, pab)
     401              : 
     402          406 :       CALL timestop(handle)
     403              : 
     404          812 :    END SUBROUTINE gauss_grid_force
     405              : 
     406              : ! **************************************************************************************************
     407              : !> \brief computes the weight function on the PW grid
     408              : !> \param rho_core ...
     409              : !> \param qs_env ...
     410              : !> \param order ...
     411              : !> \param calpha ...
     412              : !> \param ccore ...
     413              : ! **************************************************************************************************
     414          670 :    SUBROUTINE weight_function_pwgrid(rho_core, qs_env, order, calpha, ccore)
     415              :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                :: rho_core
     416              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     417              :       INTEGER, INTENT(IN)                                :: order
     418              :       REAL(KIND=dp), DIMENSION(:)                        :: calpha, ccore
     419              : 
     420              :       CHARACTER(len=*), PARAMETER :: routineN = 'weight_function_pwgrid'
     421              : 
     422              :       INTEGER                                            :: atom_a, handle, iatom, ikind, ithread, &
     423              :                                                             j, natom, ni, npme, nthread, on, &
     424              :                                                             subpatch_pattern
     425          670 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: cores
     426          670 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     427              :       REAL(KIND=dp)                                      :: alpha, eps_rho_rspace, radius
     428              :       REAL(KIND=dp), DIMENSION(3)                        :: ra
     429          670 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
     430          670 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     431              :       TYPE(cell_type), POINTER                           :: cell
     432              :       TYPE(dft_control_type), POINTER                    :: dft_control
     433          670 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     434              :       TYPE(pw_env_type), POINTER                         :: pw_env
     435              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     436              :       TYPE(pw_r3d_rs_type)                               :: rhoc_r
     437          670 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     438              :       TYPE(realspace_grid_type), POINTER                 :: rs_rho
     439              : 
     440          670 :       CALL timeset(routineN, handle)
     441              : 
     442          670 :       on = 2*order
     443          670 :       ni = ncoset(on)
     444         2010 :       ALLOCATE (pab(ni, 1))
     445              : 
     446              :       CALL get_qs_env(qs_env=qs_env, &
     447              :                       atomic_kind_set=atomic_kind_set, &
     448              :                       qs_kind_set=qs_kind_set, &
     449              :                       cell=cell, &
     450              :                       dft_control=dft_control, &
     451              :                       particle_set=particle_set, &
     452          670 :                       pw_env=pw_env)
     453              :       CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
     454          670 :                       auxbas_pw_pool=auxbas_pw_pool)
     455              :       ! be careful in parallel nsmax is chosen with multigrid in mind!
     456          670 :       CALL rs_grid_zero(rs_rho)
     457              : 
     458          670 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
     459              : 
     460         1978 :       DO ikind = 1, SIZE(atomic_kind_set)
     461         1308 :          alpha = calpha(ikind)
     462         1308 :          IF (alpha == 0.0_dp) CYCLE
     463              : 
     464         1270 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
     465              : 
     466         1270 :          CALL set_polynom_coefs(pab(:, 1), order, alpha)
     467         2880 :          pab(:, 1) = ccore(ikind)*pab(:, 1)
     468              : 
     469         1270 :          nthread = 1
     470         1270 :          ithread = 0
     471              : 
     472         3810 :          ALLOCATE (cores(natom))
     473         1270 :          npme = 0
     474         1270 :          cores = 0
     475              : 
     476         3146 :          DO iatom = 1, natom
     477         3146 :             IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
     478              :                ! replicated realspace grid, split the atoms up between procs
     479         1876 :                IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
     480          938 :                   npme = npme + 1
     481          938 :                   cores(npme) = iatom
     482              :                END IF
     483              :             ELSE
     484            0 :                npme = npme + 1
     485            0 :                cores(npme) = iatom
     486              :             END IF
     487              :          END DO
     488              : 
     489         1270 :          IF (npme > 0) THEN
     490         1841 :             DO j = 1, npme
     491              : 
     492          938 :                iatom = cores(j)
     493          938 :                atom_a = atom_list(iatom)
     494          938 :                ra(:) = pbc(particle_set(atom_a)%r, cell)
     495          938 :                subpatch_pattern = 0
     496              :                radius = exp_radius_very_extended(la_min=0, la_max=on, &
     497              :                                                  lb_min=0, lb_max=0, &
     498              :                                                  ra=ra, rb=ra, rp=ra, &
     499              :                                                  zetp=alpha, eps=eps_rho_rspace, &
     500              :                                                  pab=pab, o1=0, o2=0, &  ! without map_consistent
     501          938 :                                                  prefactor=-1.0_dp, cutoff=0.0_dp)
     502              : 
     503              :                CALL collocate_pgf_product(on, alpha, 0, 0, 0.0_dp, 0, ra, &
     504              :                                           [0.0_dp, 0.0_dp, 0.0_dp], -1.0_dp, pab, 0, 0, rs_rho, &
     505              :                                           radius=radius, ga_gb_function=GRID_FUNC_AB, &
     506         1841 :                                           use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
     507              : 
     508              :             END DO
     509              :          END IF
     510         3248 :          DEALLOCATE (cores)
     511              : 
     512              :       END DO
     513              : 
     514          670 :       DEALLOCATE (pab)
     515              : 
     516          670 :       CALL auxbas_pw_pool%create_pw(rhoc_r)
     517              : 
     518          670 :       CALL transfer_rs2pw(rs_rho, rhoc_r)
     519              : 
     520          670 :       CALL pw_transfer(rhoc_r, rho_core)
     521              : 
     522          670 :       CALL auxbas_pw_pool%give_back_pw(rhoc_r)
     523              : 
     524          670 :       CALL timestop(handle)
     525              : 
     526         1340 :    END SUBROUTINE weight_function_pwgrid
     527              : 
     528              : ! **************************************************************************************************
     529              : !> \brief Set the prefactor coefficients for the expansion of the radial weight function in
     530              : !>        cartesian spherical harmonics
     531              : !> \param pf  output coefficients
     532              : !> \param order  ...
     533              : !> \param alpha  ...
     534              : ! **************************************************************************************************
     535         2080 :    SUBROUTINE set_polynom_coefs(pf, order, alpha)
     536              :       REAL(kind=dp), DIMENSION(:), INTENT(OUT)           :: pf
     537              :       INTEGER, INTENT(IN)                                :: order
     538              :       REAL(kind=dp), INTENT(IN)                          :: alpha
     539              : 
     540              :       INTEGER                                            :: i
     541              :       REAL(KIND=dp)                                      :: ap
     542              : 
     543         4568 :       pf(:) = 0.0_dp
     544              : 
     545         4184 :       DO i = 0, order
     546         2080 :          SELECT CASE (i)
     547              :          CASE (0)
     548         2080 :             pf(1) = 1.0_dp
     549              :          CASE (1)
     550           12 :             ap = alpha
     551           12 :             pf(coset(2, 0, 0)) = ap
     552           12 :             pf(coset(0, 2, 0)) = ap
     553           12 :             pf(coset(0, 0, 2)) = ap
     554              :          CASE (2)
     555           12 :             ap = alpha**2/2.0_dp
     556           12 :             pf(coset(4, 0, 0)) = ap
     557           12 :             pf(coset(0, 4, 0)) = ap
     558           12 :             pf(coset(0, 0, 4)) = ap
     559           12 :             pf(coset(2, 2, 0)) = 2._dp*ap
     560           12 :             pf(coset(2, 0, 2)) = 2._dp*ap
     561           12 :             pf(coset(0, 2, 2)) = 2._dp*ap
     562              :          CASE (3)
     563            0 :             ap = alpha**3/6.0_dp
     564            0 :             pf(coset(6, 0, 0)) = ap
     565            0 :             pf(coset(0, 6, 0)) = ap
     566            0 :             pf(coset(0, 0, 6)) = ap
     567            0 :             pf(coset(4, 2, 0)) = 3._dp*ap
     568            0 :             pf(coset(4, 0, 2)) = 3._dp*ap
     569            0 :             pf(coset(2, 4, 0)) = 3._dp*ap
     570            0 :             pf(coset(2, 0, 4)) = 3._dp*ap
     571            0 :             pf(coset(0, 4, 2)) = 3._dp*ap
     572            0 :             pf(coset(0, 2, 4)) = 3._dp*ap
     573            0 :             pf(coset(2, 2, 2)) = 6._dp*ap
     574              :          CASE DEFAULT
     575              :             CALL cp_abort(__LOCATION__, &
     576              :                           "Only 0, 1, 2, 3 are supported as the "// &
     577         2104 :                           "polynomial order value in accuarte XC integration.")
     578              :          END SELECT
     579              :       END DO
     580              : 
     581         2080 :    END SUBROUTINE set_polynom_coefs
     582              : 
     583              : ! **************************************************************************************************
     584              : !> \brief calculates the XC density:
     585              : !>        order=0: exc will contain the xc energy density E_xc(r)
     586              : !>        order=1: exc will contain V_xc(r) * rho1(r)
     587              : !>        order=2: exc will contain F_xc(r) * rho1(r) * rho1(r)
     588              : !> \param qs_env to get all the needed things
     589              : !> \param rho_struct density
     590              : !> \param rho1_struct response density
     591              : !> \param order requested derivative order
     592              : !> \param xc_section ...
     593              : !> \param triplet ...
     594              : !> \param exc Output energy density on working grid (!)
     595              : !> \author JGH
     596              : ! **************************************************************************************************
     597          812 :    SUBROUTINE xc_density(qs_env, rho_struct, rho1_struct, order, xc_section, triplet, exc)
     598              : 
     599              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     600              :       TYPE(qs_rho_type), POINTER                         :: rho_struct, rho1_struct
     601              :       INTEGER, INTENT(IN)                                :: order
     602              :       TYPE(section_vals_type), POINTER                   :: xc_section
     603              :       LOGICAL, INTENT(IN)                                :: triplet
     604              :       TYPE(pw_r3d_rs_type)                               :: exc
     605              : 
     606              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'xc_density'
     607              : 
     608              :       INTEGER                                            :: handle, ispin, myfun, nspins
     609              :       LOGICAL                                            :: native_skala_grid, rho1_g_valid, &
     610              :                                                             rho_g_valid, tau1_valid, tau_valid, &
     611              :                                                             uf_grid
     612              :       REAL(KIND=dp)                                      :: excint, factor
     613              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: vdum
     614              :       TYPE(cell_type), POINTER                           :: cell
     615              :       TYPE(dft_control_type), POINTER                    :: dft_control
     616          406 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     617          406 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho1_g, rho1_g_xc, rho_g, rho_g_xc
     618              :       TYPE(pw_c1d_gs_type), POINTER                      :: rho_nlcc_g
     619              :       TYPE(pw_env_type), POINTER                         :: pw_env
     620              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, xc_pw_pool
     621          406 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho1_r, rho1_r_xc, rho_r, rho_r_xc, &
     622          406 :                                                             tau1_r, tau1_r_xc, tau_r, tau_r_xc, &
     623          406 :                                                             vxc_rho, vxc_tau
     624              :       TYPE(pw_r3d_rs_type), POINTER                      :: rho_nlcc, weights
     625          406 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set, rho1_atom_set
     626              : 
     627          406 :       CALL timeset(routineN, handle)
     628              : 
     629          406 :       CPASSERT(ASSOCIATED(rho_struct))
     630          406 :       IF (order > 0) THEN
     631          164 :          CPASSERT(ASSOCIATED(rho1_struct))
     632              :       END IF
     633              : 
     634              :       ! we always get true exc (not integration weighted)
     635              :       CALL get_qs_env(qs_env, &
     636              :                       dft_control=dft_control, &
     637              :                       pw_env=pw_env, &
     638              :                       cell=cell, &
     639              :                       particle_set=particle_set, &
     640              :                       rho_nlcc=rho_nlcc, &
     641          406 :                       rho_nlcc_g=rho_nlcc_g)
     642              : 
     643          406 :       nspins = dft_control%nspins
     644          406 :       CPASSERT(dft_control%sic_method_id == sic_none)
     645              : 
     646          406 :       CALL section_vals_val_get(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", i_val=myfun)
     647          406 :       native_skala_grid = xc_section_uses_native_skala_grid(xc_section)
     648              : 
     649          406 :       CALL pw_zero(exc)
     650              : 
     651          406 :       IF (myfun /= xc_none) THEN
     652          388 :          NULLIFY (weights)
     653              : 
     654          388 :          NULLIFY (rho_r, rho_g, tau_r)
     655              :          CALL qs_rho_get(rho_struct, rho_r=rho_r, rho_g=rho_g, tau_r=tau_r, &
     656          388 :                          rho_g_valid=rho_g_valid, tau_r_valid=tau_valid)
     657              : 
     658          388 :          CALL pw_env_get(pw_env, xc_pw_pool=xc_pw_pool, auxbas_pw_pool=auxbas_pw_pool)
     659          388 :          uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
     660              : 
     661              :          ! add the nlcc densities
     662          388 :          IF (ASSOCIATED(rho_nlcc) .AND. order <= 1) THEN
     663            8 :             factor = 1.0_dp
     664           16 :             DO ispin = 1, nspins
     665            8 :                CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     666           16 :                CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     667              :             END DO
     668              :          END IF
     669              : 
     670          388 :          NULLIFY (rho_r_xc, rho_g_xc, tau_r_xc)
     671          388 :          IF (uf_grid .AND. order <= 1) THEN
     672           36 :             IF (rho_g_valid) THEN
     673           36 :                CALL create_density_on_pool(xc_pw_pool, rho_g, rho_r_xc, rho_g_xc)
     674              :             ELSE
     675            0 :                CALL create_density_on_pool_from_r(auxbas_pw_pool, xc_pw_pool, rho_r, rho_r_xc, rho_g_xc)
     676              :             END IF
     677           36 :             IF (tau_valid) THEN
     678            8 :                CALL create_density_on_pool_from_r(auxbas_pw_pool, xc_pw_pool, tau_r, tau_r_xc)
     679              :             END IF
     680              :          ELSE
     681          352 :             rho_r_xc => rho_r
     682          352 :             rho_g_xc => rho_g
     683          352 :             tau_r_xc => tau_r
     684              :          END IF
     685              : 
     686          388 :          NULLIFY (rho1_r_xc, rho1_g_xc, tau1_r_xc)
     687          388 :          IF (order >= 1) THEN
     688              :             CALL qs_rho_get(rho1_struct, rho_r=rho1_r, rho_g=rho1_g, tau_r=tau1_r, &
     689          156 :                             rho_g_valid=rho1_g_valid, tau_r_valid=tau1_valid)
     690          156 :             IF (uf_grid) THEN
     691           16 :                IF (rho1_g_valid) THEN
     692           16 :                   CALL create_density_on_pool(xc_pw_pool, rho1_g, rho1_r_xc, rho1_g_xc)
     693              :                ELSE
     694            0 :                   CALL create_density_on_pool_from_r(auxbas_pw_pool, xc_pw_pool, rho1_r, rho1_r_xc, rho1_g_xc)
     695              :                END IF
     696           16 :                IF (tau1_valid) THEN
     697            0 :                   CALL create_density_on_pool_from_r(auxbas_pw_pool, xc_pw_pool, tau1_r, tau1_r_xc)
     698              :                END IF
     699              :             ELSE
     700          140 :                rho1_r_xc => rho1_r
     701          140 :                rho1_g_xc => rho1_g
     702          140 :                tau1_r_xc => tau1_r
     703              :             END IF
     704              :          END IF
     705              : 
     706          388 :          NULLIFY (vxc_rho, vxc_tau)
     707          232 :          SELECT CASE (order)
     708              :          CASE (0)
     709          232 :             IF (native_skala_grid) THEN
     710              :                CALL skala_gpw_weight_derivative(exc, rho_r, rho_g, tau_r, xc_section, weights, &
     711            0 :                                                 xc_pw_pool, particle_set, cell)
     712              :             ELSE
     713          232 :                CALL xc_exc_pw_create(rho_r_xc, rho_g_xc, tau_r_xc, xc_section, weights, xc_pw_pool, exc)
     714              :             END IF
     715              :          CASE (1)
     716           94 :             IF (native_skala_grid) THEN
     717              :                CALL cp_abort(__LOCATION__, &
     718            0 :                              "Native SKALA GAPW accurate-XCINT response forces are not implemented.")
     719              :             ELSE
     720              :                CALL xc_vxc_pw_create(vxc_rho, vxc_tau, exc=excint, &
     721              :                                      rho_r=rho_r_xc, rho_g=rho_g_xc, tau=tau_r_xc, &
     722              :                                      xc_section=xc_section, weights=weights, pw_pool=xc_pw_pool, &
     723           94 :                                      compute_virial=.FALSE., virial_xc=vdum)
     724              :             END IF
     725              :          CASE (2)
     726           62 :             IF (native_skala_grid) THEN
     727              :                CALL cp_abort(__LOCATION__, &
     728            0 :                              "Native SKALA GAPW accurate-XCINT response forces are not implemented.")
     729              :             ELSE
     730              :                CALL qs_fxc_create(qs_env, rho_struct, rho1_struct, rho0_atom_set, xc_section, .FALSE., &
     731              :                                   vxc_rho, vxc_tau, rho1_atom_set, is_triplet=triplet, &
     732           62 :                                   no_weights=.TRUE., uf_grid_results=uf_grid)
     733              :             END IF
     734              :          CASE DEFAULT
     735          388 :             CPABORT("Derivative order not available in xc_density")
     736              :          END SELECT
     737              : 
     738          388 :          IF (order >= 1) THEN
     739          156 :             CALL pw_zero(exc)
     740          156 :             IF (ASSOCIATED(vxc_rho)) THEN
     741          314 :                DO ispin = 1, nspins
     742          158 :                   CALL pw_multiply_with(vxc_rho(ispin), rho1_r_xc(ispin))
     743          158 :                   CALL pw_axpy(vxc_rho(ispin), exc, 1.0_dp)
     744          314 :                   CALL vxc_rho(ispin)%release()
     745              :                END DO
     746          156 :                DEALLOCATE (vxc_rho)
     747              :             END IF
     748          156 :             IF (ASSOCIATED(vxc_tau)) THEN
     749            0 :                DO ispin = 1, nspins
     750            0 :                   CALL pw_multiply_with(vxc_tau(ispin), tau1_r_xc(ispin))
     751            0 :                   CALL pw_axpy(vxc_tau(ispin), exc, 1.0_dp)
     752            0 :                   CALL vxc_tau(ispin)%release()
     753              :                END DO
     754            0 :                DEALLOCATE (vxc_tau)
     755              :             END IF
     756              :          END IF
     757              : 
     758          388 :          IF (order == 2) THEN
     759           62 :             CALL pw_scale(exc, 0.5_dp)
     760              :          END IF
     761              : 
     762          388 :          IF (uf_grid .AND. order <= 1) THEN
     763           36 :             CALL give_back_density_on_pool(xc_pw_pool, rho_r_xc, rho_g_xc)
     764           36 :             IF (tau_valid) THEN
     765            8 :                CALL give_back_density_on_pool(xc_pw_pool, tau_r_xc)
     766              :             END IF
     767              :          END IF
     768              : 
     769          388 :          IF (uf_grid .AND. order >= 1) THEN
     770           16 :             CALL give_back_density_on_pool(xc_pw_pool, rho1_r_xc, rho1_g_xc)
     771           16 :             IF (tau1_valid) THEN
     772            0 :                CALL give_back_density_on_pool(xc_pw_pool, tau1_r_xc)
     773              :             END IF
     774              :          END IF
     775              : 
     776              :          ! romove the nlcc densities
     777          388 :          IF (ASSOCIATED(rho_nlcc) .AND. order <= 1) THEN
     778            8 :             factor = -1.0_dp
     779           16 :             DO ispin = 1, nspins
     780            8 :                CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     781           16 :                CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     782              :             END DO
     783              :          END IF
     784              : 
     785              :       END IF
     786              : 
     787          406 :       CALL timestop(handle)
     788              : 
     789          406 :    END SUBROUTINE xc_density
     790              : ! **************************************************************************************************
     791              : !> \brief transfers a g-space density to a given PW pool and creates its r-space representation
     792              : !> \param pw_pool ...
     793              : !> \param rho_g_in ...
     794              : !> \param rho_r_out ...
     795              : !> \param rho_g_out ...
     796              : ! **************************************************************************************************
     797           52 :    SUBROUTINE create_density_on_pool(pw_pool, rho_g_in, rho_r_out, rho_g_out)
     798              :       TYPE(pw_pool_type), POINTER                        :: pw_pool
     799              :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g_in
     800              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r_out
     801              :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g_out
     802              : 
     803              :       INTEGER                                            :: ispin, nspins
     804              : 
     805           52 :       CPASSERT(ASSOCIATED(pw_pool))
     806           52 :       CPASSERT(ASSOCIATED(rho_g_in))
     807              : 
     808           52 :       nspins = SIZE(rho_g_in)
     809          364 :       ALLOCATE (rho_r_out(nspins), rho_g_out(nspins))
     810          104 :       DO ispin = 1, nspins
     811           52 :          CALL pw_pool%create_pw(rho_g_out(ispin))
     812           52 :          CALL pw_pool%create_pw(rho_r_out(ispin))
     813           52 :          CALL pw_transfer(rho_g_in(ispin), rho_g_out(ispin))
     814          104 :          CALL pw_transfer(rho_g_out(ispin), rho_r_out(ispin))
     815              :       END DO
     816              : 
     817           52 :    END SUBROUTINE create_density_on_pool
     818              : 
     819              : ! **************************************************************************************************
     820              : !> \brief transfers an r-space density to a given PW pool and creates its g-space representation
     821              : !> \param source_pw_pool ...
     822              : !> \param target_pw_pool ...
     823              : !> \param rho_r_in ...
     824              : !> \param rho_r_out ...
     825              : !> \param rho_g_out ...
     826              : ! **************************************************************************************************
     827            8 :    SUBROUTINE create_density_on_pool_from_r(source_pw_pool, target_pw_pool, rho_r_in, rho_r_out, rho_g_out)
     828              :       TYPE(pw_pool_type), POINTER                        :: source_pw_pool, target_pw_pool
     829              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r_in, rho_r_out
     830              :       TYPE(pw_c1d_gs_type), DIMENSION(:), OPTIONAL, &
     831              :          POINTER                                         :: rho_g_out
     832              : 
     833              :       INTEGER                                            :: ispin, nspins
     834              :       TYPE(pw_c1d_gs_type)                               :: rho_g_aux, rho_g_in
     835              : 
     836            0 :       CPASSERT(ASSOCIATED(source_pw_pool))
     837            8 :       CPASSERT(ASSOCIATED(target_pw_pool))
     838            8 :       CPASSERT(ASSOCIATED(rho_r_in))
     839              : 
     840            8 :       nspins = SIZE(rho_r_in)
     841            8 :       IF (PRESENT(rho_g_out)) THEN
     842            0 :          ALLOCATE (rho_r_out(nspins), rho_g_out(nspins))
     843            0 :          DO ispin = 1, nspins
     844            0 :             CALL source_pw_pool%create_pw(rho_g_in)
     845            0 :             CALL target_pw_pool%create_pw(rho_g_out(ispin))
     846            0 :             CALL target_pw_pool%create_pw(rho_r_out(ispin))
     847            0 :             CALL pw_transfer(rho_r_in(ispin), rho_g_in)
     848            0 :             CALL pw_transfer(rho_g_in, rho_g_out(ispin))
     849            0 :             CALL pw_transfer(rho_g_out(ispin), rho_r_out(ispin))
     850            0 :             CALL source_pw_pool%give_back_pw(rho_g_in)
     851              :          END DO
     852              :       ELSE
     853           32 :          ALLOCATE (rho_r_out(nspins))
     854           16 :          DO ispin = 1, nspins
     855            8 :             CALL source_pw_pool%create_pw(rho_g_in)
     856            8 :             CALL target_pw_pool%create_pw(rho_g_aux)
     857            8 :             CALL target_pw_pool%create_pw(rho_r_out(ispin))
     858            8 :             CALL pw_transfer(rho_r_in(ispin), rho_g_in)
     859            8 :             CALL pw_transfer(rho_g_in, rho_g_aux)
     860            8 :             CALL pw_transfer(rho_g_aux, rho_r_out(ispin))
     861            8 :             CALL source_pw_pool%give_back_pw(rho_g_in)
     862           16 :             CALL source_pw_pool%give_back_pw(rho_g_aux)
     863              :          END DO
     864              :       END IF
     865              : 
     866            8 :    END SUBROUTINE create_density_on_pool_from_r
     867              : 
     868              : ! **************************************************************************************************
     869              : !> \brief returns temporary density arrays to the given PW pool
     870              : !> \param pw_pool ...
     871              : !> \param rho_r ...
     872              : !> \param rho_g ...
     873              : ! **************************************************************************************************
     874           60 :    SUBROUTINE give_back_density_on_pool(pw_pool, rho_r, rho_g)
     875              :       TYPE(pw_pool_type), POINTER                        :: pw_pool
     876              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r
     877              :       TYPE(pw_c1d_gs_type), DIMENSION(:), OPTIONAL, &
     878              :          POINTER                                         :: rho_g
     879              : 
     880              :       INTEGER                                            :: ispin
     881              : 
     882           60 :       CPASSERT(ASSOCIATED(pw_pool))
     883              : 
     884           60 :       IF (ASSOCIATED(rho_r)) THEN
     885          120 :          DO ispin = 1, SIZE(rho_r)
     886          120 :             CALL pw_pool%give_back_pw(rho_r(ispin))
     887              :          END DO
     888           60 :          DEALLOCATE (rho_r)
     889              :       END IF
     890           60 :       IF (PRESENT(rho_g)) THEN
     891           52 :          IF (ASSOCIATED(rho_g)) THEN
     892          104 :             DO ispin = 1, SIZE(rho_g)
     893          104 :                CALL pw_pool%give_back_pw(rho_g(ispin))
     894              :             END DO
     895           52 :             DEALLOCATE (rho_g)
     896              :          END IF
     897              :       END IF
     898              : 
     899           60 :    END SUBROUTINE give_back_density_on_pool
     900              : 
     901              : END MODULE accint_weights_forces
        

Generated by: LCOV version 2.0-1