LCOV - code coverage report
Current view: top level - src - kg_correction.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:24d69ee) Lines: 87.9 % 389 342
Test Date: 2026-09-03 07:32:15 Functions: 100.0 % 6 6

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Routines for a Kim-Gordon-like partitioning into molecular subunits
      10              : !> \par History
      11              : !>       2012.06 created [Martin Haeufel]
      12              : !> \author Martin Haeufel and Florian Schiffmann
      13              : ! **************************************************************************************************
      14              : MODULE kg_correction
      15              :    USE atomic_kind_types,               ONLY: atomic_kind_type
      16              :    USE cp_control_types,                ONLY: dft_control_type
      17              :    USE cp_dbcsr_api,                    ONLY: dbcsr_add,&
      18              :                                               dbcsr_p_type
      19              :    USE cp_dbcsr_contrib,                ONLY: dbcsr_dot
      20              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      21              :                                               cp_logger_get_default_unit_nr,&
      22              :                                               cp_logger_type
      23              :    USE input_constants,                 ONLY: kg_tnadd_atomic,&
      24              :                                               kg_tnadd_embed,&
      25              :                                               kg_tnadd_embed_ri,&
      26              :                                               kg_tnadd_none
      27              :    USE input_section_types,             ONLY: section_vals_get,&
      28              :                                               section_vals_get_subs_vals,&
      29              :                                               section_vals_type
      30              :    USE kg_environment_types,            ONLY: kg_environment_type
      31              :    USE kinds,                           ONLY: dp
      32              :    USE lri_environment_methods,         ONLY: calculate_lri_densities,&
      33              :                                               lri_kg_rho_update
      34              :    USE lri_environment_types,           ONLY: lri_density_type,&
      35              :                                               lri_environment_type,&
      36              :                                               lri_kind_type
      37              :    USE lri_forces,                      ONLY: calculate_lri_forces
      38              :    USE lri_ks_methods,                  ONLY: calculate_lri_ks_matrix
      39              :    USE message_passing,                 ONLY: mp_para_env_type
      40              :    USE pw_env_types,                    ONLY: pw_env_get,&
      41              :                                               pw_env_type
      42              :    USE pw_methods,                      ONLY: pw_integral_ab,&
      43              :                                               pw_scale
      44              :    USE pw_pool_types,                   ONLY: pw_pool_type
      45              :    USE pw_types,                        ONLY: pw_r3d_rs_type
      46              :    USE qs_environment_types,            ONLY: get_qs_env,&
      47              :                                               qs_environment_type
      48              :    USE qs_fxc,                          ONLY: qs_fxc_create
      49              :    USE qs_integrate_potential,          ONLY: integrate_v_rspace,&
      50              :                                               integrate_v_rspace_one_center
      51              :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      52              :    USE qs_rho_atom_types,               ONLY: rho_atom_type
      53              :    USE qs_rho_methods,                  ONLY: qs_rho_rebuild,&
      54              :                                               qs_rho_update_rho
      55              :    USE qs_rho_types,                    ONLY: qs_rho_create,&
      56              :                                               qs_rho_get,&
      57              :                                               qs_rho_release,&
      58              :                                               qs_rho_set,&
      59              :                                               qs_rho_type,&
      60              :                                               qs_rho_unset_rho_ao
      61              :    USE qs_vxc,                          ONLY: qs_vxc_create
      62              :    USE virial_types,                    ONLY: virial_type
      63              :    USE xc,                              ONLY: xc_uses_kinetic_energy_density
      64              : #include "./base/base_uses.f90"
      65              : 
      66              :    IMPLICIT NONE
      67              : 
      68              :    PRIVATE
      69              : 
      70              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'kg_correction'
      71              : 
      72              :    PUBLIC :: kg_ekin_subset
      73              : 
      74              : CONTAINS
      75              : 
      76              : ! **************************************************************************************************
      77              : !> \brief Calculates the subsystem Hohenberg-Kohn kinetic energy and the forces
      78              : !> \param qs_env ...
      79              : !> \param ks_matrix ...
      80              : !> \param ekin_mol ...
      81              : !> \param calc_force ...
      82              : !> \param do_kernel Contribution of kinetic energy functional to kernel in response calculation
      83              : !> \param pmat_ext Response density used to fold 2nd deriv or to integrate kinetic energy functional
      84              : !> \par History
      85              : !>       2012.06 created [Martin Haeufel]
      86              : !>       2014.01 added atomic potential option [JGH]
      87              : !>       2020.01 Added KG contribution to linear response [fbelle]
      88              : !> \author Martin Haeufel and Florian Schiffmann
      89              : ! **************************************************************************************************
      90          970 :    SUBROUTINE kg_ekin_subset(qs_env, ks_matrix, ekin_mol, calc_force, do_kernel, pmat_ext)
      91              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      92              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ks_matrix
      93              :       REAL(KIND=dp), INTENT(out)                         :: ekin_mol
      94              :       LOGICAL, INTENT(IN)                                :: calc_force, do_kernel
      95              :       TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
      96              :          POINTER                                         :: pmat_ext
      97              : 
      98              :       LOGICAL                                            :: lrigpw
      99              :       TYPE(dft_control_type), POINTER                    :: dft_control
     100              :       TYPE(kg_environment_type), POINTER                 :: kg_env
     101              : 
     102          970 :       CALL get_qs_env(qs_env, kg_env=kg_env, dft_control=dft_control)
     103          970 :       lrigpw = dft_control%qs_control%lrigpw
     104              :       IF ((kg_env%tnadd_method == kg_tnadd_embed_ri .OR. &
     105          970 :            (kg_env%tnadd_method == kg_tnadd_embed .AND. lrigpw)) .AND. &
     106              :           kg_uses_kinetic_energy_density(kg_env, dft_control%lsd)) THEN
     107            0 :          CPABORT("KG LRI/RI embedding with meta-kinetic energy functionals not implemented")
     108              :       END IF
     109          970 :       IF (kg_env%tnadd_method == kg_tnadd_embed) THEN
     110          712 :          IF (lrigpw) THEN
     111           20 :             CALL kg_ekin_embed_lri(qs_env, kg_env, ks_matrix, ekin_mol, calc_force)
     112              :          ELSE
     113              :             CALL kg_ekin_embed(qs_env, kg_env, ks_matrix, ekin_mol, calc_force, &
     114          692 :                                do_kernel, pmat_ext)
     115              :          END IF
     116          258 :       ELSE IF (kg_env%tnadd_method == kg_tnadd_embed_ri) THEN
     117              :          CALL kg_ekin_ri_embed(qs_env, kg_env, ks_matrix, ekin_mol, calc_force, &
     118           60 :                                do_kernel, pmat_ext)
     119          198 :       ELSE IF (kg_env%tnadd_method == kg_tnadd_atomic) THEN
     120          160 :          CALL kg_ekin_atomic(qs_env, ks_matrix, ekin_mol)
     121           38 :       ELSE IF (kg_env%tnadd_method == kg_tnadd_none) THEN
     122           38 :          ekin_mol = 0.0_dp
     123              :       ELSE
     124            0 :          CPABORT("Unknown KG embedding method")
     125              :       END IF
     126              : 
     127          970 :    END SUBROUTINE kg_ekin_subset
     128              : 
     129              : ! **************************************************************************************************
     130              : !> \brief Returns whether the KG XC section needs the kinetic energy density.
     131              : !> \param kg_env Kim-Gordon environment
     132              : !> \param lsd spin-polarized calculation flag
     133              : !> \return ...
     134              : ! **************************************************************************************************
     135          160 :    FUNCTION kg_uses_kinetic_energy_density(kg_env, lsd) RESULT(res)
     136              :       TYPE(kg_environment_type), POINTER                 :: kg_env
     137              :       LOGICAL, INTENT(IN)                                :: lsd
     138              :       LOGICAL                                            :: res
     139              : 
     140              :       LOGICAL                                            :: explicit
     141              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     142              : 
     143           80 :       res = .FALSE.
     144           80 :       IF (.NOT. ASSOCIATED(kg_env%xc_section_kg)) RETURN
     145              : 
     146           80 :       xc_fun_section => section_vals_get_subs_vals(kg_env%xc_section_kg, "XC_FUNCTIONAL")
     147           80 :       CALL section_vals_get(xc_fun_section, explicit=explicit)
     148           80 :       IF (explicit) res = xc_uses_kinetic_energy_density(xc_fun_section, lsd)
     149              : 
     150              :    END FUNCTION kg_uses_kinetic_energy_density
     151              : 
     152              : ! **************************************************************************************************
     153              : !> \brief ...
     154              : !> \param qs_env ...
     155              : !> \param kg_env ...
     156              : !> \param ks_matrix ...
     157              : !> \param ekin_mol ...
     158              : !> \param calc_force ...
     159              : !> \param do_kernel Contribution of kinetic energy functional to kernel in response calculation
     160              : !> \param pmat_ext Response density used to fold 2nd deriv or to integrate kinetic energy functional
     161              : ! **************************************************************************************************
     162         1384 :    SUBROUTINE kg_ekin_embed(qs_env, kg_env, ks_matrix, ekin_mol, calc_force, do_kernel, pmat_ext)
     163              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     164              :       TYPE(kg_environment_type), POINTER                 :: kg_env
     165              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ks_matrix
     166              :       REAL(KIND=dp), INTENT(out)                         :: ekin_mol
     167              :       LOGICAL, INTENT(IN)                                :: calc_force, do_kernel
     168              :       TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
     169              :          POINTER                                         :: pmat_ext
     170              : 
     171              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'kg_ekin_embed'
     172              : 
     173              :       CHARACTER(LEN=10)                                  :: basis_type
     174              :       INTEGER                                            :: handle, iounit, ispin, isub, nspins
     175              :       LOGICAL                                            :: gapw, gapw_xc, use_gapw_soft, use_virial
     176              :       REAL(KIND=dp)                                      :: alpha, ekin_imol
     177              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: xcvirial
     178              :       TYPE(cp_logger_type), POINTER                      :: logger
     179          692 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: density_matrix
     180              :       TYPE(dft_control_type), POINTER                    :: dft_control
     181              :       TYPE(pw_env_type), POINTER                         :: pw_env
     182              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     183          692 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho1_r, rho_r, tau1_r, vxc_rho, vxc_tau
     184              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     185              :       TYPE(qs_rho_type), POINTER                         :: old_rho, rho1, rho1_use, rho1_xc, &
     186              :                                                             rho_struct, rho_use, rho_xc
     187          692 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set, rho1_atom_set
     188              :       TYPE(section_vals_type), POINTER                   :: xc_section
     189              :       TYPE(virial_type), POINTER                         :: virial
     190              : 
     191          692 :       CALL timeset(routineN, handle)
     192              : 
     193          692 :       logger => cp_get_default_logger()
     194          692 :       iounit = cp_logger_get_default_unit_nr(logger)
     195              : 
     196          692 :       NULLIFY (ks_env, dft_control, old_rho, pw_env, rho1_use, rho1_xc, rho_struct, &
     197          692 :                rho_use, rho_xc, virial, vxc_rho, vxc_tau)
     198          692 :       NULLIFY (rho0_atom_set, rho1_atom_set)
     199              : 
     200              :       CALL get_qs_env(qs_env, &
     201              :                       ks_env=ks_env, &
     202              :                       rho=old_rho, &
     203              :                       dft_control=dft_control, &
     204              :                       virial=virial, &
     205          692 :                       pw_env=pw_env)
     206          692 :       nspins = dft_control%nspins
     207          692 :       gapw = dft_control%qs_control%gapw
     208          692 :       gapw_xc = dft_control%qs_control%gapw_xc
     209          692 :       use_gapw_soft = gapw .OR. gapw_xc
     210          692 :       IF (use_gapw_soft) THEN
     211           68 :          basis_type = "ORB_SOFT"
     212              :       ELSE
     213          624 :          basis_type = "ORB"
     214              :       END IF
     215          692 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     216          692 :       use_virial = use_virial .AND. calc_force
     217              : 
     218              :       ! Kernel potential in response calculation (no forces calculated at this point)
     219              :       ! requires spin-factor
     220              :       ! alpha = 2 closed-shell
     221              :       ! alpha = 1 open-shell
     222          692 :       alpha = 1.0_dp
     223          692 :       IF (do_kernel .AND. .NOT. calc_force .AND. nspins == 1) alpha = 2.0_dp
     224              : 
     225          692 :       NULLIFY (auxbas_pw_pool)
     226          692 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     227              : 
     228              :       ! get the density matrix
     229          692 :       CALL qs_rho_get(old_rho, rho_ao=density_matrix)
     230              :       ! allocate and initialize the density
     231          692 :       ALLOCATE (rho_struct)
     232          692 :       CALL qs_rho_create(rho_struct)
     233              :       ! set the density matrix to the blocked matrix
     234          692 :       CALL qs_rho_set(rho_struct, rho_ao=density_matrix) ! blocked_matrix
     235          692 :       CALL qs_rho_rebuild(rho_struct, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
     236          692 :       IF (gapw_xc) THEN
     237           16 :          ALLOCATE (rho_xc)
     238           16 :          CALL qs_rho_create(rho_xc)
     239           16 :          CALL qs_rho_rebuild(rho_xc, qs_env, rebuild_ao=.TRUE., rebuild_grids=.TRUE.)
     240              :       END IF
     241              :       ! full density kinetic energy term
     242              :       IF (gapw_xc) THEN
     243           16 :          CALL qs_rho_update_rho(rho_struct, qs_env, rho_xc_external=rho_xc)
     244           16 :          rho_use => rho_xc
     245              :       ELSE
     246          676 :          CALL qs_rho_update_rho(rho_struct, qs_env)
     247          676 :          rho_use => rho_struct
     248              :       END IF
     249              :       ! get blocked density that has been put on grid
     250          692 :       CALL qs_rho_get(rho_use, rho_r=rho_r)
     251              : 
     252              :       ! If external density associated then it is needed either for
     253              :       ! 1) folding of second derivative while partially integrating, or
     254              :       ! 2) integration of response forces
     255          692 :       NULLIFY (rho1)
     256          692 :       IF (PRESENT(pmat_ext)) THEN
     257           58 :          ALLOCATE (rho1)
     258           58 :          CALL qs_rho_create(rho1)
     259           58 :          CALL qs_rho_set(rho1, rho_ao=pmat_ext)
     260           58 :          CALL qs_rho_rebuild(rho1, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
     261           58 :          IF (gapw_xc) THEN
     262            0 :             ALLOCATE (rho1_xc)
     263            0 :             CALL qs_rho_create(rho1_xc)
     264            0 :             CALL qs_rho_rebuild(rho1_xc, qs_env, rebuild_ao=.TRUE., rebuild_grids=.TRUE.)
     265            0 :             CALL qs_rho_update_rho(rho1, qs_env, rho_xc_external=rho1_xc)
     266            0 :             rho1_use => rho1_xc
     267              :          ELSE
     268           58 :             CALL qs_rho_update_rho(rho1, qs_env)
     269           58 :             rho1_use => rho1
     270              :          END IF
     271              :       END IF
     272              : 
     273              :       ! XC-section pointing to kinetic energy functional in KG environment
     274              :       NULLIFY (xc_section)
     275          692 :       xc_section => kg_env%xc_section_kg
     276              : 
     277          692 :       ekin_imol = 0.0_dp
     278              : 
     279              :       ! calculate xc potential or kernel
     280          692 :       IF (do_kernel) THEN
     281              :          ! derivation wrt to rho_struct and evaluation at rho_struct
     282          142 :          IF (use_virial) virial%pv_xc = 0.0_dp
     283              :          CALL qs_fxc_create(qs_env, rho_use, rho1_use, rho0_atom_set, &
     284              :                             xc_section, .FALSE., &
     285              :                             vxc_rho, vxc_tau, rho1_atom_set, &
     286           46 :                             compute_virial=use_virial, virial_xc=virial%pv_xc)
     287              :       ELSE
     288              :          CALL qs_vxc_create(ks_env=ks_env, &
     289              :                             rho_struct=rho_use, &
     290              :                             xc_section=xc_section, &
     291              :                             vxc_rho=vxc_rho, &
     292              :                             vxc_tau=vxc_tau, &
     293          646 :                             exc=ekin_imol)
     294              :       END IF
     295              : 
     296              :       ! Integrate xc-potential with external density for outer response forces
     297          692 :       IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
     298           12 :          CALL qs_rho_get(rho1, rho_ao=density_matrix)
     299           12 :          CALL qs_rho_get(rho1_use, rho_r=rho1_r, tau_r=tau1_r)
     300              :          ! Direct volume term of virial
     301              :          ! xc-potential is unscaled
     302           12 :          IF (use_virial) THEN
     303            8 :             ekin_imol = 0.0_dp
     304           16 :             DO ispin = 1, nspins
     305            8 :                ekin_imol = ekin_imol + pw_integral_ab(rho1_r(ispin), vxc_rho(ispin))
     306           16 :                IF (ASSOCIATED(vxc_tau)) THEN
     307            0 :                   ekin_imol = ekin_imol + pw_integral_ab(tau1_r(ispin), vxc_tau(ispin))
     308              :                END IF
     309              :             END DO
     310              :          END IF
     311              :       END IF
     312              : 
     313         1384 :       DO ispin = 1, nspins
     314         1384 :          CALL pw_scale(vxc_rho(ispin), alpha*vxc_rho(ispin)%pw_grid%dvol)
     315              :       END DO
     316              : 
     317         1384 :       DO ispin = 1, nspins
     318              :          CALL integrate_v_rspace(v_rspace=vxc_rho(ispin), &
     319              :                                  pmat=density_matrix(ispin), hmat=ks_matrix(ispin), &
     320          692 :                                  qs_env=qs_env, calculate_forces=calc_force, gapw=use_gapw_soft)
     321          692 :          CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
     322         1384 :          IF (ASSOCIATED(vxc_tau)) THEN
     323           34 :             CALL pw_scale(vxc_tau(ispin), alpha*vxc_tau(ispin)%pw_grid%dvol)
     324              :             CALL integrate_v_rspace(v_rspace=vxc_tau(ispin), &
     325              :                                     pmat=density_matrix(ispin), hmat=ks_matrix(ispin), &
     326              :                                     qs_env=qs_env, compute_tau=.TRUE., &
     327           34 :                                     calculate_forces=calc_force, gapw=use_gapw_soft)
     328           34 :             CALL auxbas_pw_pool%give_back_pw(vxc_tau(ispin))
     329              :          END IF
     330              :       END DO
     331          692 :       DEALLOCATE (vxc_rho)
     332          692 :       IF (ASSOCIATED(vxc_tau)) DEALLOCATE (vxc_tau)
     333          692 :       ekin_mol = -ekin_imol
     334          692 :       xcvirial(1:3, 1:3) = 0.0_dp
     335          692 :       IF (use_virial) THEN
     336          312 :          xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) - virial%pv_xc(1:3, 1:3)
     337              :       END IF
     338              : 
     339              :       ! loop over all subsets
     340         2200 :       DO isub = 1, kg_env%nsubsets
     341              :          ! calculate the densities for the given blocked density matrix
     342              :          ! pass the subset task_list
     343         1508 :          IF (gapw_xc) THEN
     344              :             CALL qs_rho_update_rho(rho_struct, qs_env, rho_xc_external=rho_xc, &
     345              :                                    task_list_external=kg_env%subset(isub)%task_list, &
     346           48 :                                    task_list_external_soft=kg_env%subset(isub)%task_list)
     347           48 :             rho_use => rho_xc
     348              :          ELSE
     349              :             CALL qs_rho_update_rho(rho_struct, qs_env, &
     350         1460 :                                    task_list_external=kg_env%subset(isub)%task_list)
     351         1460 :             rho_use => rho_struct
     352              :          END IF
     353              :          ! Same for external (response) density if present
     354         1508 :          IF (PRESENT(pmat_ext)) THEN
     355          116 :             IF (gapw_xc) THEN
     356              :                CALL qs_rho_update_rho(rho1, qs_env, rho_xc_external=rho1_xc, &
     357              :                                       task_list_external=kg_env%subset(isub)%task_list, &
     358            0 :                                       task_list_external_soft=kg_env%subset(isub)%task_list)
     359            0 :                rho1_use => rho1_xc
     360              :             ELSE
     361              :                CALL qs_rho_update_rho(rho1, qs_env, &
     362          116 :                                       task_list_external=kg_env%subset(isub)%task_list)
     363          116 :                rho1_use => rho1
     364              :             END IF
     365              :          END IF
     366              : 
     367         1508 :          ekin_imol = 0.0_dp
     368         1508 :          NULLIFY (vxc_rho, vxc_tau)
     369              : 
     370              :          ! calculate  Hohenberg-Kohn kinetic energy of the density
     371              :          ! corresponding to the remaining molecular block(s)
     372              :          ! info per block in rho_struct now
     373              : 
     374              :          ! calculate xc-potential or kernel
     375         1508 :          IF (do_kernel) THEN
     376          284 :             IF (use_virial) virial%pv_xc = 0.0_dp
     377              :             CALL qs_fxc_create(qs_env, rho_use, rho1_use, rho0_atom_set, &
     378              :                                xc_section, .FALSE., &
     379              :                                vxc_rho, vxc_tau, rho1_atom_set, &
     380           92 :                                compute_virial=use_virial, virial_xc=virial%pv_xc)
     381              :          ELSE
     382              :             CALL qs_vxc_create(ks_env=ks_env, &
     383              :                                rho_struct=rho_use, &
     384              :                                xc_section=xc_section, &
     385              :                                vxc_rho=vxc_rho, &
     386              :                                vxc_tau=vxc_tau, &
     387         1416 :                                exc=ekin_imol)
     388              :          END IF
     389              : 
     390              :          ! Integrate with response density for outer response forces
     391         1508 :          IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
     392           24 :             CALL qs_rho_get(rho1, rho_ao=density_matrix)
     393           24 :             CALL qs_rho_get(rho1_use, rho_r=rho1_r, tau_r=tau1_r)
     394              :             ! Direct volume term of virial
     395              :             ! xc-potential is unscaled
     396           24 :             IF (use_virial) THEN
     397           16 :                ekin_imol = 0.0_dp
     398           32 :                DO ispin = 1, nspins
     399           16 :                   ekin_imol = ekin_imol + pw_integral_ab(rho1_r(ispin), vxc_rho(ispin))
     400           32 :                   IF (ASSOCIATED(vxc_tau)) THEN
     401            0 :                      ekin_imol = ekin_imol + pw_integral_ab(tau1_r(ispin), vxc_tau(ispin))
     402              :                   END IF
     403              :                END DO
     404              :             END IF
     405              :          END IF
     406              : 
     407         3016 :          DO ispin = 1, nspins
     408         1508 :             CALL pw_scale(vxc_rho(ispin), -alpha*vxc_rho(ispin)%pw_grid%dvol)
     409              : 
     410              :             CALL integrate_v_rspace(v_rspace=vxc_rho(ispin), &
     411              :                                     pmat=density_matrix(ispin), &
     412              :                                     hmat=ks_matrix(ispin), &
     413              :                                     qs_env=qs_env, &
     414              :                                     calculate_forces=calc_force, &
     415              :                                     basis_type=basis_type, &
     416         1508 :                                     task_list_external=kg_env%subset(isub)%task_list)
     417              :             ! clean up vxc_rho
     418         1508 :             CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
     419         3016 :             IF (ASSOCIATED(vxc_tau)) THEN
     420          102 :                CALL pw_scale(vxc_tau(ispin), -alpha*vxc_tau(ispin)%pw_grid%dvol)
     421              :                CALL integrate_v_rspace(v_rspace=vxc_tau(ispin), &
     422              :                                        pmat=density_matrix(ispin), &
     423              :                                        hmat=ks_matrix(ispin), &
     424              :                                        qs_env=qs_env, &
     425              :                                        compute_tau=.TRUE., &
     426              :                                        calculate_forces=calc_force, &
     427              :                                        basis_type=basis_type, &
     428          102 :                                        task_list_external=kg_env%subset(isub)%task_list)
     429              :                ! clean up vxc_rho
     430          102 :                CALL auxbas_pw_pool%give_back_pw(vxc_tau(ispin))
     431              :             END IF
     432              :          END DO
     433         1508 :          DEALLOCATE (vxc_rho)
     434         1508 :          IF (ASSOCIATED(vxc_tau)) DEALLOCATE (vxc_tau)
     435              : 
     436         1508 :          ekin_mol = ekin_mol + ekin_imol
     437              : 
     438         2200 :          IF (use_virial) THEN
     439          728 :             xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) + virial%pv_xc(1:3, 1:3)
     440              :          END IF
     441              : 
     442              :       END DO
     443              : 
     444          692 :       IF (use_virial) THEN
     445          312 :          virial%pv_xc(1:3, 1:3) = xcvirial(1:3, 1:3)
     446              :       END IF
     447              : 
     448              :       ! clean up rho_struct
     449          692 :       CALL qs_rho_unset_rho_ao(rho_struct)
     450          692 :       CALL qs_rho_release(rho_struct)
     451          692 :       DEALLOCATE (rho_struct)
     452          692 :       IF (ASSOCIATED(rho_xc)) THEN
     453           16 :          CALL qs_rho_release(rho_xc)
     454           16 :          DEALLOCATE (rho_xc)
     455              :       END IF
     456          692 :       IF (PRESENT(pmat_ext)) THEN
     457           58 :          CALL qs_rho_unset_rho_ao(rho1)
     458           58 :          CALL qs_rho_release(rho1)
     459           58 :          DEALLOCATE (rho1)
     460           58 :          IF (ASSOCIATED(rho1_xc)) THEN
     461            0 :             CALL qs_rho_release(rho1_xc)
     462            0 :             DEALLOCATE (rho1_xc)
     463              :          END IF
     464              :       END IF
     465              : 
     466          692 :       CALL timestop(handle)
     467              : 
     468          692 :    END SUBROUTINE kg_ekin_embed
     469              : 
     470              : ! **************************************************************************************************
     471              : !> \brief ...
     472              : !> \param qs_env ...
     473              : !> \param kg_env ...
     474              : !> \param ks_matrix ...
     475              : !> \param ekin_mol ...
     476              : !> \param calc_force ...
     477              : ! **************************************************************************************************
     478           20 :    SUBROUTINE kg_ekin_embed_lri(qs_env, kg_env, ks_matrix, ekin_mol, calc_force)
     479              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     480              :       TYPE(kg_environment_type), POINTER                 :: kg_env
     481              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ks_matrix
     482              :       REAL(KIND=dp), INTENT(out)                         :: ekin_mol
     483              :       LOGICAL                                            :: calc_force
     484              : 
     485              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'kg_ekin_embed_lri'
     486              : 
     487              :       INTEGER                                            :: color, handle, iatom, ikind, imol, &
     488              :                                                             ispin, isub, natom, nkind, nspins
     489              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atomlist
     490              :       LOGICAL                                            :: use_virial
     491              :       REAL(KIND=dp)                                      :: ekin_imol
     492              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: xcvirial
     493           20 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     494           20 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: density_matrix, ksmat
     495           20 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: pmat
     496              :       TYPE(dft_control_type), POINTER                    :: dft_control
     497              :       TYPE(lri_density_type), POINTER                    :: lri_density
     498              :       TYPE(lri_environment_type), POINTER                :: lri_env
     499           20 :       TYPE(lri_kind_type), DIMENSION(:), POINTER         :: lri_v_int
     500              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     501              :       TYPE(pw_env_type), POINTER                         :: pw_env
     502              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     503           20 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: vxc_rho, vxc_tau
     504              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     505              :       TYPE(qs_rho_type), POINTER                         :: old_rho, rho_struct
     506              :       TYPE(virial_type), POINTER                         :: virial
     507              : 
     508           20 :       CALL timeset(routineN, handle)
     509              : 
     510           20 :       NULLIFY (vxc_rho, vxc_tau, old_rho, rho_struct, ks_env)
     511              : 
     512           20 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     513              : 
     514              :       ! get set of molecules, natom, dft_control, pw_env
     515              :       CALL get_qs_env(qs_env, &
     516              :                       ks_env=ks_env, &
     517              :                       rho=old_rho, &
     518              :                       natom=natom, &
     519              :                       dft_control=dft_control, &
     520              :                       virial=virial, &
     521              :                       para_env=para_env, &
     522           20 :                       pw_env=pw_env)
     523              : 
     524           20 :       nspins = dft_control%nspins
     525           20 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     526            0 :       use_virial = use_virial .AND. calc_force
     527              : 
     528           20 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     529              : 
     530              :       ! get the density matrix
     531           20 :       CALL qs_rho_get(old_rho, rho_ao=density_matrix)
     532              :       ! allocate and initialize the density
     533           20 :       ALLOCATE (rho_struct)
     534           20 :       CALL qs_rho_create(rho_struct)
     535              :       ! set the density matrix to the blocked matrix
     536           20 :       CALL qs_rho_set(rho_struct, rho_ao=density_matrix) ! blocked_matrix
     537           20 :       CALL qs_rho_rebuild(rho_struct, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
     538              : 
     539           20 :       CALL get_qs_env(qs_env, lri_env=lri_env, lri_density=lri_density, nkind=nkind)
     540           20 :       IF (lri_env%exact_1c_terms) THEN
     541            0 :          CPABORT(" KG with LRI and exact one-center terms not implemented")
     542              :       END IF
     543           60 :       ALLOCATE (atomlist(natom))
     544           40 :       DO ispin = 1, nspins
     545           20 :          lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
     546           80 :          DO ikind = 1, nkind
     547        14660 :             lri_v_int(ikind)%v_int = 0.0_dp
     548           60 :             IF (calc_force) THEN
     549           46 :                lri_v_int(ikind)%v_dadr = 0.0_dp
     550           46 :                lri_v_int(ikind)%v_dfdr = 0.0_dp
     551              :             END IF
     552              :          END DO
     553              :       END DO
     554              : 
     555              :       ! full density kinetic energy term
     556          120 :       atomlist = 1
     557           20 :       CALL lri_kg_rho_update(rho_struct, qs_env, lri_env, lri_density, atomlist)
     558              :       ekin_imol = 0.0_dp
     559              :       CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=kg_env%xc_section_kg, &
     560           20 :                          vxc_rho=vxc_rho, vxc_tau=vxc_tau, exc=ekin_imol)
     561           20 :       IF (ASSOCIATED(vxc_tau)) THEN
     562            0 :          CPABORT(" KG with meta-kinetic energy functionals not implemented")
     563              :       END IF
     564           40 :       DO ispin = 1, nspins
     565           20 :          CALL pw_scale(vxc_rho(ispin), vxc_rho(ispin)%pw_grid%dvol)
     566           20 :          lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
     567           20 :          CALL integrate_v_rspace_one_center(vxc_rho(ispin), qs_env, lri_v_int, calc_force, "LRI_AUX")
     568           40 :          CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
     569              :       END DO
     570           20 :       DEALLOCATE (vxc_rho)
     571           20 :       ekin_mol = -ekin_imol
     572           20 :       xcvirial(1:3, 1:3) = 0.0_dp
     573           20 :       IF (use_virial) xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) - virial%pv_xc(1:3, 1:3)
     574              : 
     575              :       ! loop over all subsets
     576           60 :       DO isub = 1, kg_env%nsubsets
     577           40 :          atomlist = 0
     578          240 :          DO iatom = 1, natom
     579          200 :             imol = kg_env%atom_to_molecule(iatom)
     580          200 :             color = kg_env%subset_of_mol(imol)
     581          240 :             IF (color == isub) atomlist(iatom) = 1
     582              :          END DO
     583           40 :          CALL lri_kg_rho_update(rho_struct, qs_env, lri_env, lri_density, atomlist)
     584              : 
     585              :          ekin_imol = 0.0_dp
     586              :          ! calc Hohenberg-Kohn kin. energy of the density corresp. to the remaining molecular block(s)
     587              :          CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=kg_env%xc_section_kg, &
     588           40 :                             vxc_rho=vxc_rho, vxc_tau=vxc_tau, exc=ekin_imol)
     589           40 :          ekin_mol = ekin_mol + ekin_imol
     590              : 
     591           80 :          DO ispin = 1, nspins
     592           40 :             CALL pw_scale(vxc_rho(ispin), -vxc_rho(ispin)%pw_grid%dvol)
     593           40 :             lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
     594              :             CALL integrate_v_rspace_one_center(vxc_rho(ispin), qs_env, &
     595              :                                                lri_v_int, calc_force, &
     596           40 :                                                "LRI_AUX", atomlist=atomlist)
     597              :             ! clean up vxc_rho
     598           80 :             CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
     599              :          END DO
     600           40 :          DEALLOCATE (vxc_rho)
     601              : 
     602          100 :          IF (use_virial) THEN
     603            0 :             xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) + virial%pv_xc(1:3, 1:3)
     604              :          END IF
     605              : 
     606              :       END DO
     607              : 
     608           20 :       IF (use_virial) THEN
     609            0 :          virial%pv_xc(1:3, 1:3) = xcvirial(1:3, 1:3)
     610              :       END IF
     611              : 
     612           20 :       CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
     613           40 :       ALLOCATE (ksmat(1))
     614           40 :       DO ispin = 1, nspins
     615           20 :          lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
     616           60 :          DO ikind = 1, nkind
     617        29300 :             CALL para_env%sum(lri_v_int(ikind)%v_int)
     618              :          END DO
     619           20 :          ksmat(1)%matrix => ks_matrix(ispin)%matrix
     620           40 :          CALL calculate_lri_ks_matrix(lri_env, lri_v_int, ksmat, atomic_kind_set)
     621              :       END DO
     622           20 :       IF (calc_force) THEN
     623            2 :          pmat(1:nspins, 1:1) => density_matrix(1:nspins)
     624            2 :          CALL calculate_lri_forces(lri_env, lri_density, qs_env, pmat, atomic_kind_set)
     625              :       END IF
     626           20 :       DEALLOCATE (atomlist, ksmat)
     627              : 
     628              :       ! clean up rho_struct
     629           20 :       CALL qs_rho_unset_rho_ao(rho_struct)
     630           20 :       CALL qs_rho_release(rho_struct)
     631           20 :       DEALLOCATE (rho_struct)
     632              : 
     633           20 :       CALL timestop(handle)
     634              : 
     635           60 :    END SUBROUTINE kg_ekin_embed_lri
     636              : 
     637              : ! **************************************************************************************************
     638              : !> \brief ...
     639              : !> \param qs_env ...
     640              : !> \param kg_env ...
     641              : !> \param ks_matrix ...
     642              : !> \param ekin_mol ...
     643              : !> \param calc_force ...
     644              : !> \param do_kernel Contribution of kinetic energy functional to kernel in response calculation
     645              : !> \param pmat_ext Response density used to fold 2nd deriv or to integrate kinetic energy functional
     646              : ! **************************************************************************************************
     647           60 :    SUBROUTINE kg_ekin_ri_embed(qs_env, kg_env, ks_matrix, ekin_mol, calc_force, &
     648              :                                do_kernel, pmat_ext)
     649              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     650              :       TYPE(kg_environment_type), POINTER                 :: kg_env
     651              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ks_matrix
     652              :       REAL(KIND=dp), INTENT(out)                         :: ekin_mol
     653              :       LOGICAL                                            :: calc_force, do_kernel
     654              :       TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
     655              :          POINTER                                         :: pmat_ext
     656              : 
     657              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'kg_ekin_ri_embed'
     658              : 
     659              :       INTEGER                                            :: color, handle, iatom, ikind, imol, &
     660              :                                                             iounit, ispin, isub, natom, nkind, &
     661              :                                                             nspins
     662           60 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atomlist
     663           60 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
     664              :       LOGICAL                                            :: use_virial
     665              :       REAL(KIND=dp)                                      :: alpha, ekin_imol
     666              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: xcvirial
     667           60 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     668              :       TYPE(cp_logger_type), POINTER                      :: logger
     669           60 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: density_matrix, ksmat
     670           60 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: pmat
     671              :       TYPE(dft_control_type), POINTER                    :: dft_control
     672              :       TYPE(lri_density_type), POINTER                    :: lri_density, lri_rho1
     673              :       TYPE(lri_environment_type), POINTER                :: lri_env, lri_env1
     674           60 :       TYPE(lri_kind_type), DIMENSION(:), POINTER         :: lri_v_int
     675              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     676              :       TYPE(pw_env_type), POINTER                         :: pw_env
     677              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     678           60 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: vxc_rho, vxc_tau
     679              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     680              :       TYPE(qs_rho_type), POINTER                         :: rho, rho1, rho_struct
     681           60 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set, rho1_atom_set
     682              :       TYPE(section_vals_type), POINTER                   :: xc_section
     683              :       TYPE(virial_type), POINTER                         :: virial
     684              : 
     685           60 :       CALL timeset(routineN, handle)
     686              : 
     687           60 :       logger => cp_get_default_logger()
     688           60 :       iounit = cp_logger_get_default_unit_nr(logger)
     689              : 
     690           60 :       NULLIFY (rho0_atom_set, rho1_atom_set)
     691              : 
     692              :       CALL get_qs_env(qs_env, &
     693              :                       ks_env=ks_env, &
     694              :                       rho=rho, &
     695              :                       natom=natom, &
     696              :                       nkind=nkind, &
     697              :                       dft_control=dft_control, &
     698              :                       virial=virial, &
     699              :                       para_env=para_env, &
     700           60 :                       pw_env=pw_env)
     701              : 
     702           60 :       nspins = dft_control%nspins
     703           96 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     704           40 :       use_virial = use_virial .AND. calc_force
     705              : 
     706              :       ! Kernel potential in response calculation (no forces calculated at this point)
     707              :       ! requires spin-factor
     708              :       ! alpha = 2 closed-shell
     709              :       ! alpha = 1 open-shell
     710           60 :       alpha = 1.0_dp
     711           60 :       IF (do_kernel .AND. .NOT. calc_force .AND. nspins == 1) alpha = 2.0_dp
     712              : 
     713           60 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     714              : 
     715              :       ! get the density matrix
     716           60 :       CALL qs_rho_get(rho, rho_ao=density_matrix)
     717              :       ! allocate and initialize the density
     718              :       NULLIFY (rho_struct)
     719           60 :       ALLOCATE (rho_struct)
     720           60 :       CALL qs_rho_create(rho_struct)
     721              :       ! set the density matrix to the blocked matrix
     722           60 :       CALL qs_rho_set(rho_struct, rho_ao=density_matrix)
     723           60 :       CALL qs_rho_rebuild(rho_struct, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
     724              : 
     725           60 :       CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
     726           60 :       ALLOCATE (cell_to_index(1, 1, 1))
     727           60 :       cell_to_index(1, 1, 1) = 1
     728           60 :       lri_env => kg_env%lri_env
     729           60 :       lri_density => kg_env%lri_density
     730              : 
     731           60 :       NULLIFY (pmat)
     732          300 :       ALLOCATE (pmat(nspins, 1))
     733          120 :       DO ispin = 1, nspins
     734          120 :          pmat(ispin, 1)%matrix => density_matrix(ispin)%matrix
     735              :       END DO
     736              :       CALL calculate_lri_densities(lri_env, lri_density, qs_env, pmat, cell_to_index, &
     737           60 :                                    rho_struct, atomic_kind_set, para_env, response_density=.FALSE.)
     738           60 :       kg_env%lri_density => lri_density
     739              : 
     740           60 :       DEALLOCATE (pmat)
     741              : 
     742           60 :       IF (PRESENT(pmat_ext)) THEN
     743              :          ! If external density associated then it is needed either for
     744              :          ! 1) folding of second derivative while partially integrating, or
     745              :          ! 2) integration of response forces
     746              :          NULLIFY (rho1)
     747            0 :          ALLOCATE (rho1)
     748            0 :          CALL qs_rho_create(rho1)
     749            0 :          CALL qs_rho_set(rho1, rho_ao=pmat_ext)
     750            0 :          CALL qs_rho_rebuild(rho1, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
     751              : 
     752            0 :          lri_env1 => kg_env%lri_env1
     753            0 :          lri_rho1 => kg_env%lri_rho1
     754              :          ! calculate external density as LRI-densities
     755            0 :          NULLIFY (pmat)
     756            0 :          ALLOCATE (pmat(nspins, 1))
     757            0 :          DO ispin = 1, nspins
     758            0 :             pmat(ispin, 1)%matrix => pmat_ext(ispin)%matrix
     759              :          END DO
     760              :          CALL calculate_lri_densities(lri_env1, lri_rho1, qs_env, pmat, cell_to_index, &
     761            0 :                                       rho1, atomic_kind_set, para_env, response_density=.FALSE.)
     762            0 :          kg_env%lri_rho1 => lri_rho1
     763            0 :          DEALLOCATE (pmat)
     764              : 
     765              :       END IF
     766              : 
     767              :       ! XC-section pointing to kinetic energy functional in KG environment
     768              :       NULLIFY (xc_section)
     769           60 :       xc_section => kg_env%xc_section_kg
     770              : 
     771              :       ! full density kinetic energy term
     772           60 :       ekin_imol = 0.0_dp
     773           60 :       NULLIFY (vxc_rho, vxc_tau)
     774              : 
     775              :       ! calculate xc potential or kernel
     776           60 :       IF (do_kernel) THEN
     777              :          ! kernel total
     778              :          ! derivation wrt to rho_struct and evaluation at rho_struct
     779              :          CALL qs_fxc_create(qs_env, rho_struct, rho1, rho0_atom_set, &
     780              :                             xc_section, .FALSE., &
     781            0 :                             vxc_rho, vxc_tau, rho1_atom_set)
     782              :       ELSE
     783              :          ! vxc total
     784              :          CALL qs_vxc_create(ks_env=ks_env, &
     785              :                             rho_struct=rho_struct, &
     786              :                             xc_section=xc_section, &
     787              :                             vxc_rho=vxc_rho, &
     788              :                             vxc_tau=vxc_tau, &
     789           60 :                             exc=ekin_imol)
     790              : 
     791              :       END IF
     792              : 
     793           60 :       IF (ASSOCIATED(vxc_tau)) THEN
     794            0 :          CPABORT(" KG with meta-kinetic energy functionals not implemented")
     795              :       END IF
     796              : 
     797          120 :       DO ispin = 1, nspins
     798           60 :          CALL pw_scale(vxc_rho(ispin), alpha*vxc_rho(ispin)%pw_grid%dvol)
     799              : 
     800           60 :          IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
     801              :             ! int w/ pmat_ext
     802            0 :             lri_v_int => lri_rho1%lri_coefs(ispin)%lri_kinds
     803              :          ELSE
     804              :             ! int w/ rho_ao
     805           60 :             lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
     806              :          END IF
     807           60 :          CALL integrate_v_rspace_one_center(vxc_rho(ispin), qs_env, lri_v_int, calc_force, "LRI_AUX")
     808          120 :          CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
     809              :       END DO
     810              : 
     811           60 :       DEALLOCATE (vxc_rho)
     812           60 :       ekin_mol = -ekin_imol
     813           60 :       xcvirial(1:3, 1:3) = 0.0_dp
     814          108 :       IF (use_virial) xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) - virial%pv_xc(1:3, 1:3)
     815              : 
     816              :       ! loop over all subsets
     817          180 :       ALLOCATE (atomlist(natom))
     818          180 :       DO isub = 1, kg_env%nsubsets
     819          120 :          atomlist = 0
     820          720 :          DO iatom = 1, natom
     821          600 :             imol = kg_env%atom_to_molecule(iatom)
     822          600 :             color = kg_env%subset_of_mol(imol)
     823          720 :             IF (color == isub) atomlist(iatom) = 1
     824              :          END DO
     825              :          ! update ground-state density
     826          120 :          CALL lri_kg_rho_update(rho_struct, qs_env, lri_env, lri_density, atomlist)
     827              : 
     828              :          ! Same for external (response) density if present
     829          120 :          IF (PRESENT(pmat_ext)) THEN
     830              :             ! update response density
     831            0 :             CALL lri_kg_rho_update(rho1, qs_env, lri_env1, lri_rho1, atomlist)
     832              :          END IF
     833              : 
     834          120 :          ekin_imol = 0.0_dp
     835              :          ! calc Hohenberg-Kohn kin. energy of the density corresp. to the remaining molecular block(s)
     836          120 :          NULLIFY (vxc_rho, vxc_tau)
     837              : 
     838              :          ! calculate xc potential or kernel
     839          120 :          IF (do_kernel) THEN
     840              :             ! subsys kernel
     841              :             CALL qs_fxc_create(qs_env, rho_struct, rho1, rho0_atom_set, &
     842              :                                xc_section, .FALSE., &
     843            0 :                                vxc_rho, vxc_tau, rho1_atom_set)
     844              :          ELSE
     845              : 
     846              :             ! subsys xc-potential
     847              :             CALL qs_vxc_create(ks_env=ks_env, &
     848              :                                rho_struct=rho_struct, &
     849              :                                xc_section=xc_section, &
     850              :                                vxc_rho=vxc_rho, &
     851              :                                vxc_tau=vxc_tau, &
     852          120 :                                exc=ekin_imol)
     853              :          END IF
     854          120 :          ekin_mol = ekin_mol + ekin_imol
     855              : 
     856          240 :          DO ispin = 1, nspins
     857          120 :             CALL pw_scale(vxc_rho(ispin), -alpha*vxc_rho(ispin)%pw_grid%dvol)
     858              : 
     859          120 :             IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
     860              :                ! int w/ pmat_ext
     861            0 :                lri_v_int => lri_rho1%lri_coefs(ispin)%lri_kinds
     862              :             ELSE
     863              :                ! int w/ rho_ao
     864          120 :                lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
     865              :             END IF
     866              : 
     867              :             CALL integrate_v_rspace_one_center(vxc_rho(ispin), qs_env, &
     868              :                                                lri_v_int, calc_force, &
     869          120 :                                                "LRI_AUX", atomlist=atomlist)
     870              :             ! clean up vxc_rho
     871          240 :             CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
     872              :          END DO
     873          120 :          DEALLOCATE (vxc_rho)
     874              : 
     875          180 :          IF (use_virial) THEN
     876          104 :             xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) + virial%pv_xc(1:3, 1:3)
     877              :          END IF
     878              : 
     879              :       END DO
     880              : 
     881           60 :       IF (use_virial) THEN
     882           52 :          virial%pv_xc(1:3, 1:3) = xcvirial(1:3, 1:3)
     883              :       END IF
     884              : 
     885          120 :       ALLOCATE (ksmat(1))
     886          120 :       DO ispin = 1, nspins
     887           60 :          ksmat(1)%matrix => ks_matrix(ispin)%matrix
     888          120 :          IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
     889              :             ! KS int with rho_ext"
     890            0 :             lri_v_int => lri_rho1%lri_coefs(ispin)%lri_kinds
     891            0 :             DO ikind = 1, nkind
     892            0 :                CALL para_env%sum(lri_v_int(ikind)%v_int)
     893              :             END DO
     894            0 :             CALL calculate_lri_ks_matrix(lri_env1, lri_v_int, ksmat, atomic_kind_set)
     895              :          ELSE
     896              :             ! KS int with rho_ao"
     897           60 :             lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
     898          180 :             DO ikind = 1, nkind
     899        87900 :                CALL para_env%sum(lri_v_int(ikind)%v_int)
     900              :             END DO
     901           60 :             CALL calculate_lri_ks_matrix(lri_env, lri_v_int, ksmat, atomic_kind_set)
     902              :          END IF
     903              : 
     904              :       END DO
     905           60 :       IF (calc_force) THEN
     906              : 
     907            6 :          NULLIFY (pmat)
     908           24 :          ALLOCATE (pmat(nspins, 1))
     909              : 
     910            6 :          IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
     911              :             ! Forces with rho_ext
     912            0 :             DO ispin = 1, nspins
     913            0 :                pmat(ispin, 1)%matrix => pmat_ext(ispin)%matrix
     914              :             END DO
     915            0 :             CALL calculate_lri_forces(lri_env1, lri_rho1, qs_env, pmat, atomic_kind_set)
     916              :          ELSE
     917              :             ! Forces with rho_ao
     918           12 :             DO ispin = 1, nspins
     919           12 :                pmat(ispin, 1)%matrix => density_matrix(ispin)%matrix
     920              :             END DO
     921            6 :             CALL calculate_lri_forces(lri_env, lri_density, qs_env, pmat, atomic_kind_set)
     922              :          END IF
     923              : 
     924            6 :          DEALLOCATE (pmat)
     925              : 
     926              :       END IF
     927           60 :       DEALLOCATE (atomlist, ksmat)
     928              : 
     929              :       ! clean up rho_struct
     930           60 :       CALL qs_rho_unset_rho_ao(rho_struct)
     931           60 :       CALL qs_rho_release(rho_struct)
     932           60 :       DEALLOCATE (rho_struct)
     933           60 :       IF (PRESENT(pmat_ext)) THEN
     934            0 :          CALL qs_rho_unset_rho_ao(rho1)
     935            0 :          CALL qs_rho_release(rho1)
     936            0 :          DEALLOCATE (rho1)
     937              :       END IF
     938           60 :       DEALLOCATE (cell_to_index)
     939              : 
     940           60 :       CALL timestop(handle)
     941              : 
     942          120 :    END SUBROUTINE kg_ekin_ri_embed
     943              : 
     944              : ! **************************************************************************************************
     945              : !> \brief ...
     946              : !> \param qs_env ...
     947              : !> \param ks_matrix ...
     948              : !> \param ekin_mol ...
     949              : ! **************************************************************************************************
     950          160 :    SUBROUTINE kg_ekin_atomic(qs_env, ks_matrix, ekin_mol)
     951              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     952              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ks_matrix
     953              :       REAL(KIND=dp), INTENT(out)                         :: ekin_mol
     954              : 
     955              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'kg_ekin_atomic'
     956              : 
     957              :       INTEGER                                            :: handle, ispin, nspins
     958          160 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: density_matrix, tnadd_matrix
     959              :       TYPE(kg_environment_type), POINTER                 :: kg_env
     960              :       TYPE(qs_rho_type), POINTER                         :: rho
     961              : 
     962          160 :       NULLIFY (rho, kg_env, density_matrix, tnadd_matrix)
     963              : 
     964          160 :       CALL timeset(routineN, handle)
     965          160 :       CALL get_qs_env(qs_env, kg_env=kg_env, rho=rho)
     966              : 
     967          160 :       nspins = SIZE(ks_matrix)
     968              :       ! get the density matrix
     969          160 :       CALL qs_rho_get(rho, rho_ao=density_matrix)
     970              :       ! get the tnadd matrix
     971          160 :       tnadd_matrix => kg_env%tnadd_mat
     972              : 
     973          160 :       ekin_mol = 0.0_dp
     974          320 :       DO ispin = 1, nspins
     975          160 :          CALL dbcsr_dot(tnadd_matrix(1)%matrix, density_matrix(ispin)%matrix, ekin_mol)
     976              :          CALL dbcsr_add(ks_matrix(ispin)%matrix, tnadd_matrix(1)%matrix, &
     977          320 :                         alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     978              :       END DO
     979              :       ! definition is inverted (see qs_ks_methods)
     980          160 :       ekin_mol = -ekin_mol
     981              : 
     982          160 :       CALL timestop(handle)
     983              : 
     984          160 :    END SUBROUTINE kg_ekin_atomic
     985              : 
     986              : END MODULE kg_correction
        

Generated by: LCOV version 2.0-1