LCOV - code coverage report
Current view: top level - src - qs_linres_kernel.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:123285f) Lines: 93.8 % 449 421
Test Date: 2026-11-04 00:58:17 Functions: 100.0 % 7 7

            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 linres kernel functions
      10              : !> \par History
      11              : !>      created from qs_linres_methods
      12              : !> \author JGH
      13              : ! **************************************************************************************************
      14              : MODULE qs_linres_kernel
      15              :    USE admm_types,                      ONLY: admm_type,&
      16              :                                               get_admm_env
      17              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      18              :                                               get_atomic_kind
      19              :    USE cp_control_types,                ONLY: dft_control_type
      20              :    USE cp_dbcsr_api,                    ONLY: dbcsr_add,&
      21              :                                               dbcsr_copy,&
      22              :                                               dbcsr_create,&
      23              :                                               dbcsr_deallocate_matrix,&
      24              :                                               dbcsr_p_type,&
      25              :                                               dbcsr_set
      26              :    USE cp_dbcsr_operations,             ONLY: cp_dbcsr_sm_fm_multiply,&
      27              :                                               dbcsr_allocate_matrix_set,&
      28              :                                               dbcsr_deallocate_matrix_set
      29              :    USE cp_fm_types,                     ONLY: cp_fm_get_info,&
      30              :                                               cp_fm_type
      31              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      32              :                                               cp_logger_type
      33              :    USE hartree_local_methods,           ONLY: Vh_1c_gg_integrals
      34              :    USE hfx_energy_potential,            ONLY: integrate_four_center
      35              :    USE hfx_ri,                          ONLY: hfx_ri_update_ks
      36              :    USE hfx_types,                       ONLY: hfx_type
      37              :    USE input_constants,                 ONLY: do_admm_aux_exch_func_none,&
      38              :                                               do_admm_basis_projection,&
      39              :                                               do_admm_exch_scaling_none,&
      40              :                                               do_admm_purify_none,&
      41              :                                               kg_tnadd_embed
      42              :    USE input_section_types,             ONLY: section_vals_get,&
      43              :                                               section_vals_get_subs_vals,&
      44              :                                               section_vals_type,&
      45              :                                               section_vals_val_get
      46              :    USE kg_correction,                   ONLY: kg_ekin_subset
      47              :    USE kg_environment_types,            ONLY: kg_environment_type
      48              :    USE kinds,                           ONLY: default_string_length,&
      49              :                                               dp
      50              :    USE lri_environment_types,           ONLY: lri_density_type,&
      51              :                                               lri_environment_type,&
      52              :                                               lri_kind_type
      53              :    USE lri_ks_methods,                  ONLY: calculate_lri_ks_matrix
      54              :    USE message_passing,                 ONLY: mp_para_env_type
      55              :    USE mulliken,                        ONLY: ao_charges
      56              :    USE particle_types,                  ONLY: particle_type
      57              :    USE pw_env_types,                    ONLY: pw_env_get,&
      58              :                                               pw_env_type
      59              :    USE pw_methods,                      ONLY: pw_axpy,&
      60              :                                               pw_copy,&
      61              :                                               pw_scale,&
      62              :                                               pw_transfer
      63              :    USE pw_poisson_methods,              ONLY: pw_poisson_solve
      64              :    USE pw_poisson_types,                ONLY: pw_poisson_type
      65              :    USE pw_pool_types,                   ONLY: pw_pool_type
      66              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      67              :                                               pw_r3d_rs_type
      68              :    USE qs_dispersion_nonloc,            ONLY: qs_fxc_nlvdw_apply
      69              :    USE qs_environment_types,            ONLY: get_qs_env,&
      70              :                                               qs_environment_type
      71              :    USE qs_fxc,                          ONLY: qs_fxc_apply,&
      72              :                                               qs_fxc_prep
      73              :    USE qs_gapw_densities,               ONLY: prepare_gapw_den
      74              :    USE qs_integrate_potential,          ONLY: integrate_v_rspace,&
      75              :                                               integrate_v_rspace_diagonal,&
      76              :                                               integrate_v_rspace_one_center
      77              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      78              :                                               get_qs_kind_set,&
      79              :                                               qs_kind_type
      80              :    USE qs_kpp1_env_methods,             ONLY: kpp1_check_i_alloc
      81              :    USE qs_kpp1_env_types,               ONLY: qs_kpp1_env_type
      82              :    USE qs_ks_atom,                      ONLY: update_ks_atom
      83              :    USE qs_linres_types,                 ONLY: linres_control_type
      84              :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
      85              :    USE qs_p_env_methods,                ONLY: p_env_finish_kpp1
      86              :    USE qs_p_env_types,                  ONLY: qs_p_env_type
      87              :    USE qs_rho0_ggrid,                   ONLY: integrate_vhg0_rspace
      88              :    USE qs_rho_atom_types,               ONLY: rho_atom_type
      89              :    USE qs_rho_methods,                  ONLY: qs_rho_rebuild,&
      90              :                                               qs_rho_update_rho
      91              :    USE qs_rho_types,                    ONLY: qs_rho_create,&
      92              :                                               qs_rho_get,&
      93              :                                               qs_rho_release,&
      94              :                                               qs_rho_type
      95              :    USE task_list_types,                 ONLY: task_list_type
      96              :    USE xtb_ehess,                       ONLY: xtb_coulomb_hessian
      97              :    USE xtb_types,                       ONLY: get_xtb_atom_param,&
      98              :                                               xtb_atom_type
      99              : #include "./base/base_uses.f90"
     100              : 
     101              :    IMPLICIT NONE
     102              : 
     103              :    PRIVATE
     104              : 
     105              :    ! *** Public subroutines ***
     106              :    PUBLIC :: apply_xc_admm
     107              :    PUBLIC :: apply_hfx
     108              :    PUBLIC :: apply_hxc_kernel_kp
     109              :    PUBLIC :: apply_op_2
     110              :    PUBLIC :: hfx_matrix
     111              : 
     112              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_kernel'
     113              : 
     114              : ! **************************************************************************************************
     115              : 
     116              : CONTAINS
     117              : 
     118              : ! **************************************************************************************************
     119              : !> \brief Apply the periodic GPW Hartree-XC kernel to a K-point AO density response.
     120              : !> \param qs_env Ground-state QS environment defining the density and XC kernel.
     121              : !> \param kpp1_env Persistent XC derivative data at the ground-state density.
     122              : !> \param rho1_ao_kp Real-space image matrices of the spin-resolved density response.
     123              : !> \param v1_ao_kp Real-space image matrices of the resulting Hartree-XC potential response.
     124              : !>
     125              : !> The input is the physical density response, including occupations and irreducible K-point
     126              : !> weights.  Consequently, unlike the occupied-virtual linear-response path, no closed-shell
     127              : !> factor of two is introduced here.
     128              : ! **************************************************************************************************
     129          180 :    SUBROUTINE apply_hxc_kernel_kp(qs_env, kpp1_env, rho1_ao_kp, v1_ao_kp)
     130              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     131              :       TYPE(qs_kpp1_env_type), INTENT(INOUT)              :: kpp1_env
     132              :       TYPE(dbcsr_p_type), DIMENSION(:, :), INTENT(IN)    :: rho1_ao_kp
     133              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: v1_ao_kp
     134              : 
     135              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'apply_hxc_kernel_kp'
     136              : 
     137              :       INTEGER                                            :: handle, img, ispin, nimages, nspins
     138              :       LOGICAL                                            :: do_hfx
     139              :       REAL(KIND=dp)                                      :: energy_hartree
     140              :       TYPE(admm_type), POINTER                           :: admm_env
     141          180 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: v1_ao_spin
     142          180 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: rho1_work
     143              :       TYPE(dft_control_type), POINTER                    :: dft_control
     144              :       TYPE(pw_c1d_gs_type)                               :: rho1_tot_gspace, v_hartree_gspace
     145          180 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho1_g
     146              :       TYPE(pw_env_type), POINTER                         :: pw_env
     147              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
     148              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     149              :       TYPE(pw_r3d_rs_type)                               :: v_hartree_rspace
     150          180 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho0_r, rho1_r, v_hxc, v_xc, v_xc_tau
     151              :       TYPE(qs_rho_type), POINTER                         :: rho, rho1
     152              :       TYPE(qs_rho_type), TARGET                          :: rho1_store
     153          180 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho1_atom_set, rho_atom_set
     154              :       TYPE(section_vals_type), POINTER                   :: hfx_section, input, xc_section
     155              : 
     156          180 :       CALL timeset(routineN, handle)
     157              : 
     158          180 :       NULLIFY (admm_env, auxbas_pw_pool, dft_control, hfx_section, input, poisson_env, pw_env, rho, rho1, &
     159          180 :                rho1_g, rho1_work, rho_atom_set, rho1_atom_set, v1_ao_spin, v_hxc, v_xc, &
     160          180 :                v_xc_tau, xc_section)
     161              :       CALL get_qs_env(qs_env=qs_env, admm_env=admm_env, dft_control=dft_control, input=input, &
     162          180 :                       pw_env=pw_env, rho=rho)
     163              : 
     164          180 :       IF (dft_control%qs_control%semi_empirical .OR. dft_control%qs_control%dftb .OR. &
     165              :           dft_control%qs_control%xtb) THEN
     166            0 :          CPABORT("The periodic AO Hartree-XC kernel is only available for DFT")
     167              :       END IF
     168              :       IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc .OR. &
     169          180 :           dft_control%qs_control%lrigpw .OR. dft_control%qs_control%rigpw) THEN
     170            0 :          CPABORT("The periodic AO Hartree-XC kernel currently requires GPW")
     171              :       END IF
     172          180 :       IF (dft_control%do_admm) THEN
     173            0 :          CPABORT("The periodic AO Hartree-XC kernel currently excludes ADMM")
     174              :       END IF
     175          180 :       hfx_section => section_vals_get_subs_vals(input, "DFT%XC%HF")
     176          180 :       CALL section_vals_get(hfx_section, explicit=do_hfx)
     177          180 :       IF (do_hfx) THEN
     178            0 :          CPABORT("The periodic AO Hartree-XC kernel currently excludes exact exchange")
     179              :       END IF
     180              : 
     181          180 :       nspins = dft_control%nspins
     182          180 :       nimages = dft_control%nimages
     183          540 :       CPASSERT(ALL(SHAPE(rho1_ao_kp) == [nspins, nimages]))
     184              : 
     185          180 :       IF (.NOT. ASSOCIATED(v1_ao_kp)) THEN
     186          180 :          CALL dbcsr_allocate_matrix_set(v1_ao_kp, nspins, nimages)
     187          360 :          DO ispin = 1, nspins
     188        39382 :             DO img = 1, nimages
     189        39022 :                ALLOCATE (v1_ao_kp(ispin, img)%matrix)
     190              :                CALL dbcsr_copy(v1_ao_kp(ispin, img)%matrix, rho1_ao_kp(ispin, img)%matrix, &
     191        39202 :                                name="K-point Hartree-XC response")
     192              :             END DO
     193              :          END DO
     194              :       ELSE
     195            0 :          CPASSERT(ALL(SHAPE(v1_ao_kp) == [nspins, nimages]))
     196              :       END IF
     197          360 :       DO ispin = 1, nspins
     198        39382 :          DO img = 1, nimages
     199        39202 :             CALL dbcsr_set(v1_ao_kp(ispin, img)%matrix, 0.0_dp)
     200              :          END DO
     201              :       END DO
     202              : 
     203          180 :       CALL qs_rho_create(rho1_store)
     204          180 :       rho1 => rho1_store
     205          180 :       CALL qs_rho_rebuild(rho1_store, qs_env, rebuild_ao=.TRUE., rebuild_grids=.TRUE.)
     206          180 :       CALL qs_rho_get(rho1, rho_ao_kp=rho1_work)
     207          360 :       DO ispin = 1, nspins
     208        39382 :          DO img = 1, nimages
     209        39202 :             CALL dbcsr_copy(rho1_work(ispin, img)%matrix, rho1_ao_kp(ispin, img)%matrix)
     210              :          END DO
     211              :       END DO
     212          180 :       CALL qs_rho_update_rho(rho1, qs_env)
     213              : 
     214          180 :       xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     215          180 :       IF (.NOT. ASSOCIATED(kpp1_env%deriv_set)) THEN
     216         2392 :          ALLOCATE (kpp1_env%deriv_set, kpp1_env%rho_set)
     217              :          CALL qs_fxc_prep(qs_env, rho, kpp1_env%rho_set, kpp1_env%deriv_set, &
     218          104 :                           xc_section, pw_env, is_triplet=.FALSE.)
     219              :       END IF
     220              : 
     221          180 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, poisson_env=poisson_env)
     222          180 :       CALL auxbas_pw_pool%create_pw(rho1_tot_gspace)
     223          180 :       CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
     224          180 :       CALL auxbas_pw_pool%create_pw(v_hartree_rspace)
     225          180 :       CALL qs_rho_get(rho1, rho_g=rho1_g)
     226          180 :       CALL pw_copy(rho1_g(1), rho1_tot_gspace)
     227          180 :       DO ispin = 2, nspins
     228          180 :          CALL pw_axpy(rho1_g(ispin), rho1_tot_gspace)
     229              :       END DO
     230              :       energy_hartree = 0.0_dp
     231          180 :       CALL pw_poisson_solve(poisson_env, rho1_tot_gspace, energy_hartree, v_hartree_gspace)
     232          180 :       CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
     233          180 :       CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
     234              : 
     235              :       CALL qs_fxc_apply(qs_env, kpp1_env%deriv_set, kpp1_env%rho_set, rho1, &
     236          180 :                         rho_atom_set, xc_section, .FALSE., v_xc, v_xc_tau, rho1_atom_set)
     237              :       ! nl-vdW
     238          180 :       CALL qs_rho_get(rho, rho_r=rho0_r)
     239          180 :       CALL qs_rho_get(rho1, rho_r=rho1_r)
     240          180 :       CALL qs_fxc_nlvdw_apply(qs_env, xc_section, qs_env%dispersion_env, rho0_r, rho1_r, v_xc)
     241              :       !
     242          180 :       v_hxc => v_xc
     243          180 :       NULLIFY (v_xc)
     244          360 :       DO ispin = 1, nspins
     245          180 :          CALL pw_scale(v_hxc(ispin), v_hxc(ispin)%pw_grid%dvol)
     246          180 :          CALL pw_axpy(v_hartree_rspace, v_hxc(ispin))
     247          180 :          v1_ao_spin => v1_ao_kp(ispin, :)
     248              :          CALL integrate_v_rspace(v_rspace=v_hxc(ispin), hmat_kp=v1_ao_spin, &
     249          360 :                                  qs_env=qs_env, calculate_forces=.FALSE.)
     250              :       END DO
     251          180 :       IF (ASSOCIATED(v_xc_tau)) THEN
     252            0 :          DO ispin = 1, nspins
     253            0 :             CALL pw_scale(v_xc_tau(ispin), v_xc_tau(ispin)%pw_grid%dvol)
     254            0 :             v1_ao_spin => v1_ao_kp(ispin, :)
     255              :             CALL integrate_v_rspace(v_rspace=v_xc_tau(ispin), hmat_kp=v1_ao_spin, &
     256            0 :                                     qs_env=qs_env, compute_tau=.TRUE., calculate_forces=.FALSE.)
     257              :          END DO
     258              :       END IF
     259          180 :       NULLIFY (v1_ao_spin)
     260              : 
     261          180 :       CALL auxbas_pw_pool%give_back_pw(rho1_tot_gspace)
     262          180 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
     263          180 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_rspace)
     264          360 :       DO ispin = 1, SIZE(v_hxc)
     265          360 :          CALL auxbas_pw_pool%give_back_pw(v_hxc(ispin))
     266              :       END DO
     267          180 :       DEALLOCATE (v_hxc)
     268          180 :       IF (ASSOCIATED(v_xc_tau)) THEN
     269            0 :          DO ispin = 1, SIZE(v_xc_tau)
     270            0 :             CALL auxbas_pw_pool%give_back_pw(v_xc_tau(ispin))
     271              :          END DO
     272            0 :          DEALLOCATE (v_xc_tau)
     273              :       END IF
     274          180 :       CALL qs_rho_release(rho1_store)
     275              : 
     276          180 :       CALL timestop(handle)
     277          180 :    END SUBROUTINE apply_hxc_kernel_kp
     278              : 
     279              : ! **************************************************************************************************
     280              : !> \brief ...
     281              : !> \param qs_env ...
     282              : !> \param p_env ...
     283              : !> \param c0 ...
     284              : !> \param Av ...
     285              : ! **************************************************************************************************
     286         9958 :    SUBROUTINE apply_op_2(qs_env, p_env, c0, Av)
     287              :       !
     288              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     289              :       TYPE(qs_p_env_type)                                :: p_env
     290              :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: c0
     291              :       TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT)      :: Av
     292              : 
     293              :       INTEGER                                            :: ispin, ncol
     294              :       TYPE(dft_control_type), POINTER                    :: dft_control
     295              : 
     296         9958 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
     297         9958 :       IF (dft_control%qs_control%semi_empirical) THEN
     298            0 :          CPABORT("Linear response not available with SE methods")
     299         9958 :       ELSE IF (dft_control%qs_control%dftb) THEN
     300            0 :          CPABORT("Linear response not available with DFTB")
     301         9958 :       ELSE IF (dft_control%qs_control%xtb) THEN
     302          206 :          CALL apply_op_2_xtb(qs_env, p_env)
     303              :       ELSE
     304         9752 :          CALL apply_op_2_dft(qs_env, p_env)
     305         9752 :          CALL apply_hfx(qs_env, p_env)
     306         9752 :          CALL apply_xc_admm(qs_env, p_env)
     307         9752 :          IF (dft_control%do_admm) CALL p_env_finish_kpp1(qs_env, p_env)
     308              :       END IF
     309              : 
     310        21172 :       DO ispin = 1, SIZE(c0)
     311        11214 :          CALL cp_fm_get_info(c0(ispin), ncol_global=ncol)
     312              :          CALL cp_dbcsr_sm_fm_multiply(p_env%kpp1(ispin)%matrix, &
     313              :                                       c0(ispin), &
     314              :                                       Av(ispin), &
     315        21172 :                                       ncol=ncol, alpha=1.0_dp, beta=1.0_dp)
     316              :       END DO
     317              : 
     318         9958 :    END SUBROUTINE apply_op_2
     319              : 
     320              : ! **************************************************************************************************
     321              : !> \brief ...
     322              : !> \param qs_env ...
     323              : !> \param p_env ...
     324              : ! **************************************************************************************************
     325         9752 :    SUBROUTINE apply_op_2_dft(qs_env, p_env)
     326              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     327              :       TYPE(qs_p_env_type)                                :: p_env
     328              : 
     329              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'apply_op_2_dft'
     330              : 
     331              :       INTEGER                                            :: handle, ikind, ispin, nkind, ns, nspins
     332              :       LOGICAL                                            :: do_onecenter, gapw, gapw_xc, lr_triplet, &
     333              :                                                             lrigpw
     334              :       REAL(KIND=dp)                                      :: alpha, ekin_mol, energy_hartree, &
     335              :                                                             energy_hartree_1c
     336              :       TYPE(admm_type), POINTER                           :: admm_env
     337         9752 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     338              :       TYPE(cp_logger_type), POINTER                      :: logger
     339         9752 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: k1mat, rho1_ao, rho_ao
     340         9752 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ksmat, psmat
     341              :       TYPE(dft_control_type), POINTER                    :: dft_control
     342              :       TYPE(kg_environment_type), POINTER                 :: kg_env
     343              :       TYPE(linres_control_type), POINTER                 :: linres_control
     344              :       TYPE(lri_density_type), POINTER                    :: lri_density
     345              :       TYPE(lri_environment_type), POINTER                :: lri_env
     346         9752 :       TYPE(lri_kind_type), DIMENSION(:), POINTER         :: lri_v_int
     347              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     348              :       TYPE(pw_c1d_gs_type)                               :: rho1_tot_gspace, v_hartree_gspace
     349         9752 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho1_g
     350              :       TYPE(pw_env_type), POINTER                         :: pw_env
     351              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
     352              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     353              :       TYPE(pw_r3d_rs_type)                               :: v_hartree_rspace
     354         9752 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho0_r, rho1_r, rho_r, v_rspace_new, &
     355         9752 :                                                             v_xc, v_xc_tau
     356              :       TYPE(qs_kpp1_env_type), POINTER                    :: kpp1_env
     357              :       TYPE(qs_rho_type), POINTER                         :: rho, rho0, rho1, rho1_xc, rho1a, &
     358              :                                                             rho_aux, rho_xc
     359         9752 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho1_atom_set, rho_atom_set
     360              :       TYPE(section_vals_type), POINTER                   :: input, xc_section, xc_section_aux
     361              : 
     362         9752 :       CALL timeset(routineN, handle)
     363              : 
     364         9752 :       NULLIFY (auxbas_pw_pool, pw_env, v_rspace_new, para_env, v_xc, &
     365         9752 :                rho1_ao, rho_ao, poisson_env, input, rho, dft_control, logger, &
     366         9752 :                rho1_g, v_xc_tau)
     367         9752 :       logger => cp_get_default_logger()
     368              : 
     369         9752 :       energy_hartree = 0.0_dp
     370         9752 :       energy_hartree_1c = 0.0_dp
     371              : 
     372         9752 :       CPASSERT(ASSOCIATED(p_env%kpp1))
     373         9752 :       CPASSERT(ASSOCIATED(p_env%kpp1_env))
     374         9752 :       kpp1_env => p_env%kpp1_env
     375              : 
     376              :       CALL get_qs_env(qs_env=qs_env, &
     377              :                       pw_env=pw_env, &
     378              :                       input=input, &
     379              :                       admm_env=admm_env, &
     380              :                       para_env=para_env, &
     381              :                       rho=rho, &
     382              :                       rho_xc=rho_xc, &
     383              :                       linres_control=linres_control, &
     384         9752 :                       dft_control=dft_control)
     385              : 
     386         9752 :       gapw = dft_control%qs_control%gapw
     387         9752 :       gapw_xc = dft_control%qs_control%gapw_xc
     388         9752 :       do_onecenter = gapw .OR. gapw_xc
     389         9752 :       lr_triplet = linres_control%lr_triplet
     390              : 
     391         9752 :       rho1 => p_env%rho1
     392         9752 :       rho1_xc => p_env%rho1_xc
     393         9752 :       CPASSERT(ASSOCIATED(rho1))
     394         9752 :       IF (gapw_xc) THEN
     395          560 :          CPASSERT(ASSOCIATED(rho1_xc))
     396              :       END IF
     397              : 
     398         9752 :       CALL qs_rho_get(rho, rho_ao=rho_ao, rho_r=rho_r)
     399         9752 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     400              : 
     401         9752 :       nspins = SIZE(p_env%kpp1)
     402         9752 :       lrigpw = dft_control%qs_control%lrigpw
     403         9752 :       IF (lrigpw) THEN
     404              :          CALL get_qs_env(qs_env, &
     405              :                          lri_env=lri_env, &
     406              :                          lri_density=lri_density, &
     407           72 :                          atomic_kind_set=atomic_kind_set)
     408              :       END IF
     409              : 
     410         9752 :       IF (dft_control%do_admm) THEN
     411         2158 :          xc_section => admm_env%xc_section_primary
     412              :       ELSE
     413         7594 :          xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     414              :       END IF
     415              : 
     416         9752 :       CALL kpp1_check_i_alloc(kpp1_env, qs_env, xc_section)
     417              : 
     418              :       ! gets the tmp grids
     419         9752 :       CPASSERT(ASSOCIATED(pw_env))
     420              :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
     421         9752 :                       poisson_env=poisson_env)
     422         9752 :       CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
     423         9752 :       CALL auxbas_pw_pool%create_pw(v_hartree_rspace)
     424              : 
     425         9752 :       IF (gapw .OR. gapw_xc) THEN
     426         2510 :          CALL prepare_gapw_den(qs_env, p_env%local_rho_set, do_rho0=(.NOT. gapw_xc))
     427              :       END IF
     428              : 
     429              :       ! *** calculate the hartree potential on the total density ***
     430         9752 :       CALL auxbas_pw_pool%create_pw(rho1_tot_gspace)
     431              : 
     432         9752 :       CALL qs_rho_get(rho1, rho_g=rho1_g)
     433         9752 :       CALL pw_copy(rho1_g(1), rho1_tot_gspace)
     434        10912 :       DO ispin = 2, nspins
     435        10912 :          CALL pw_axpy(rho1_g(ispin), rho1_tot_gspace)
     436              :       END DO
     437         9752 :       IF (gapw) THEN
     438         1950 :          CALL pw_axpy(p_env%local_rho_set%rho0_mpole%rho0_s_gs, rho1_tot_gspace)
     439         1950 :          IF (ASSOCIATED(p_env%local_rho_set%rho0_mpole%rhoz_cneo_s_gs)) THEN
     440            0 :             CALL pw_axpy(p_env%local_rho_set%rho0_mpole%rhoz_cneo_s_gs, rho1_tot_gspace)
     441              :          END IF
     442              :       END IF
     443              : 
     444         9752 :       IF (.NOT. (nspins == 1 .AND. lr_triplet)) THEN
     445              :          CALL pw_poisson_solve(poisson_env, rho1_tot_gspace, &
     446              :                                energy_hartree, &
     447         9752 :                                v_hartree_gspace)
     448         9752 :          CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
     449              :       END IF
     450              : 
     451         9752 :       CALL auxbas_pw_pool%give_back_pw(rho1_tot_gspace)
     452              : 
     453              :       ! *** calculate the xc potential ***
     454         9752 :       NULLIFY (rho1a)
     455         9752 :       IF (gapw_xc) THEN
     456          560 :          CALL get_qs_env(qs_env, rho_xc=rho0)
     457          560 :          rho1a => rho1_xc
     458              :       ELSE
     459         9192 :          CALL get_qs_env(qs_env, rho=rho0)
     460         9192 :          rho1a => rho1
     461              :       END IF
     462              : 
     463         9752 :       NULLIFY (v_xc_tau)
     464         9752 :       NULLIFY (rho_atom_set, rho1_atom_set)
     465         9752 :       IF (do_onecenter) THEN
     466         2510 :          CALL get_qs_env(qs_env, rho_atom_set=rho_atom_set)
     467         2510 :          rho1_atom_set => p_env%local_rho_set%rho_atom_set
     468              :       END IF
     469              :       CALL qs_fxc_apply(qs_env, kpp1_env%deriv_set, kpp1_env%rho_set, rho1a, rho_atom_set, &
     470         9752 :                         xc_section, do_onecenter, v_xc, v_xc_tau, rho1_atom_set)
     471              :       ! nl-vdW
     472         9752 :       CALL qs_rho_get(rho0, rho_r=rho0_r)
     473         9752 :       CALL qs_rho_get(rho1a, rho_r=rho1_r)
     474         9752 :       CALL qs_fxc_nlvdw_apply(qs_env, xc_section, qs_env%dispersion_env, rho0_r, rho1_r, v_xc)
     475              : 
     476         9752 :       v_rspace_new => v_xc
     477         9752 :       NULLIFY (v_xc)
     478              : 
     479         9752 :       CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
     480        20664 :       DO ispin = 1, nspins
     481        10912 :          CALL pw_scale(v_rspace_new(ispin), v_rspace_new(ispin)%pw_grid%dvol)
     482        20664 :          IF (ASSOCIATED(v_xc_tau)) CALL pw_scale(v_xc_tau(ispin), v_xc_tau(ispin)%pw_grid%dvol)
     483              :       END DO
     484              : 
     485              :       ! ADMM Correction
     486         9752 :       IF (dft_control%do_admm) THEN
     487         2158 :          IF (admm_env%aux_exch_func /= do_admm_aux_exch_func_none) THEN
     488         1312 :             IF (.NOT. ASSOCIATED(kpp1_env%deriv_set_admm)) THEN
     489            0 :                CPASSERT(.NOT. lr_triplet)
     490            0 :                xc_section_aux => admm_env%xc_section_aux
     491            0 :                CALL get_admm_env(qs_env%admm_env, rho_aux_fit=rho_aux)
     492            0 :                ALLOCATE (kpp1_env%deriv_set_admm, kpp1_env%rho_set_admm)
     493              :                CALL qs_fxc_prep(qs_env, rho_aux, kpp1_env%rho_set_admm, kpp1_env%deriv_set_admm, &
     494            0 :                                 xc_section_aux, pw_env, is_triplet=.FALSE.)
     495              :             END IF
     496              :          END IF
     497              :       END IF
     498              : 
     499              :       !-------------------------------!
     500              :       ! Add both hartree and xc terms !
     501              :       !-------------------------------!
     502        20664 :       DO ispin = 1, nspins
     503        10912 :          CALL dbcsr_set(kpp1_env%v_ao(ispin)%matrix, 0.0_dp)
     504              : 
     505        10912 :          IF (gapw_xc) THEN
     506              :             ! XC and Hartree are integrated separatedly
     507              :             ! XC uses the soft basis set only
     508              : 
     509          588 :             IF (nspins == 1) THEN
     510              : 
     511          532 :                IF (.NOT. (lr_triplet)) THEN
     512          532 :                   CALL pw_scale(v_rspace_new(1), 2.0_dp)
     513          532 :                   IF (ASSOCIATED(v_xc_tau)) CALL pw_scale(v_xc_tau(1), 2.0_dp)
     514              :                END IF
     515          532 :                CALL qs_rho_get(rho1, rho_ao=rho1_ao)
     516              :                ! remove kpp1_env%v_ao and work directly on k_p_p1 ?
     517              :                CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
     518              :                                        pmat=rho1_ao(ispin), &
     519              :                                        hmat=kpp1_env%v_ao(ispin), &
     520              :                                        qs_env=qs_env, &
     521          532 :                                        calculate_forces=.FALSE., gapw=gapw_xc)
     522              : 
     523          532 :                IF (ASSOCIATED(v_xc_tau)) THEN
     524              :                   CALL integrate_v_rspace(v_rspace=v_xc_tau(ispin), &
     525              :                                           pmat=rho1_ao(ispin), &
     526              :                                           hmat=kpp1_env%v_ao(ispin), &
     527              :                                           qs_env=qs_env, &
     528              :                                           compute_tau=.TRUE., &
     529            0 :                                           calculate_forces=.FALSE., gapw=gapw_xc)
     530              :                END IF
     531              : 
     532              :                ! add hartree only for SINGLETS
     533          532 :                IF (.NOT. lr_triplet) THEN
     534          532 :                   CALL pw_axpy(v_hartree_rspace, v_rspace_new(1), 2.0_dp, 0.0_dp)
     535              : 
     536              :                   CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
     537              :                                           pmat=rho_ao(ispin), &
     538              :                                           hmat=kpp1_env%v_ao(ispin), &
     539              :                                           qs_env=qs_env, &
     540          532 :                                           calculate_forces=.FALSE., gapw=gapw)
     541              :                END IF
     542              :             ELSE
     543              :                ! remove kpp1_env%v_ao and work directly on k_p_p1 ?
     544              :                CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
     545              :                                        pmat=rho_ao(ispin), &
     546              :                                        hmat=kpp1_env%v_ao(ispin), &
     547              :                                        qs_env=qs_env, &
     548           56 :                                        calculate_forces=.FALSE., gapw=gapw_xc)
     549              : 
     550           56 :                IF (ASSOCIATED(v_xc_tau)) THEN
     551              :                   CALL integrate_v_rspace(v_rspace=v_xc_tau(ispin), &
     552              :                                           pmat=rho_ao(ispin), &
     553              :                                           hmat=kpp1_env%v_ao(ispin), &
     554              :                                           qs_env=qs_env, &
     555              :                                           compute_tau=.TRUE., &
     556            0 :                                           calculate_forces=.FALSE., gapw=gapw_xc)
     557              :                END IF
     558              : 
     559           56 :                CALL pw_copy(v_hartree_rspace, v_rspace_new(ispin))
     560              :                CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
     561              :                                        pmat=rho_ao(ispin), &
     562              :                                        hmat=kpp1_env%v_ao(ispin), &
     563              :                                        qs_env=qs_env, &
     564           56 :                                        calculate_forces=.FALSE., gapw=gapw)
     565              :             END IF
     566              : 
     567              :          ELSE
     568              : 
     569        10324 :             IF (nspins == 1) THEN
     570         8060 :                IF (.NOT. (lr_triplet)) THEN
     571         8060 :                   CALL pw_scale(v_rspace_new(1), 2.0_dp)
     572         8060 :                   IF (ASSOCIATED(v_xc_tau)) CALL pw_scale(v_xc_tau(1), 2.0_dp)
     573              :                END IF
     574              :                ! add hartree only for SINGLETS
     575              :                !IF (res_etype == tddfpt_singlet) THEN
     576              :                IF (.NOT. lr_triplet) THEN
     577         8060 :                   CALL pw_axpy(v_hartree_rspace, v_rspace_new(1), 2.0_dp)
     578              :                END IF
     579              :             ELSE
     580         2264 :                CALL pw_axpy(v_hartree_rspace, v_rspace_new(ispin), 1.0_dp)
     581              :             END IF
     582              : 
     583        10324 :             IF (lrigpw) THEN
     584           72 :                IF (ASSOCIATED(v_xc_tau)) THEN
     585            0 :                   CPABORT("metaGGA-functionals not supported with LRI!")
     586              :                END IF
     587              : 
     588           72 :                lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
     589           72 :                CALL get_qs_env(qs_env, nkind=nkind)
     590          216 :                DO ikind = 1, nkind
     591        43008 :                   lri_v_int(ikind)%v_int = 0.0_dp
     592              :                END DO
     593              :                CALL integrate_v_rspace_one_center(v_rspace_new(ispin), qs_env, &
     594           72 :                                                   lri_v_int, .FALSE., "LRI_AUX")
     595          216 :                DO ikind = 1, nkind
     596        85800 :                   CALL para_env%sum(lri_v_int(ikind)%v_int)
     597              :                END DO
     598          144 :                ALLOCATE (k1mat(1))
     599           72 :                k1mat(1)%matrix => kpp1_env%v_ao(ispin)%matrix
     600           72 :                IF (lri_env%exact_1c_terms) THEN
     601              :                   CALL integrate_v_rspace_diagonal(v_rspace_new(ispin), k1mat(1)%matrix, &
     602            0 :                                                    rho_ao(ispin)%matrix, qs_env, .FALSE., "ORB")
     603              :                END IF
     604           72 :                CALL calculate_lri_ks_matrix(lri_env, lri_v_int, k1mat, atomic_kind_set)
     605           72 :                DEALLOCATE (k1mat)
     606              :             ELSE
     607              :                CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
     608              :                                        pmat=rho_ao(ispin), &
     609              :                                        hmat=kpp1_env%v_ao(ispin), &
     610              :                                        qs_env=qs_env, &
     611        10252 :                                        calculate_forces=.FALSE., gapw=gapw)
     612              : 
     613        10252 :                IF (ASSOCIATED(v_xc_tau)) THEN
     614              :                   CALL integrate_v_rspace(v_rspace=v_xc_tau(ispin), &
     615              :                                           pmat=rho_ao(ispin), &
     616              :                                           hmat=kpp1_env%v_ao(ispin), &
     617              :                                           qs_env=qs_env, &
     618              :                                           compute_tau=.TRUE., &
     619          358 :                                           calculate_forces=.FALSE., gapw=gapw)
     620              :                END IF
     621              :             END IF
     622              : 
     623              :          END IF
     624              : 
     625        20664 :          CALL dbcsr_copy(p_env%kpp1(ispin)%matrix, kpp1_env%v_ao(ispin)%matrix)
     626              :       END DO
     627              : 
     628         9752 :       IF (gapw) THEN
     629         1950 :          IF (.NOT. ((nspins == 1 .AND. lr_triplet))) THEN
     630              :             CALL Vh_1c_gg_integrals(qs_env, energy_hartree_1c, &
     631              :                                     p_env%hartree_local%ecoul_1c, &
     632              :                                     p_env%local_rho_set, &
     633         1950 :                                     para_env, tddft=.TRUE., core_2nd=.TRUE.)
     634              : 
     635              :             CALL integrate_vhg0_rspace(qs_env, v_hartree_rspace, para_env, &
     636              :                                        calculate_forces=.FALSE., &
     637         1950 :                                        local_rho_set=p_env%local_rho_set)
     638              :          END IF
     639              :          ! ***  Add single atom contributions to the KS matrix ***
     640              :          ! remap pointer
     641         1950 :          ns = SIZE(p_env%kpp1)
     642         1950 :          ksmat(1:ns, 1:1) => p_env%kpp1(1:ns)
     643         1950 :          ns = SIZE(rho_ao)
     644         1950 :          psmat(1:ns, 1:1) => rho_ao(1:ns)
     645              :          CALL update_ks_atom(qs_env, ksmat, psmat, forces=.FALSE., tddft=.TRUE., &
     646         1950 :                              rho_atom_external=p_env%local_rho_set%rho_atom_set)
     647         7802 :       ELSE IF (gapw_xc) THEN
     648          560 :          ns = SIZE(p_env%kpp1)
     649          560 :          ksmat(1:ns, 1:1) => p_env%kpp1(1:ns)
     650          560 :          ns = SIZE(rho_ao)
     651          560 :          psmat(1:ns, 1:1) => rho_ao(1:ns)
     652              :          CALL update_ks_atom(qs_env, ksmat, psmat, forces=.FALSE., tddft=.TRUE., &
     653          560 :                              rho_atom_external=p_env%local_rho_set%rho_atom_set)
     654              :       END IF
     655              : 
     656              :       ! KG embedding, contribution of kinetic energy functional to kernel
     657         9752 :       IF (dft_control%qs_control%do_kg .AND. .NOT. (lr_triplet .OR. gapw .OR. gapw_xc)) THEN
     658           16 :          IF (qs_env%kg_env%tnadd_method == kg_tnadd_embed) THEN
     659              : 
     660           10 :             CALL qs_rho_get(rho1, rho_ao=rho1_ao)
     661           10 :             alpha = 1.0_dp
     662              : 
     663              :             ekin_mol = 0.0_dp
     664           10 :             CALL get_qs_env(qs_env, kg_env=kg_env)
     665              :             CALL kg_ekin_subset(qs_env=qs_env, &
     666              :                                 ks_matrix=p_env%kpp1, &
     667              :                                 ekin_mol=ekin_mol, &
     668              :                                 calc_force=.FALSE., &
     669              :                                 do_kernel=.TRUE., &
     670           10 :                                 pmat_ext=rho1_ao)
     671              :          END IF
     672              :       END IF
     673              : 
     674         9752 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
     675         9752 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_rspace)
     676        20664 :       DO ispin = 1, nspins
     677        20664 :          CALL auxbas_pw_pool%give_back_pw(v_rspace_new(ispin))
     678              :       END DO
     679         9752 :       DEALLOCATE (v_rspace_new)
     680         9752 :       IF (ASSOCIATED(v_xc_tau)) THEN
     681          684 :          DO ispin = 1, nspins
     682          684 :             CALL auxbas_pw_pool%give_back_pw(v_xc_tau(ispin))
     683              :          END DO
     684          326 :          DEALLOCATE (v_xc_tau)
     685              :       END IF
     686              : 
     687         9752 :       CALL timestop(handle)
     688              : 
     689         9752 :    END SUBROUTINE apply_op_2_dft
     690              : 
     691              : ! **************************************************************************************************
     692              : !> \brief ...
     693              : !> \param qs_env ...
     694              : !> \param p_env ...
     695              : ! **************************************************************************************************
     696          206 :    SUBROUTINE apply_op_2_xtb(qs_env, p_env)
     697              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     698              :       TYPE(qs_p_env_type)                                :: p_env
     699              : 
     700              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'apply_op_2_xtb'
     701              : 
     702              :       INTEGER                                            :: atom_a, handle, iatom, ikind, is, ispin, &
     703              :                                                             na, natom, natorb, nkind, ns, nsgf, &
     704              :                                                             nspins
     705              :       INTEGER, DIMENSION(25)                             :: lao
     706              :       INTEGER, DIMENSION(5)                              :: occ
     707              :       LOGICAL                                            :: lr_triplet
     708          206 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: mcharge, mcharge1
     709          206 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: aocg, aocg1, charges, charges1
     710          206 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     711          206 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: pmat, rho_ao
     712          206 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_p1, matrix_s
     713              :       TYPE(dft_control_type), POINTER                    :: dft_control
     714              :       TYPE(linres_control_type), POINTER                 :: linres_control
     715              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     716          206 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     717              :       TYPE(pw_env_type), POINTER                         :: pw_env
     718          206 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     719              :       TYPE(qs_kpp1_env_type), POINTER                    :: kpp1_env
     720              :       TYPE(qs_rho_type), POINTER                         :: rho, rho1
     721              :       TYPE(xtb_atom_type), POINTER                       :: xtb_kind
     722              : 
     723          206 :       CALL timeset(routineN, handle)
     724              : 
     725          206 :       CPASSERT(ASSOCIATED(p_env%kpp1_env))
     726          206 :       CPASSERT(ASSOCIATED(p_env%kpp1))
     727          206 :       kpp1_env => p_env%kpp1_env
     728              : 
     729          206 :       rho1 => p_env%rho1
     730          206 :       CPASSERT(ASSOCIATED(rho1))
     731              : 
     732              :       CALL get_qs_env(qs_env=qs_env, &
     733              :                       pw_env=pw_env, &
     734              :                       para_env=para_env, &
     735              :                       rho=rho, &
     736              :                       linres_control=linres_control, &
     737          206 :                       dft_control=dft_control)
     738              : 
     739          206 :       CALL qs_rho_get(rho, rho_ao=rho_ao)
     740              : 
     741          206 :       lr_triplet = linres_control%lr_triplet
     742          206 :       CPASSERT(.NOT. lr_triplet)
     743              : 
     744          206 :       nspins = SIZE(p_env%kpp1)
     745              : 
     746          508 :       DO ispin = 1, nspins
     747          508 :          CALL dbcsr_set(p_env%kpp1(ispin)%matrix, 0.0_dp)
     748              :       END DO
     749              : 
     750          206 :       IF (dft_control%qs_control%xtb_control%coulomb_interaction) THEN
     751              :          ! Mulliken charges
     752          202 :          CALL get_qs_env(qs_env, particle_set=particle_set, matrix_s_kp=matrix_s)
     753          202 :          natom = SIZE(particle_set)
     754          202 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     755          202 :          CALL qs_rho_get(rho1, rho_ao_kp=matrix_p1)
     756         1010 :          ALLOCATE (mcharge(natom), charges(natom, 5))
     757          606 :          ALLOCATE (mcharge1(natom), charges1(natom, 5))
     758          202 :          charges = 0.0_dp
     759          202 :          charges1 = 0.0_dp
     760          202 :          CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
     761          202 :          nkind = SIZE(atomic_kind_set)
     762          202 :          CALL get_qs_kind_set(qs_kind_set, maxsgf=nsgf)
     763          808 :          ALLOCATE (aocg(nsgf, natom))
     764          202 :          aocg = 0.0_dp
     765          606 :          ALLOCATE (aocg1(nsgf, natom))
     766          202 :          aocg1 = 0.0_dp
     767          202 :          CALL ao_charges(matrix_p, matrix_s, aocg, para_env)
     768          202 :          CALL ao_charges(matrix_p1, matrix_s, aocg1, para_env)
     769         1872 :          IF (nspins == 2) aocg1 = 0.5_dp*aocg1
     770          704 :          DO ikind = 1, nkind
     771          502 :             CALL get_atomic_kind(atomic_kind_set(ikind), natom=na)
     772          502 :             CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_kind)
     773          502 :             CALL get_xtb_atom_param(xtb_kind, natorb=natorb, lao=lao, occupation=occ)
     774         3026 :             DO iatom = 1, na
     775         1820 :                atom_a = atomic_kind_set(ikind)%atom_list(iatom)
     776        10920 :                charges(atom_a, :) = REAL(occ(:), KIND=dp)
     777         7306 :                DO is = 1, natorb
     778         4984 :                   ns = lao(is) + 1
     779         4984 :                   charges(atom_a, ns) = charges(atom_a, ns) - aocg(is, atom_a)
     780         6804 :                   charges1(atom_a, ns) = charges1(atom_a, ns) - aocg1(is, atom_a)
     781              :                END DO
     782              :             END DO
     783              :          END DO
     784          202 :          DEALLOCATE (aocg, aocg1)
     785         2022 :          DO iatom = 1, natom
     786        10920 :             mcharge(iatom) = SUM(charges(iatom, :))
     787        11122 :             mcharge1(iatom) = SUM(charges1(iatom, :))
     788              :          END DO
     789              :          ! Coulomb Kernel
     790          202 :          pmat => matrix_p1(:, 1)
     791          202 :          CALL xtb_coulomb_hessian(qs_env, p_env%kpp1, charges1, mcharge1, mcharge, pmat)
     792              :          !
     793          404 :          DEALLOCATE (charges, mcharge, charges1, mcharge1)
     794              :       END IF
     795              : 
     796          206 :       CALL timestop(handle)
     797              : 
     798          412 :    END SUBROUTINE apply_op_2_xtb
     799              : 
     800              : ! **************************************************************************************************
     801              : !> \brief Update action of TDDFPT operator on trial vectors by adding exact-exchange term.
     802              : !> \param qs_env ...
     803              : !> \param p_env ...
     804              : !> \par History
     805              : !>    * 11.2019 adapted from tddfpt_apply_hfx
     806              : ! **************************************************************************************************
     807        20632 :    SUBROUTINE apply_hfx(qs_env, p_env)
     808              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     809              :       TYPE(qs_p_env_type)                                :: p_env
     810              : 
     811              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'apply_hfx'
     812              : 
     813              :       INTEGER                                            :: handle, ispin, nspins
     814              :       LOGICAL                                            :: do_hfx
     815              :       REAL(KIND=dp)                                      :: alpha
     816              :       TYPE(cp_logger_type), POINTER                      :: logger
     817        10316 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: h1_mat, matrix_s, rho1_ao, work
     818              :       TYPE(dft_control_type), POINTER                    :: dft_control
     819              :       TYPE(section_vals_type), POINTER                   :: hfx_section, input
     820              : 
     821        10316 :       CALL timeset(routineN, handle)
     822              : 
     823        10316 :       logger => cp_get_default_logger()
     824              : 
     825              :       CALL get_qs_env(qs_env=qs_env, &
     826              :                       input=input, &
     827              :                       matrix_s=matrix_s, &
     828        10316 :                       dft_control=dft_control)
     829        10316 :       nspins = dft_control%nspins
     830              : 
     831        10316 :       hfx_section => section_vals_get_subs_vals(input, "DFT%XC%HF")
     832        10316 :       CALL section_vals_get(hfx_section, explicit=do_hfx)
     833              : 
     834        10316 :       IF (do_hfx) THEN
     835              : 
     836         4130 :          IF (dft_control%do_admm) THEN
     837         2290 :             IF (dft_control%admm_control%purification_method /= do_admm_purify_none) THEN
     838            0 :                CPABORT("ADMM: Linear Response needs purification_method=none")
     839              :             END IF
     840         2290 :             IF (dft_control%admm_control%scaling_model /= do_admm_exch_scaling_none) THEN
     841            0 :                CPABORT("ADMM: Linear Response needs scaling_model=none")
     842              :             END IF
     843         2290 :             IF (dft_control%admm_control%method /= do_admm_basis_projection) THEN
     844            0 :                CPABORT("ADMM: Linear Response needs admm_method=basis_projection")
     845              :             END IF
     846              :             !
     847         2290 :             rho1_ao => p_env%p1_admm
     848         2290 :             h1_mat => p_env%kpp1_admm
     849              :          ELSE
     850         1840 :             rho1_ao => p_env%p1
     851         1840 :             h1_mat => p_env%kpp1
     852              :          END IF
     853              : 
     854         4130 :          NULLIFY (work)
     855         4130 :          CALL dbcsr_allocate_matrix_set(work, nspins)
     856         8658 :          DO ispin = 1, nspins
     857         4528 :             ALLOCATE (work(ispin)%matrix)
     858         4528 :             CALL dbcsr_create(work(ispin)%matrix, template=h1_mat(ispin)%matrix)
     859         4528 :             CALL dbcsr_copy(work(ispin)%matrix, h1_mat(ispin)%matrix)
     860         8658 :             CALL dbcsr_set(work(ispin)%matrix, 0.0_dp)
     861              :          END DO
     862              : 
     863         4130 :          CALL hfx_matrix(work, rho1_ao, qs_env, hfx_section)
     864              : 
     865         4130 :          alpha = 2.0_dp
     866         4130 :          IF (nspins == 2) alpha = 1.0_dp
     867              : 
     868         8658 :          DO ispin = 1, nspins
     869         8658 :             CALL dbcsr_add(h1_mat(ispin)%matrix, work(ispin)%matrix, 1.0_dp, alpha)
     870              :          END DO
     871              : 
     872         4130 :          CALL dbcsr_deallocate_matrix_set(work)
     873              : 
     874              :       END IF
     875              : 
     876        10316 :       CALL timestop(handle)
     877              : 
     878        10316 :    END SUBROUTINE apply_hfx
     879              : 
     880              : ! **************************************************************************************************
     881              : !> \brief Add the hfx contributions to the Hamiltonian
     882              : !>
     883              : !> \param matrix_ks ...
     884              : !> \param rho_ao ...
     885              : !> \param qs_env ...
     886              : !> \param hfx_sections ...
     887              : !> \param external_x_data ...
     888              : !> \param ex ...
     889              : !> \note
     890              : !>     Simplified version of subroutine hfx_ks_matrix()
     891              : ! **************************************************************************************************
     892         4130 :    SUBROUTINE hfx_matrix(matrix_ks, rho_ao, qs_env, hfx_sections, external_x_data, ex)
     893              :       TYPE(dbcsr_p_type), DIMENSION(:), TARGET           :: matrix_ks, rho_ao
     894              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     895              :       TYPE(section_vals_type), POINTER                   :: hfx_sections
     896              :       TYPE(hfx_type), DIMENSION(:, :), OPTIONAL, TARGET  :: external_x_data
     897              :       REAL(KIND=dp), OPTIONAL                            :: ex
     898              : 
     899              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'hfx_matrix'
     900              : 
     901              :       INTEGER                                            :: handle, irep, ispin, mspin, n_rep_hf, &
     902              :                                                             nspins
     903              :       LOGICAL                                            :: distribute_fock_matrix, &
     904              :                                                             hfx_treat_lsd_in_core, &
     905              :                                                             s_mstruct_changed
     906              :       REAL(KIND=dp)                                      :: eh1, ehfx
     907         4130 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks_kp, rho_ao_kp
     908              :       TYPE(dft_control_type), POINTER                    :: dft_control
     909         4130 :       TYPE(hfx_type), DIMENSION(:, :), POINTER           :: x_data
     910              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     911              : 
     912         4130 :       CALL timeset(routineN, handle)
     913              : 
     914         4130 :       NULLIFY (dft_control, para_env, matrix_ks_kp, rho_ao_kp, x_data)
     915              : 
     916              :       CALL get_qs_env(qs_env=qs_env, &
     917              :                       dft_control=dft_control, &
     918              :                       para_env=para_env, &
     919              :                       s_mstruct_changed=s_mstruct_changed, &
     920         4130 :                       x_data=x_data)
     921              : 
     922         4130 :       IF (PRESENT(external_x_data)) x_data => external_x_data
     923              : 
     924         4130 :       CPASSERT(dft_control%nimages == 1)
     925         4130 :       nspins = dft_control%nspins
     926              : 
     927         4130 :       CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
     928              :       CALL section_vals_val_get(hfx_sections, "TREAT_LSD_IN_CORE", l_val=hfx_treat_lsd_in_core, &
     929         4130 :                                 i_rep_section=1)
     930              : 
     931         4130 :       CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
     932         4130 :       distribute_fock_matrix = .TRUE.
     933              : 
     934         4130 :       mspin = 1
     935         4130 :       IF (hfx_treat_lsd_in_core) mspin = nspins
     936              : 
     937         4130 :       matrix_ks_kp(1:nspins, 1:1) => matrix_ks(1:nspins)
     938         4130 :       rho_ao_kp(1:nspins, 1:1) => rho_ao(1:nspins)
     939              : 
     940         8260 :       DO irep = 1, n_rep_hf
     941         4130 :          ehfx = 0.0_dp
     942              : 
     943         8260 :          IF (x_data(irep, 1)%do_hfx_ri) THEN
     944              :             CALL hfx_ri_update_ks(qs_env, x_data(irep, 1)%ri_data, matrix_ks_kp, ehfx, &
     945              :                                   rho_ao=rho_ao_kp, geometry_did_change=s_mstruct_changed, &
     946          170 :                                   nspins=nspins, hf_fraction=x_data(irep, 1)%general_parameter%fraction)
     947              : 
     948              :          ELSE
     949              : 
     950         7920 :             DO ispin = 1, mspin
     951              :                CALL integrate_four_center(qs_env, x_data, matrix_ks_kp, eh1, rho_ao_kp, hfx_sections, para_env, &
     952         3960 :                                           s_mstruct_changed, irep, distribute_fock_matrix, ispin=ispin)
     953         7920 :                ehfx = ehfx + eh1
     954              :             END DO
     955              : 
     956              :          END IF
     957              :       END DO
     958              : 
     959              :       ! Export energy
     960         4130 :       IF (PRESENT(ex)) ex = ehfx
     961              : 
     962         4130 :       CALL timestop(handle)
     963              : 
     964         4130 :    END SUBROUTINE hfx_matrix
     965              : 
     966              : ! **************************************************************************************************
     967              : !> \brief ...
     968              : !> \param qs_env ...
     969              : !> \param p_env ...
     970              : ! **************************************************************************************************
     971        10316 :    SUBROUTINE apply_xc_admm(qs_env, p_env)
     972              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     973              :       TYPE(qs_p_env_type)                                :: p_env
     974              : 
     975              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'apply_xc_admm'
     976              : 
     977              :       CHARACTER(LEN=default_string_length)               :: basis_type
     978              :       INTEGER                                            :: handle, ispin, ns, nspins
     979              :       REAL(KIND=dp)                                      :: alpha
     980              :       TYPE(admm_type), POINTER                           :: admm_env
     981              :       TYPE(dbcsr_p_type)                                 :: xcmat
     982        10316 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     983        10316 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ksmat, psmat
     984              :       TYPE(dft_control_type), POINTER                    :: dft_control
     985              :       TYPE(linres_control_type), POINTER                 :: linres_control
     986              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     987              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     988        10316 :          POINTER                                         :: sab_aux_fit
     989              :       TYPE(pw_env_type), POINTER                         :: pw_env
     990              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     991        10316 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_xc, v_xc_tau
     992        10316 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: kind_set
     993              :       TYPE(qs_kpp1_env_type), POINTER                    :: kpp1_env
     994              :       TYPE(qs_rho_type), POINTER                         :: rho_aux
     995        10316 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho1_atom_set, rho_atom_set
     996              :       TYPE(section_vals_type), POINTER                   :: xc_section
     997              :       TYPE(task_list_type), POINTER                      :: task_list
     998              : 
     999        10316 :       CALL timeset(routineN, handle)
    1000              : 
    1001        10316 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
    1002              : 
    1003        10316 :       IF (dft_control%do_admm) THEN
    1004         2290 :          CALL get_qs_env(qs_env, admm_env=admm_env)
    1005         2290 :          IF (admm_env%aux_exch_func == do_admm_aux_exch_func_none) THEN
    1006              :             ! nothing to do
    1007              :          ELSE
    1008         1382 :             CALL get_qs_env(qs_env=qs_env, linres_control=linres_control)
    1009         1382 :             CPASSERT(.NOT. dft_control%qs_control%lrigpw)
    1010         1382 :             CPASSERT(.NOT. linres_control%lr_triplet)
    1011              : 
    1012         1382 :             nspins = dft_control%nspins
    1013              : 
    1014              :             ! AUX basis contribution
    1015         1382 :             CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
    1016         1382 :             CPASSERT(ASSOCIATED(pw_env))
    1017         1382 :             CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
    1018              :             ! calculate the xc potential
    1019         1382 :             CALL get_admm_env(admm_env, matrix_s_aux_fit=matrix_s)
    1020         1382 :             ALLOCATE (xcmat%matrix)
    1021         1382 :             CALL dbcsr_create(xcmat%matrix, template=matrix_s(1)%matrix)
    1022              : 
    1023         1382 :             NULLIFY (v_xc, v_xc_tau)
    1024         1382 :             CALL get_admm_env(admm_env, rho_aux_fit=rho_aux)
    1025         1382 :             xc_section => admm_env%xc_section_aux
    1026         1382 :             kpp1_env => p_env%kpp1_env
    1027              : 
    1028         1382 :             NULLIFY (rho_atom_set, rho1_atom_set)
    1029         1382 :             basis_type = "AUX_FIT"
    1030         1382 :             CALL get_qs_env(qs_env, para_env=para_env, qs_kind_set=kind_set)
    1031         1382 :             CALL get_admm_env(admm_env, task_list_aux_fit=task_list)
    1032         1382 :             IF (admm_env%do_gapw) THEN
    1033          432 :                kind_set => admm_env%admm_gapw_env%admm_kind_set
    1034              :                CALL prepare_gapw_den(qs_env, local_rho_set=p_env%local_rho_set_admm, &
    1035          432 :                                      do_rho0=.FALSE., kind_set_external=kind_set)
    1036          432 :                rho_atom_set => admm_env%admm_gapw_env%local_rho_set%rho_atom_set
    1037          432 :                rho1_atom_set => p_env%local_rho_set_admm%rho_atom_set
    1038          432 :                basis_type = "AUX_FIT_SOFT"
    1039          432 :                task_list => admm_env%admm_gapw_env%task_list
    1040              :             END IF
    1041              : 
    1042              :             CALL qs_fxc_apply(qs_env, kpp1_env%deriv_set_admm, kpp1_env%rho_set_admm, p_env%rho1_admm, &
    1043              :                               rho_atom_set, xc_section, admm_env%do_gapw, v_xc, v_xc_tau, rho1_atom_set, &
    1044         1382 :                               kind_set_external=kind_set)
    1045         1382 :             IF (ASSOCIATED(v_xc_tau)) THEN
    1046            0 :                CPABORT("Meta-GGA ADMM functionals not yet supported!")
    1047              :             END IF
    1048              : 
    1049         1382 :             alpha = 1.0_dp
    1050         1382 :             IF (nspins == 1) alpha = 2.0_dp
    1051              : 
    1052         2884 :             DO ispin = 1, nspins
    1053         1502 :                CALL pw_scale(v_xc(ispin), v_xc(ispin)%pw_grid%dvol)
    1054         1502 :                CALL dbcsr_copy(xcmat%matrix, matrix_s(1)%matrix)
    1055         1502 :                CALL dbcsr_set(xcmat%matrix, 0.0_dp)
    1056              :                CALL integrate_v_rspace(v_rspace=v_xc(ispin), hmat=xcmat, qs_env=qs_env, &
    1057              :                                        calculate_forces=.FALSE., basis_type=basis_type, &
    1058         1502 :                                        task_list_external=task_list)
    1059         2884 :                CALL dbcsr_add(p_env%kpp1_admm(ispin)%matrix, xcmat%matrix, 1.0_dp, alpha)
    1060              :             END DO
    1061              : 
    1062         1382 :             IF (admm_env%do_gapw) THEN
    1063          432 :                CALL get_admm_env(admm_env, sab_aux_fit=sab_aux_fit)
    1064          432 :                ns = SIZE(p_env%kpp1_admm)
    1065          432 :                ksmat(1:ns, 1:1) => p_env%kpp1_admm(1:ns)
    1066          432 :                psmat(1:ns, 1:1) => p_env%p1_admm(1:ns)
    1067              :                CALL update_ks_atom(qs_env, ksmat, psmat, forces=.FALSE., tddft=.TRUE., &
    1068              :                                    rho_atom_external=p_env%local_rho_set_admm%rho_atom_set, &
    1069              :                                    kind_set_external=admm_env%admm_gapw_env%admm_kind_set, &
    1070              :                                    oce_external=admm_env%admm_gapw_env%oce, &
    1071          432 :                                    sab_external=sab_aux_fit)
    1072              :             END IF
    1073              : 
    1074         2884 :             DO ispin = 1, nspins
    1075         2884 :                CALL auxbas_pw_pool%give_back_pw(v_xc(ispin))
    1076              :             END DO
    1077         1382 :             DEALLOCATE (v_xc)
    1078         1382 :             CALL dbcsr_deallocate_matrix(xcmat%matrix)
    1079              : 
    1080              :          END IF
    1081              :       END IF
    1082              : 
    1083        10316 :       CALL timestop(handle)
    1084              : 
    1085        10316 :    END SUBROUTINE apply_xc_admm
    1086              : 
    1087              : END MODULE qs_linres_kernel
        

Generated by: LCOV version 2.0-1