LCOV - code coverage report
Current view: top level - src - qs_tddfpt2_forces.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:b4bd748) Lines: 577 601 96.0 %
Date: 2025-03-09 07:56:22 Functions: 9 9 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : MODULE qs_tddfpt2_forces
       9             :    USE admm_types,                      ONLY: admm_type,&
      10             :                                               get_admm_env
      11             :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      12             :                                               get_atomic_kind,&
      13             :                                               get_atomic_kind_set
      14             :    USE bibliography,                    ONLY: Sertcan2024,&
      15             :                                               cite_reference
      16             :    USE cp_control_types,                ONLY: dft_control_type,&
      17             :                                               tddfpt2_control_type
      18             :    USE cp_dbcsr_api,                    ONLY: &
      19             :         dbcsr_add, dbcsr_complete_redistribute, dbcsr_copy, dbcsr_create, dbcsr_p_type, &
      20             :         dbcsr_release, dbcsr_scale, dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric
      21             :    USE cp_dbcsr_contrib,                ONLY: dbcsr_dot
      22             :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      23             :    USE cp_dbcsr_operations,             ONLY: copy_dbcsr_to_fm,&
      24             :                                               copy_fm_to_dbcsr,&
      25             :                                               cp_dbcsr_plus_fm_fm_t,&
      26             :                                               cp_dbcsr_sm_fm_multiply,&
      27             :                                               dbcsr_allocate_matrix_set,&
      28             :                                               dbcsr_deallocate_matrix_set
      29             :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      30             :                                               cp_fm_struct_release,&
      31             :                                               cp_fm_struct_type
      32             :    USE cp_fm_types,                     ONLY: cp_fm_copy_general,&
      33             :                                               cp_fm_create,&
      34             :                                               cp_fm_get_info,&
      35             :                                               cp_fm_release,&
      36             :                                               cp_fm_set_all,&
      37             :                                               cp_fm_type
      38             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      39             :                                               cp_logger_get_default_unit_nr,&
      40             :                                               cp_logger_type
      41             :    USE exstates_types,                  ONLY: excited_energy_type,&
      42             :                                               exstate_potential_release
      43             :    USE hartree_local_methods,           ONLY: Vh_1c_gg_integrals,&
      44             :                                               init_coulomb_local
      45             :    USE hartree_local_types,             ONLY: hartree_local_create,&
      46             :                                               hartree_local_release,&
      47             :                                               hartree_local_type
      48             :    USE hfx_energy_potential,            ONLY: integrate_four_center
      49             :    USE hfx_ri,                          ONLY: hfx_ri_update_ks
      50             :    USE hfx_types,                       ONLY: hfx_type
      51             :    USE input_constants,                 ONLY: do_admm_aux_exch_func_none,&
      52             :                                               oe_shift,&
      53             :                                               tddfpt_kernel_full,&
      54             :                                               tddfpt_kernel_none,&
      55             :                                               tddfpt_kernel_stda
      56             :    USE input_section_types,             ONLY: section_get_lval,&
      57             :                                               section_vals_get,&
      58             :                                               section_vals_get_subs_vals,&
      59             :                                               section_vals_type,&
      60             :                                               section_vals_val_get
      61             :    USE kinds,                           ONLY: default_string_length,&
      62             :                                               dp
      63             :    USE message_passing,                 ONLY: mp_para_env_type
      64             :    USE mulliken,                        ONLY: ao_charges
      65             :    USE parallel_gemm_api,               ONLY: parallel_gemm
      66             :    USE particle_types,                  ONLY: particle_type
      67             :    USE pw_env_types,                    ONLY: pw_env_get,&
      68             :                                               pw_env_type
      69             :    USE pw_methods,                      ONLY: pw_axpy,&
      70             :                                               pw_scale,&
      71             :                                               pw_transfer,&
      72             :                                               pw_zero
      73             :    USE pw_poisson_methods,              ONLY: pw_poisson_solve
      74             :    USE pw_poisson_types,                ONLY: pw_poisson_type
      75             :    USE pw_pool_types,                   ONLY: pw_pool_type
      76             :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      77             :                                               pw_r3d_rs_type
      78             :    USE qs_collocate_density,            ONLY: calculate_rho_elec
      79             :    USE qs_density_matrices,             ONLY: calculate_wx_matrix,&
      80             :                                               calculate_xwx_matrix
      81             :    USE qs_environment_types,            ONLY: get_qs_env,&
      82             :                                               qs_environment_type,&
      83             :                                               set_qs_env
      84             :    USE qs_force_types,                  ONLY: allocate_qs_force,&
      85             :                                               deallocate_qs_force,&
      86             :                                               qs_force_type,&
      87             :                                               sum_qs_force,&
      88             :                                               total_qs_force,&
      89             :                                               zero_qs_force
      90             :    USE qs_fxc,                          ONLY: qs_fxc_analytic,&
      91             :                                               qs_fxc_fdiff
      92             :    USE qs_gapw_densities,               ONLY: prepare_gapw_den
      93             :    USE qs_integrate_potential,          ONLY: integrate_v_rspace
      94             :    USE qs_kernel_types,                 ONLY: kernel_env_type
      95             :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      96             :                                               get_qs_kind_set,&
      97             :                                               qs_kind_type
      98             :    USE qs_ks_atom,                      ONLY: update_ks_atom
      99             :    USE qs_ks_reference,                 ONLY: ks_ref_potential,&
     100             :                                               ks_ref_potential_atom
     101             :    USE qs_ks_types,                     ONLY: qs_ks_env_type
     102             :    USE qs_local_rho_types,              ONLY: local_rho_set_create,&
     103             :                                               local_rho_set_release,&
     104             :                                               local_rho_type
     105             :    USE qs_mo_types,                     ONLY: get_mo_set,&
     106             :                                               mo_set_type
     107             :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
     108             :    USE qs_oce_types,                    ONLY: oce_matrix_type
     109             :    USE qs_overlap,                      ONLY: build_overlap_matrix
     110             :    USE qs_rho0_ggrid,                   ONLY: integrate_vhg0_rspace,&
     111             :                                               rho0_s_grid_create
     112             :    USE qs_rho0_methods,                 ONLY: init_rho0
     113             :    USE qs_rho0_types,                   ONLY: get_rho0_mpole
     114             :    USE qs_rho_atom_methods,             ONLY: allocate_rho_atom_internals,&
     115             :                                               calculate_rho_atom_coeff
     116             :    USE qs_rho_atom_types,               ONLY: rho_atom_type
     117             :    USE qs_rho_types,                    ONLY: qs_rho_create,&
     118             :                                               qs_rho_get,&
     119             :                                               qs_rho_set,&
     120             :                                               qs_rho_type
     121             :    USE qs_tddfpt2_fhxc_forces,          ONLY: fhxc_force,&
     122             :                                               stda_force
     123             :    USE qs_tddfpt2_subgroups,            ONLY: tddfpt_subgroup_env_type
     124             :    USE qs_tddfpt2_types,                ONLY: tddfpt_ground_state_mos,&
     125             :                                               tddfpt_work_matrices
     126             :    USE qs_vxc_atom,                     ONLY: calculate_xc_2nd_deriv_atom
     127             :    USE task_list_types,                 ONLY: task_list_type
     128             :    USE xtb_ehess,                       ONLY: xtb_coulomb_hessian
     129             :    USE xtb_types,                       ONLY: get_xtb_atom_param,&
     130             :                                               xtb_atom_type
     131             : #include "./base/base_uses.f90"
     132             : 
     133             :    IMPLICIT NONE
     134             : 
     135             :    PRIVATE
     136             : 
     137             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_tddfpt2_forces'
     138             : 
     139             :    PUBLIC :: tddfpt_forces_main
     140             : 
     141             : ! **************************************************************************************************
     142             : 
     143             : CONTAINS
     144             : 
     145             : ! **************************************************************************************************
     146             : !> \brief Perform TDDFPT gradient calculation.
     147             : !> \param qs_env  Quickstep environment
     148             : !> \param gs_mos ...
     149             : !> \param ex_env ...
     150             : !> \param kernel_env ...
     151             : !> \param sub_env ...
     152             : !> \param work_matrices ...
     153             : !> \par History
     154             : !>    * 10.2022 created JHU
     155             : ! **************************************************************************************************
     156         568 :    SUBROUTINE tddfpt_forces_main(qs_env, gs_mos, ex_env, kernel_env, sub_env, work_matrices)
     157             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     158             :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
     159             :          POINTER                                         :: gs_mos
     160             :       TYPE(excited_energy_type), POINTER                 :: ex_env
     161             :       TYPE(kernel_env_type)                              :: kernel_env
     162             :       TYPE(tddfpt_subgroup_env_type)                     :: sub_env
     163             :       TYPE(tddfpt_work_matrices)                         :: work_matrices
     164             : 
     165             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_forces_main'
     166             : 
     167             :       INTEGER                                            :: handle, ispin, nspins
     168             :       TYPE(admm_type), POINTER                           :: admm_env
     169             :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
     170         568 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_pe_asymm, matrix_pe_symm, &
     171         568 :                                                             matrix_s, matrix_s_aux_fit
     172             :       TYPE(dft_control_type), POINTER                    :: dft_control
     173             :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
     174             : 
     175         568 :       CALL timeset(routineN, handle)
     176             : 
     177         568 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     178             : 
     179         568 :       IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) CALL cite_reference(Sertcan2024)
     180             : 
     181         568 :       nspins = dft_control%nspins
     182         568 :       tddfpt_control => dft_control%tddfpt2_control
     183             :       ! rhs of linres equation
     184         568 :       IF (ASSOCIATED(ex_env%cpmos)) THEN
     185         504 :          DO ispin = 1, SIZE(ex_env%cpmos)
     186         504 :             CALL cp_fm_release(ex_env%cpmos(ispin))
     187             :          END DO
     188         230 :          DEALLOCATE (ex_env%cpmos)
     189             :       END IF
     190        2368 :       ALLOCATE (ex_env%cpmos(nspins))
     191        1232 :       DO ispin = 1, nspins
     192         664 :          CALL cp_fm_get_info(matrix=ex_env%evect(ispin), matrix_struct=matrix_struct)
     193         664 :          CALL cp_fm_create(ex_env%cpmos(ispin), matrix_struct)
     194        1232 :          CALL cp_fm_set_all(ex_env%cpmos(ispin), 0.0_dp)
     195             :       END DO
     196         568 :       CALL get_qs_env(qs_env=qs_env, matrix_s=matrix_s)
     197         568 :       NULLIFY (matrix_pe_asymm, matrix_pe_symm)
     198         568 :       CALL dbcsr_allocate_matrix_set(ex_env%matrix_pe, nspins)
     199         568 :       CALL dbcsr_allocate_matrix_set(matrix_pe_symm, nspins)
     200         568 :       CALL dbcsr_allocate_matrix_set(matrix_pe_asymm, nspins)
     201        1232 :       DO ispin = 1, nspins
     202         664 :          ALLOCATE (ex_env%matrix_pe(ispin)%matrix)
     203         664 :          CALL dbcsr_create(ex_env%matrix_pe(ispin)%matrix, template=matrix_s(1)%matrix)
     204         664 :          CALL dbcsr_copy(ex_env%matrix_pe(ispin)%matrix, matrix_s(1)%matrix)
     205         664 :          CALL dbcsr_set(ex_env%matrix_pe(ispin)%matrix, 0.0_dp)
     206             : 
     207         664 :          ALLOCATE (matrix_pe_symm(ispin)%matrix)
     208         664 :          CALL dbcsr_create(matrix_pe_symm(ispin)%matrix, template=matrix_s(1)%matrix)
     209         664 :          CALL dbcsr_copy(matrix_pe_symm(ispin)%matrix, ex_env%matrix_pe(ispin)%matrix)
     210             : 
     211         664 :          ALLOCATE (matrix_pe_asymm(ispin)%matrix)
     212             :          CALL dbcsr_create(matrix_pe_asymm(ispin)%matrix, template=matrix_s(1)%matrix, &
     213         664 :                            matrix_type=dbcsr_type_antisymmetric)
     214         664 :          CALL dbcsr_complete_redistribute(ex_env%matrix_pe(ispin)%matrix, matrix_pe_asymm(ispin)%matrix)
     215             : 
     216             :          CALL tddfpt_resvec1(ex_env%evect(ispin), gs_mos(ispin)%mos_occ, &
     217        1232 :                              matrix_s(1)%matrix, ex_env%matrix_pe(ispin)%matrix)
     218             :       END DO
     219             :       !
     220             :       ! ground state ADMM!
     221         568 :       IF (dft_control%do_admm) THEN
     222         128 :          CALL get_qs_env(qs_env, admm_env=admm_env)
     223         128 :          CALL get_admm_env(admm_env, matrix_s_aux_fit=matrix_s_aux_fit)
     224         128 :          CALL dbcsr_allocate_matrix_set(ex_env%matrix_pe_admm, nspins)
     225         276 :          DO ispin = 1, nspins
     226         148 :             ALLOCATE (ex_env%matrix_pe_admm(ispin)%matrix)
     227         148 :             CALL dbcsr_create(ex_env%matrix_pe_admm(ispin)%matrix, template=matrix_s_aux_fit(1)%matrix)
     228         148 :             CALL dbcsr_copy(ex_env%matrix_pe_admm(ispin)%matrix, matrix_s_aux_fit(1)%matrix)
     229         148 :             CALL dbcsr_set(ex_env%matrix_pe_admm(ispin)%matrix, 0.0_dp)
     230             :             CALL tddfpt_resvec1_admm(ex_env%matrix_pe(ispin)%matrix, &
     231         276 :                                      admm_env, ex_env%matrix_pe_admm(ispin)%matrix)
     232             :          END DO
     233             :       END IF
     234             :       !
     235         568 :       CALL dbcsr_allocate_matrix_set(ex_env%matrix_hz, nspins)
     236        1232 :       DO ispin = 1, nspins
     237         664 :          ALLOCATE (ex_env%matrix_hz(ispin)%matrix)
     238         664 :          CALL dbcsr_create(ex_env%matrix_hz(ispin)%matrix, template=matrix_s(1)%matrix)
     239         664 :          CALL dbcsr_copy(ex_env%matrix_hz(ispin)%matrix, matrix_s(1)%matrix)
     240        1232 :          CALL dbcsr_set(ex_env%matrix_hz(ispin)%matrix, 0.0_dp)
     241             :       END DO
     242         568 :       IF (dft_control%qs_control%xtb) THEN
     243          16 :          CALL tddfpt_resvec2_xtb(qs_env, ex_env%matrix_pe, gs_mos, ex_env%matrix_hz, ex_env%cpmos)
     244             :       ELSE
     245             :          CALL tddfpt_resvec2(qs_env, ex_env%matrix_pe, ex_env%matrix_pe_admm, &
     246         552 :                              gs_mos, ex_env%matrix_hz, ex_env%cpmos)
     247             :       END IF
     248             :       !
     249         568 :       CALL dbcsr_allocate_matrix_set(ex_env%matrix_px1, nspins)
     250         568 :       CALL dbcsr_allocate_matrix_set(ex_env%matrix_px1_asymm, nspins)
     251        1232 :       DO ispin = 1, nspins
     252         664 :          ALLOCATE (ex_env%matrix_px1(ispin)%matrix)
     253         664 :          CALL dbcsr_create(ex_env%matrix_px1(ispin)%matrix, template=matrix_s(1)%matrix)
     254         664 :          CALL dbcsr_copy(ex_env%matrix_px1(ispin)%matrix, matrix_s(1)%matrix)
     255         664 :          CALL dbcsr_set(ex_env%matrix_px1(ispin)%matrix, 0.0_dp)
     256             : 
     257         664 :          ALLOCATE (ex_env%matrix_px1_asymm(ispin)%matrix)
     258             :          CALL dbcsr_create(ex_env%matrix_px1_asymm(ispin)%matrix, template=matrix_s(1)%matrix, &
     259         664 :                            matrix_type=dbcsr_type_antisymmetric)
     260        1232 :          CALL dbcsr_complete_redistribute(ex_env%matrix_px1(ispin)%matrix, ex_env%matrix_px1_asymm(ispin)%matrix)
     261             :       END DO
     262             :       ! Kernel ADMM
     263         568 :       IF (tddfpt_control%do_admm) THEN
     264          64 :          CALL get_qs_env(qs_env, admm_env=admm_env)
     265          64 :          CALL get_admm_env(admm_env, matrix_s_aux_fit=matrix_s_aux_fit)
     266          64 :          CALL dbcsr_allocate_matrix_set(ex_env%matrix_px1_admm, nspins)
     267          64 :          CALL dbcsr_allocate_matrix_set(ex_env%matrix_px1_admm_asymm, nspins)
     268         132 :          DO ispin = 1, nspins
     269          68 :             ALLOCATE (ex_env%matrix_px1_admm(ispin)%matrix)
     270          68 :             CALL dbcsr_create(ex_env%matrix_px1_admm(ispin)%matrix, template=matrix_s_aux_fit(1)%matrix)
     271          68 :             CALL dbcsr_copy(ex_env%matrix_px1_admm(ispin)%matrix, matrix_s_aux_fit(1)%matrix)
     272          68 :             CALL dbcsr_set(ex_env%matrix_px1_admm(ispin)%matrix, 0.0_dp)
     273             : 
     274          68 :             ALLOCATE (ex_env%matrix_px1_admm_asymm(ispin)%matrix)
     275             :             CALL dbcsr_create(ex_env%matrix_px1_admm_asymm(ispin)%matrix, template=matrix_s_aux_fit(1)%matrix, &
     276          68 :                               matrix_type=dbcsr_type_antisymmetric)
     277             :             CALL dbcsr_complete_redistribute(ex_env%matrix_px1_admm(ispin)%matrix, &
     278         132 :                                              ex_env%matrix_px1_admm_asymm(ispin)%matrix)
     279             :          END DO
     280             :       END IF
     281             :       ! TDA forces
     282         568 :       CALL tddfpt_forces(qs_env, ex_env, gs_mos, kernel_env, sub_env, work_matrices)
     283             :       ! Rotate res vector cpmos into original frame of occupied orbitals
     284         568 :       CALL tddfpt_resvec3(qs_env, ex_env%cpmos, work_matrices)
     285             : 
     286         568 :       CALL dbcsr_deallocate_matrix_set(matrix_pe_symm)
     287         568 :       CALL dbcsr_deallocate_matrix_set(matrix_pe_asymm)
     288             : 
     289         568 :       CALL timestop(handle)
     290             : 
     291         568 :    END SUBROUTINE tddfpt_forces_main
     292             : 
     293             : ! **************************************************************************************************
     294             : !> \brief Calculate direct tddft forces
     295             : !> \param qs_env ...
     296             : !> \param ex_env ...
     297             : !> \param gs_mos ...
     298             : !> \param kernel_env ...
     299             : !> \param sub_env ...
     300             : !> \param work_matrices ...
     301             : !> \par History
     302             : !>    * 01.2020 screated [JGH]
     303             : ! **************************************************************************************************
     304         568 :    SUBROUTINE tddfpt_forces(qs_env, ex_env, gs_mos, kernel_env, sub_env, work_matrices)
     305             : 
     306             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     307             :       TYPE(excited_energy_type), POINTER                 :: ex_env
     308             :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
     309             :          POINTER                                         :: gs_mos
     310             :       TYPE(kernel_env_type), INTENT(IN)                  :: kernel_env
     311             :       TYPE(tddfpt_subgroup_env_type)                     :: sub_env
     312             :       TYPE(tddfpt_work_matrices)                         :: work_matrices
     313             : 
     314             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'tddfpt_forces'
     315             : 
     316             :       INTEGER                                            :: handle
     317         568 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: natom_of_kind
     318             :       LOGICAL                                            :: debug_forces
     319             :       REAL(KIND=dp)                                      :: ehartree, exc
     320         568 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     321             :       TYPE(dft_control_type), POINTER                    :: dft_control
     322         568 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: ks_force, td_force
     323             : 
     324         568 :       CALL timeset(routineN, handle)
     325             : 
     326             :       ! for extended debug output
     327         568 :       debug_forces = ex_env%debug_forces
     328             :       ! prepare force array
     329             :       CALL get_qs_env(qs_env, dft_control=dft_control, force=ks_force, &
     330         568 :                       atomic_kind_set=atomic_kind_set)
     331         568 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, natom_of_kind=natom_of_kind)
     332         568 :       NULLIFY (td_force)
     333         568 :       CALL allocate_qs_force(td_force, natom_of_kind)
     334         568 :       DEALLOCATE (natom_of_kind)
     335         568 :       CALL zero_qs_force(td_force)
     336         568 :       CALL set_qs_env(qs_env, force=td_force)
     337             :       !
     338         568 :       IF (dft_control%qs_control%xtb) THEN
     339             :          CALL tddfpt_force_direct(qs_env, ex_env, gs_mos, kernel_env, sub_env, &
     340          16 :                                   work_matrices, debug_forces)
     341             :       ELSE
     342             :          !
     343         552 :          CALL exstate_potential_release(ex_env)
     344             :          CALL ks_ref_potential(qs_env, ex_env%vh_rspace, ex_env%vxc_rspace, &
     345         552 :                                ex_env%vtau_rspace, ex_env%vadmm_rspace, ehartree, exc)
     346             :          CALL ks_ref_potential_atom(qs_env, ex_env%local_rho_set, ex_env%local_rho_set_admm, &
     347         552 :                                     ex_env%vh_rspace)
     348             :          CALL tddfpt_force_direct(qs_env, ex_env, gs_mos, kernel_env, sub_env, &
     349         552 :                                   work_matrices, debug_forces)
     350             :       END IF
     351             :       !
     352             :       ! add TD and KS forces
     353         568 :       CALL get_qs_env(qs_env, force=td_force)
     354         568 :       CALL sum_qs_force(ks_force, td_force)
     355         568 :       CALL set_qs_env(qs_env, force=ks_force)
     356         568 :       CALL deallocate_qs_force(td_force)
     357             :       !
     358         568 :       CALL timestop(handle)
     359             : 
     360         568 :    END SUBROUTINE tddfpt_forces
     361             : 
     362             : ! **************************************************************************************************
     363             : !> \brief Calculate direct tddft forces
     364             : !> \param qs_env ...
     365             : !> \param ex_env ...
     366             : !> \param gs_mos ...
     367             : !> \param kernel_env ...
     368             : !> \param sub_env ...
     369             : !> \param work_matrices ...
     370             : !> \param debug_forces ...
     371             : !> \par History
     372             : !>    * 01.2020 screated [JGH]
     373             : ! **************************************************************************************************
     374         568 :    SUBROUTINE tddfpt_force_direct(qs_env, ex_env, gs_mos, kernel_env, sub_env, work_matrices, &
     375             :                                   debug_forces)
     376             : 
     377             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     378             :       TYPE(excited_energy_type), POINTER                 :: ex_env
     379             :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
     380             :          POINTER                                         :: gs_mos
     381             :       TYPE(kernel_env_type), INTENT(IN)                  :: kernel_env
     382             :       TYPE(tddfpt_subgroup_env_type)                     :: sub_env
     383             :       TYPE(tddfpt_work_matrices)                         :: work_matrices
     384             :       LOGICAL                                            :: debug_forces
     385             : 
     386             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_force_direct'
     387             : 
     388             :       INTEGER                                            :: handle, iounit, ispin, natom, norb, &
     389             :                                                             nspins
     390             :       REAL(KIND=dp)                                      :: evalue
     391         568 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: ftot1, ftot2
     392             :       REAL(KIND=dp), DIMENSION(3)                        :: fodeb
     393         568 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     394         568 :       TYPE(cp_fm_type), DIMENSION(:), POINTER            :: evect
     395             :       TYPE(cp_logger_type), POINTER                      :: logger
     396         568 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks, matrix_s, matrix_wx1, &
     397         568 :                                                             matrix_wz, scrm
     398             :       TYPE(dft_control_type), POINTER                    :: dft_control
     399             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     400             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     401         568 :          POINTER                                         :: sab_orb
     402         568 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     403             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     404             :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
     405             : 
     406         568 :       CALL timeset(routineN, handle)
     407             : 
     408         568 :       logger => cp_get_default_logger()
     409         568 :       IF (logger%para_env%is_source()) THEN
     410         284 :          iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     411             :       ELSE
     412             :          iounit = -1
     413             :       END IF
     414             : 
     415         568 :       evect => ex_env%evect
     416             : 
     417             :       CALL get_qs_env(qs_env=qs_env, ks_env=ks_env, para_env=para_env, &
     418         568 :                       sab_orb=sab_orb, dft_control=dft_control, force=force)
     419         568 :       NULLIFY (tddfpt_control)
     420         568 :       tddfpt_control => dft_control%tddfpt2_control
     421         568 :       nspins = dft_control%nspins
     422             : 
     423         568 :       IF (debug_forces) THEN
     424          58 :          CALL get_qs_env(qs_env, natom=natom, atomic_kind_set=atomic_kind_set)
     425         174 :          ALLOCATE (ftot1(3, natom))
     426          58 :          CALL total_qs_force(ftot1, force, atomic_kind_set)
     427             :       END IF
     428             : 
     429         568 :       CALL tddfpt_kernel_force(qs_env, ex_env, gs_mos, kernel_env, sub_env, work_matrices, debug_forces)
     430             : 
     431             :       ! Overlap matrix
     432         568 :       matrix_wx1 => ex_env%matrix_wx1
     433         568 :       CALL get_qs_env(qs_env=qs_env, matrix_s=matrix_s, matrix_ks=matrix_ks)
     434         568 :       NULLIFY (matrix_wz)
     435         568 :       CALL dbcsr_allocate_matrix_set(matrix_wz, nspins)
     436        1232 :       DO ispin = 1, nspins
     437         664 :          ALLOCATE (matrix_wz(ispin)%matrix)
     438         664 :          CALL dbcsr_create(matrix=matrix_wz(ispin)%matrix, template=matrix_s(1)%matrix)
     439         664 :          CALL cp_dbcsr_alloc_block_from_nbl(matrix_wz(ispin)%matrix, sab_orb)
     440         664 :          CALL dbcsr_set(matrix_wz(ispin)%matrix, 0.0_dp)
     441         664 :          CALL cp_fm_get_info(gs_mos(ispin)%mos_occ, ncol_global=norb)
     442         664 :          CALL cp_dbcsr_plus_fm_fm_t(matrix_wz(ispin)%matrix, matrix_v=evect(ispin), ncol=norb)
     443         664 :          evalue = ex_env%evalue
     444         664 :          IF (tddfpt_control%oe_corr == oe_shift) THEN
     445           4 :             evalue = ex_env%evalue - tddfpt_control%ev_shift
     446             :          END IF
     447         664 :          CALL dbcsr_scale(matrix_wz(ispin)%matrix, evalue)
     448             :          CALL calculate_wx_matrix(gs_mos(ispin)%mos_occ, evect(ispin), matrix_ks(ispin)%matrix, &
     449        1896 :                                   matrix_wz(ispin)%matrix)
     450             :       END DO
     451         568 :       IF (nspins == 2) THEN
     452             :          CALL dbcsr_add(matrix_wz(1)%matrix, matrix_wz(2)%matrix, &
     453          96 :                         alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     454             :       END IF
     455         568 :       NULLIFY (scrm)
     456         742 :       IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
     457             :       CALL build_overlap_matrix(ks_env, matrix_s=scrm, &
     458             :                                 matrix_name="OVERLAP MATRIX", &
     459             :                                 basis_type_a="ORB", basis_type_b="ORB", &
     460             :                                 sab_nl=sab_orb, calculate_forces=.TRUE., &
     461         568 :                                 matrix_p=matrix_wz(1)%matrix)
     462         568 :       CALL dbcsr_deallocate_matrix_set(scrm)
     463         568 :       CALL dbcsr_deallocate_matrix_set(matrix_wz)
     464         568 :       IF (debug_forces) THEN
     465         232 :          fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
     466          58 :          CALL para_env%sum(fodeb)
     467          58 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wx*dS ", fodeb
     468             :       END IF
     469             : 
     470             :       ! Overlap matrix
     471         568 :       CALL get_qs_env(qs_env=qs_env, matrix_s=matrix_s, matrix_ks=matrix_ks)
     472         568 :       NULLIFY (matrix_wz)
     473         568 :       CALL dbcsr_allocate_matrix_set(matrix_wz, nspins)
     474        1232 :       DO ispin = 1, nspins
     475         664 :          ALLOCATE (matrix_wz(ispin)%matrix)
     476         664 :          CALL dbcsr_create(matrix=matrix_wz(ispin)%matrix, template=matrix_s(1)%matrix)
     477         664 :          CALL cp_dbcsr_alloc_block_from_nbl(matrix_wz(ispin)%matrix, sab_orb)
     478         664 :          CALL dbcsr_set(matrix_wz(ispin)%matrix, 0.0_dp)
     479         664 :          CALL cp_fm_get_info(gs_mos(ispin)%mos_occ, ncol_global=norb)
     480         664 :          evalue = ex_env%evalue
     481         664 :          IF (tddfpt_control%oe_corr == oe_shift) THEN
     482           4 :             evalue = ex_env%evalue - tddfpt_control%ev_shift
     483             :          END IF
     484             :          CALL calculate_xwx_matrix(gs_mos(ispin)%mos_occ, evect(ispin), matrix_s(1)%matrix, &
     485        1896 :                                    matrix_ks(ispin)%matrix, matrix_wz(ispin)%matrix, evalue)
     486             :       END DO
     487         568 :       IF (nspins == 2) THEN
     488             :          CALL dbcsr_add(matrix_wz(1)%matrix, matrix_wz(2)%matrix, &
     489          96 :                         alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     490             :       END IF
     491         568 :       NULLIFY (scrm)
     492         742 :       IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
     493             :       CALL build_overlap_matrix(ks_env, matrix_s=scrm, &
     494             :                                 matrix_name="OVERLAP MATRIX", &
     495             :                                 basis_type_a="ORB", basis_type_b="ORB", &
     496             :                                 sab_nl=sab_orb, calculate_forces=.TRUE., &
     497         568 :                                 matrix_p=matrix_wz(1)%matrix)
     498         568 :       CALL dbcsr_deallocate_matrix_set(scrm)
     499         568 :       CALL dbcsr_deallocate_matrix_set(matrix_wz)
     500         568 :       IF (debug_forces) THEN
     501         232 :          fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
     502          58 :          CALL para_env%sum(fodeb)
     503          58 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: xWx*dS ", fodeb
     504             :       END IF
     505             : 
     506             :       ! Overlap matrix
     507         568 :       IF (ASSOCIATED(matrix_wx1)) THEN
     508         500 :          IF (nspins == 2) THEN
     509             :             CALL dbcsr_add(matrix_wx1(1)%matrix, matrix_wx1(2)%matrix, &
     510          96 :                            alpha_scalar=0.5_dp, beta_scalar=0.5_dp)
     511             :          END IF
     512         500 :          NULLIFY (scrm)
     513         656 :          IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
     514             :          CALL build_overlap_matrix(ks_env, matrix_s=scrm, &
     515             :                                    matrix_name="OVERLAP MATRIX", &
     516             :                                    basis_type_a="ORB", basis_type_b="ORB", &
     517             :                                    sab_nl=sab_orb, calculate_forces=.TRUE., &
     518         500 :                                    matrix_p=matrix_wx1(1)%matrix)
     519         500 :          CALL dbcsr_deallocate_matrix_set(scrm)
     520         500 :          IF (debug_forces) THEN
     521         208 :             fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
     522          52 :             CALL para_env%sum(fodeb)
     523          52 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: WK*dS ", fodeb
     524             :          END IF
     525             :       END IF
     526             : 
     527         568 :       IF (debug_forces) THEN
     528         174 :          ALLOCATE (ftot2(3, natom))
     529          58 :          CALL total_qs_force(ftot2, force, atomic_kind_set)
     530         232 :          fodeb(1:3) = ftot2(1:3, 1) - ftot1(1:3, 1)
     531          58 :          CALL para_env%sum(fodeb)
     532          58 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T30,3F16.8)") "DEBUG:: Excitation Force", fodeb
     533          58 :          DEALLOCATE (ftot1, ftot2)
     534             :       END IF
     535             : 
     536         568 :       CALL timestop(handle)
     537             : 
     538        1136 :    END SUBROUTINE tddfpt_force_direct
     539             : 
     540             : ! **************************************************************************************************
     541             : !> \brief ...
     542             : !> \param evect ...
     543             : !> \param mos_occ ...
     544             : !> \param matrix_s ...
     545             : !> \param matrix_pe ...
     546             : ! **************************************************************************************************
     547        3320 :    SUBROUTINE tddfpt_resvec1(evect, mos_occ, matrix_s, matrix_pe)
     548             : 
     549             :       TYPE(cp_fm_type), INTENT(IN)                       :: evect, mos_occ
     550             :       TYPE(dbcsr_type), POINTER                          :: matrix_s, matrix_pe
     551             : 
     552             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'tddfpt_resvec1'
     553             : 
     554             :       INTEGER                                            :: handle, iounit, nao, norb
     555             :       REAL(KIND=dp)                                      :: tmp
     556             :       TYPE(cp_fm_struct_type), POINTER                   :: fmstruct, fmstruct2
     557             :       TYPE(cp_fm_type)                                   :: cxmat, xxmat
     558             :       TYPE(cp_logger_type), POINTER                      :: logger
     559             : 
     560         664 :       CALL timeset(routineN, handle)
     561             :       ! X*X^T
     562         664 :       CALL cp_fm_get_info(mos_occ, nrow_global=nao, ncol_global=norb)
     563         664 :       CALL cp_dbcsr_plus_fm_fm_t(matrix_pe, matrix_v=evect, ncol=norb)
     564             :       ! X^T*S*X
     565         664 :       CALL cp_fm_get_info(evect, matrix_struct=fmstruct)
     566         664 :       NULLIFY (fmstruct2)
     567             :       CALL cp_fm_struct_create(fmstruct=fmstruct2, template_fmstruct=fmstruct, &
     568         664 :                                nrow_global=norb, ncol_global=norb)
     569         664 :       CALL cp_fm_create(xxmat, matrix_struct=fmstruct2)
     570         664 :       CALL cp_fm_struct_release(fmstruct2)
     571         664 :       CALL cp_fm_create(cxmat, matrix_struct=fmstruct)
     572         664 :       CALL cp_dbcsr_sm_fm_multiply(matrix_s, evect, cxmat, norb, alpha=1.0_dp, beta=0.0_dp)
     573         664 :       CALL parallel_gemm('T', 'N', norb, norb, nao, 1.0_dp, cxmat, evect, 0.0_dp, xxmat)
     574         664 :       CALL parallel_gemm('N', 'N', nao, norb, norb, 1.0_dp, mos_occ, xxmat, 0.0_dp, cxmat)
     575         664 :       CALL cp_fm_release(xxmat)
     576             :       ! C*C^T*XX
     577             :       CALL cp_dbcsr_plus_fm_fm_t(matrix_pe, matrix_v=mos_occ, matrix_g=cxmat, &
     578         664 :                                  ncol=norb, alpha=-1.0_dp, symmetry_mode=1)
     579         664 :       CALL cp_fm_release(cxmat)
     580             :       !
     581             :       ! Test for Tr(Pe*S)=0
     582         664 :       CALL dbcsr_dot(matrix_pe, matrix_s, tmp)
     583         664 :       IF (ABS(tmp) > 1.e-08_dp) THEN
     584           0 :          logger => cp_get_default_logger()
     585           0 :          IF (logger%para_env%is_source()) THEN
     586           0 :             iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     587             :          ELSE
     588             :             iounit = -1
     589             :          END IF
     590           0 :          CPWARN("Electron count of excitation density matrix is non-zero.")
     591           0 :          IF (iounit > 0) THEN
     592           0 :             WRITE (iounit, "(T2,A,T61,G20.10)") "Measured electron count is ", tmp
     593           0 :             WRITE (iounit, "(T2,A,/)") REPEAT("*", 79)
     594             :          END IF
     595             :       END IF
     596             :       !
     597             : 
     598         664 :       CALL timestop(handle)
     599             : 
     600         664 :    END SUBROUTINE tddfpt_resvec1
     601             : 
     602             : ! **************************************************************************************************
     603             : !> \brief PA = A * P * A(T)
     604             : !> \param matrix_pe ...
     605             : !> \param admm_env ...
     606             : !> \param matrix_pe_admm ...
     607             : ! **************************************************************************************************
     608         148 :    SUBROUTINE tddfpt_resvec1_admm(matrix_pe, admm_env, matrix_pe_admm)
     609             : 
     610             :       TYPE(dbcsr_type), POINTER                          :: matrix_pe
     611             :       TYPE(admm_type), POINTER                           :: admm_env
     612             :       TYPE(dbcsr_type), POINTER                          :: matrix_pe_admm
     613             : 
     614             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_resvec1_admm'
     615             : 
     616             :       INTEGER                                            :: handle, nao, nao_aux
     617             : 
     618         148 :       CALL timeset(routineN, handle)
     619             :       !
     620         148 :       nao_aux = admm_env%nao_aux_fit
     621         148 :       nao = admm_env%nao_orb
     622             :       !
     623         148 :       CALL copy_dbcsr_to_fm(matrix_pe, admm_env%work_orb_orb)
     624             :       CALL parallel_gemm('N', 'N', nao_aux, nao, nao, &
     625             :                          1.0_dp, admm_env%A, admm_env%work_orb_orb, 0.0_dp, &
     626         148 :                          admm_env%work_aux_orb)
     627             :       CALL parallel_gemm('N', 'T', nao_aux, nao_aux, nao, &
     628             :                          1.0_dp, admm_env%work_aux_orb, admm_env%A, 0.0_dp, &
     629         148 :                          admm_env%work_aux_aux)
     630         148 :       CALL copy_fm_to_dbcsr(admm_env%work_aux_aux, matrix_pe_admm, keep_sparsity=.TRUE.)
     631             :       !
     632         148 :       CALL timestop(handle)
     633             : 
     634         148 :    END SUBROUTINE tddfpt_resvec1_admm
     635             : 
     636             : ! **************************************************************************************************
     637             : !> \brief ...
     638             : !> \param qs_env ...
     639             : !> \param matrix_pe ...
     640             : !> \param matrix_pe_admm ...
     641             : !> \param gs_mos ...
     642             : !> \param matrix_hz ...
     643             : !> \param cpmos ...
     644             : ! **************************************************************************************************
     645         552 :    SUBROUTINE tddfpt_resvec2(qs_env, matrix_pe, matrix_pe_admm, gs_mos, matrix_hz, cpmos)
     646             : 
     647             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     648             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_pe, matrix_pe_admm
     649             :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
     650             :          POINTER                                         :: gs_mos
     651             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_hz
     652             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT)      :: cpmos
     653             : 
     654             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'tddfpt_resvec2'
     655             : 
     656             :       CHARACTER(LEN=default_string_length)               :: basis_type
     657             :       INTEGER                                            :: handle, iounit, ispin, mspin, n_rep_hf, &
     658             :                                                             nao, nao_aux, natom, norb, nspins
     659             :       LOGICAL                                            :: deriv2_analytic, distribute_fock_matrix, &
     660             :                                                             do_hfx, gapw, gapw_xc, &
     661             :                                                             hfx_treat_lsd_in_core, &
     662             :                                                             s_mstruct_changed
     663             :       REAL(KIND=dp)                                      :: eh1, focc, rhotot, thartree
     664             :       REAL(KIND=dp), DIMENSION(2)                        :: total_rho
     665         552 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: Qlm_tot
     666             :       TYPE(admm_type), POINTER                           :: admm_env
     667         552 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     668             :       TYPE(cp_fm_type), POINTER                          :: mos
     669             :       TYPE(cp_logger_type), POINTER                      :: logger
     670         552 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: msaux
     671         552 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: mhz, mpe
     672             :       TYPE(dbcsr_type), POINTER                          :: dbwork
     673             :       TYPE(dft_control_type), POINTER                    :: dft_control
     674             :       TYPE(hartree_local_type), POINTER                  :: hartree_local
     675         552 :       TYPE(hfx_type), DIMENSION(:, :), POINTER           :: x_data
     676             :       TYPE(local_rho_type), POINTER                      :: local_rho_set, local_rho_set_admm
     677             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     678             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     679         552 :          POINTER                                         :: sab, sab_aux_fit
     680             :       TYPE(oce_matrix_type), POINTER                     :: oce
     681             :       TYPE(pw_c1d_gs_type)                               :: rho_tot_gspace, v_hartree_gspace
     682         552 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g, rho_g_aux, rhoz_g_aux, trho_g, &
     683         552 :                                                             trho_xc_g
     684             :       TYPE(pw_env_type), POINTER                         :: pw_env
     685             :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
     686             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     687             :       TYPE(pw_r3d_rs_type)                               :: v_hartree_rspace
     688         552 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, rho_r_aux, rhoz_r_aux, tau_r, &
     689         552 :                                                             trho_r, trho_xc_r, v_xc, v_xc_tau
     690         552 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     691             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     692             :       TYPE(qs_rho_type), POINTER                         :: rho, rho_aux_fit, rho_xc, rhoz_aux, trho
     693         552 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho1_atom_set, rho_atom_set
     694             :       TYPE(section_vals_type), POINTER                   :: hfx_section, input, xc_section
     695             :       TYPE(task_list_type), POINTER                      :: task_list
     696             : 
     697         552 :       CALL timeset(routineN, handle)
     698             : 
     699         552 :       NULLIFY (pw_env)
     700             :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, ks_env=ks_env, &
     701         552 :                       dft_control=dft_control, para_env=para_env)
     702         552 :       CPASSERT(ASSOCIATED(pw_env))
     703         552 :       nspins = dft_control%nspins
     704         552 :       gapw = dft_control%qs_control%gapw
     705         552 :       gapw_xc = dft_control%qs_control%gapw_xc
     706             : 
     707         552 :       CPASSERT(.NOT. dft_control%tddfpt2_control%do_exck)
     708         552 :       CPASSERT(.NOT. dft_control%tddfpt2_control%do_hfxsr)
     709         552 :       CPASSERT(.NOT. dft_control%tddfpt2_control%do_hfxlr)
     710             : 
     711         552 :       NULLIFY (auxbas_pw_pool, poisson_env)
     712             :       ! gets the tmp grids
     713             :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
     714         552 :                       poisson_env=poisson_env)
     715             : 
     716         552 :       CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
     717         552 :       CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
     718         552 :       CALL auxbas_pw_pool%create_pw(v_hartree_rspace)
     719             : 
     720        4056 :       ALLOCATE (trho_r(nspins), trho_g(nspins))
     721        1200 :       DO ispin = 1, nspins
     722         648 :          CALL auxbas_pw_pool%create_pw(trho_r(ispin))
     723        1200 :          CALL auxbas_pw_pool%create_pw(trho_g(ispin))
     724             :       END DO
     725         552 :       IF (gapw_xc) THEN
     726          70 :          ALLOCATE (trho_xc_r(nspins), trho_xc_g(nspins))
     727          28 :          DO ispin = 1, nspins
     728          14 :             CALL auxbas_pw_pool%create_pw(trho_xc_r(ispin))
     729          28 :             CALL auxbas_pw_pool%create_pw(trho_xc_g(ispin))
     730             :          END DO
     731             :       END IF
     732             : 
     733             :       ! GAPW/GAPW_XC initializations
     734         552 :       NULLIFY (hartree_local, local_rho_set)
     735         552 :       IF (gapw) THEN
     736             :          CALL get_qs_env(qs_env, &
     737             :                          atomic_kind_set=atomic_kind_set, &
     738             :                          natom=natom, &
     739          64 :                          qs_kind_set=qs_kind_set)
     740          64 :          CALL local_rho_set_create(local_rho_set)
     741             :          CALL allocate_rho_atom_internals(local_rho_set%rho_atom_set, atomic_kind_set, &
     742          64 :                                           qs_kind_set, dft_control, para_env)
     743             :          CALL init_rho0(local_rho_set, qs_env, dft_control%qs_control%gapw_control, &
     744          64 :                         zcore=0.0_dp)
     745          64 :          CALL rho0_s_grid_create(pw_env, local_rho_set%rho0_mpole)
     746          64 :          CALL hartree_local_create(hartree_local)
     747          64 :          CALL init_coulomb_local(hartree_local, natom)
     748         488 :       ELSEIF (gapw_xc) THEN
     749             :          CALL get_qs_env(qs_env, &
     750             :                          atomic_kind_set=atomic_kind_set, &
     751          14 :                          qs_kind_set=qs_kind_set)
     752          14 :          CALL local_rho_set_create(local_rho_set)
     753             :          CALL allocate_rho_atom_internals(local_rho_set%rho_atom_set, atomic_kind_set, &
     754          14 :                                           qs_kind_set, dft_control, para_env)
     755             :       END IF
     756             : 
     757         552 :       total_rho = 0.0_dp
     758         552 :       CALL pw_zero(rho_tot_gspace)
     759        1200 :       DO ispin = 1, nspins
     760             :          CALL calculate_rho_elec(ks_env=ks_env, matrix_p=matrix_pe(ispin)%matrix, &
     761             :                                  rho=trho_r(ispin), &
     762             :                                  rho_gspace=trho_g(ispin), &
     763             :                                  soft_valid=gapw, &
     764         648 :                                  total_rho=total_rho(ispin))
     765         648 :          CALL pw_axpy(trho_g(ispin), rho_tot_gspace)
     766        1200 :          IF (gapw_xc) THEN
     767             :             CALL calculate_rho_elec(ks_env=ks_env, matrix_p=matrix_pe(ispin)%matrix, &
     768             :                                     rho=trho_xc_r(ispin), &
     769             :                                     rho_gspace=trho_xc_g(ispin), &
     770             :                                     soft_valid=gapw_xc, &
     771          14 :                                     total_rho=rhotot)
     772             :          END IF
     773             :       END DO
     774             : 
     775             :       ! GAPW o GAPW_XC require the calculation of hard and soft local densities
     776         552 :       IF (gapw .OR. gapw_xc) THEN
     777          78 :          CALL get_qs_env(qs_env=qs_env, oce=oce, sab_orb=sab)
     778             :          CALL calculate_rho_atom_coeff(qs_env, matrix_pe, local_rho_set%rho_atom_set, &
     779          78 :                                        qs_kind_set, oce, sab, para_env)
     780          78 :          CALL prepare_gapw_den(qs_env, local_rho_set, do_rho0=gapw)
     781             :       END IF
     782        1656 :       rhotot = SUM(total_rho)
     783         552 :       IF (gapw) THEN
     784          64 :          CALL get_rho0_mpole(local_rho_set%rho0_mpole, Qlm_tot=Qlm_tot)
     785          64 :          rhotot = rhotot + local_rho_set%rho0_mpole%total_rho0_h
     786          64 :          CALL pw_axpy(local_rho_set%rho0_mpole%rho0_s_gs, rho_tot_gspace)
     787             :       END IF
     788             : 
     789         552 :       IF (ABS(rhotot) > 1.e-05_dp) THEN
     790          20 :          logger => cp_get_default_logger()
     791          20 :          IF (logger%para_env%is_source()) THEN
     792          10 :             iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     793             :          ELSE
     794             :             iounit = -1
     795             :          END IF
     796          20 :          CPWARN("Real space electron count of excitation density is non-zero.")
     797          20 :          IF (iounit > 0) THEN
     798          10 :             WRITE (iounit, "(T2,A,T61,G20.10)") "Measured electron count is ", rhotot
     799          10 :             WRITE (iounit, "(T2,A,/)") REPEAT("*", 79)
     800             :          END IF
     801             :       END IF
     802             : 
     803             :       ! calculate associated hartree potential
     804             :       CALL pw_poisson_solve(poisson_env, rho_tot_gspace, thartree, &
     805         552 :                             v_hartree_gspace)
     806         552 :       CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
     807         552 :       CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
     808         552 :       IF (gapw) THEN
     809             :          CALL Vh_1c_gg_integrals(qs_env, thartree, hartree_local%ecoul_1c, &
     810          64 :                                  local_rho_set, para_env, tddft=.TRUE.)
     811             :          CALL integrate_vhg0_rspace(qs_env, v_hartree_rspace, para_env, &
     812             :                                     calculate_forces=.FALSE., &
     813          64 :                                     local_rho_set=local_rho_set)
     814             :       END IF
     815             : 
     816             :       ! Fxc*drho term
     817         552 :       CALL get_qs_env(qs_env, rho=rho)
     818         552 :       CALL qs_rho_get(rho, rho_r=rho_r, rho_g=rho_g)
     819             :       !
     820         552 :       CALL get_qs_env(qs_env, input=input)
     821         552 :       IF (dft_control%do_admm) THEN
     822         128 :          CALL get_qs_env(qs_env, admm_env=admm_env)
     823         128 :          xc_section => admm_env%xc_section_primary
     824             :       ELSE
     825         424 :          xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     826             :       END IF
     827             :       !
     828         552 :       deriv2_analytic = section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")
     829         552 :       IF (deriv2_analytic) THEN
     830         552 :          NULLIFY (v_xc, v_xc_tau, tau_r)
     831         552 :          IF (gapw_xc) THEN
     832          14 :             CALL get_qs_env(qs_env=qs_env, rho_xc=rho_xc)
     833          14 :             CALL qs_fxc_analytic(rho_xc, trho_xc_r, tau_r, xc_section, auxbas_pw_pool, .FALSE., v_xc, v_xc_tau)
     834             :          ELSE
     835         538 :             CALL qs_fxc_analytic(rho, trho_r, tau_r, xc_section, auxbas_pw_pool, .FALSE., v_xc, v_xc_tau)
     836             :          END IF
     837         552 :          IF (gapw .OR. gapw_xc) THEN
     838          78 :             CALL get_qs_env(qs_env, rho_atom_set=rho_atom_set)
     839          78 :             rho1_atom_set => local_rho_set%rho_atom_set
     840             :             CALL calculate_xc_2nd_deriv_atom(rho_atom_set, rho1_atom_set, qs_env, xc_section, para_env, &
     841          78 :                                              do_tddft=.TRUE., do_triplet=.FALSE.)
     842             :          END IF
     843             :       ELSE
     844           0 :          CPABORT("NYA 00006")
     845           0 :          NULLIFY (v_xc, trho)
     846           0 :          ALLOCATE (trho)
     847           0 :          CALL qs_rho_create(trho)
     848           0 :          CALL qs_rho_set(trho, rho_r=trho_r, rho_g=trho_g)
     849           0 :          CALL qs_fxc_fdiff(ks_env, rho, trho, xc_section, 6, .FALSE., v_xc, v_xc_tau)
     850           0 :          DEALLOCATE (trho)
     851             :       END IF
     852             : 
     853        1200 :       DO ispin = 1, nspins
     854         648 :          CALL dbcsr_set(matrix_hz(ispin)%matrix, 0.0_dp)
     855        1200 :          CALL pw_scale(v_xc(ispin), v_xc(ispin)%pw_grid%dvol)
     856             :       END DO
     857         552 :       IF (gapw_xc) THEN
     858          28 :          DO ispin = 1, nspins
     859             :             CALL integrate_v_rspace(qs_env=qs_env, v_rspace=v_hartree_rspace, &
     860             :                                     hmat=matrix_hz(ispin), &
     861          14 :                                     calculate_forces=.FALSE.)
     862             :             CALL integrate_v_rspace(qs_env=qs_env, v_rspace=v_xc(ispin), &
     863             :                                     hmat=matrix_hz(ispin), &
     864          28 :                                     gapw=gapw_xc, calculate_forces=.FALSE.)
     865             :          END DO
     866             :       ELSE
     867             :          ! vtot = v_xc(ispin) + v_hartree
     868        1172 :          DO ispin = 1, nspins
     869             :             CALL integrate_v_rspace(qs_env=qs_env, v_rspace=v_xc(ispin), &
     870             :                                     hmat=matrix_hz(ispin), &
     871         634 :                                     gapw=gapw, calculate_forces=.FALSE.)
     872             :             CALL integrate_v_rspace(qs_env=qs_env, v_rspace=v_hartree_rspace, &
     873             :                                     hmat=matrix_hz(ispin), &
     874        1172 :                                     gapw=gapw, calculate_forces=.FALSE.)
     875             :          END DO
     876             :       END IF
     877         552 :       IF (gapw .OR. gapw_xc) THEN
     878          78 :          mhz(1:nspins, 1:1) => matrix_hz(1:nspins)
     879          78 :          mpe(1:nspins, 1:1) => matrix_pe(1:nspins)
     880             :          CALL update_ks_atom(qs_env, mhz, mpe, forces=.FALSE., &
     881          78 :                              rho_atom_external=local_rho_set%rho_atom_set)
     882             :       END IF
     883             : 
     884         552 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
     885         552 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_rspace)
     886         552 :       CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
     887        1200 :       DO ispin = 1, nspins
     888         648 :          CALL auxbas_pw_pool%give_back_pw(trho_r(ispin))
     889         648 :          CALL auxbas_pw_pool%give_back_pw(trho_g(ispin))
     890        1200 :          CALL auxbas_pw_pool%give_back_pw(v_xc(ispin))
     891             :       END DO
     892         552 :       DEALLOCATE (trho_r, trho_g, v_xc)
     893         552 :       IF (gapw_xc) THEN
     894          28 :          DO ispin = 1, nspins
     895          14 :             CALL auxbas_pw_pool%give_back_pw(trho_xc_r(ispin))
     896          28 :             CALL auxbas_pw_pool%give_back_pw(trho_xc_g(ispin))
     897             :          END DO
     898          14 :          DEALLOCATE (trho_xc_r, trho_xc_g)
     899             :       END IF
     900         552 :       IF (ASSOCIATED(v_xc_tau)) THEN
     901           0 :          DO ispin = 1, nspins
     902           0 :             CALL auxbas_pw_pool%give_back_pw(v_xc_tau(ispin))
     903             :          END DO
     904           0 :          DEALLOCATE (v_xc_tau)
     905             :       END IF
     906         552 :       IF (dft_control%do_admm) THEN
     907         128 :          IF (qs_env%admm_env%aux_exch_func == do_admm_aux_exch_func_none) THEN
     908             :             ! nothing to do
     909             :          ELSE
     910             :             ! add ADMM xc_section_aux terms: f_x[rhoz_ADMM]
     911          78 :             CALL get_qs_env(qs_env, admm_env=admm_env)
     912             :             CALL get_admm_env(admm_env, rho_aux_fit=rho_aux_fit, matrix_s_aux_fit=msaux, &
     913          78 :                               task_list_aux_fit=task_list)
     914          78 :             basis_type = "AUX_FIT"
     915             :             !
     916          78 :             NULLIFY (mpe, mhz)
     917         398 :             ALLOCATE (mpe(nspins, 1))
     918          78 :             CALL dbcsr_allocate_matrix_set(mhz, nspins, 1)
     919         164 :             DO ispin = 1, nspins
     920          86 :                ALLOCATE (mhz(ispin, 1)%matrix)
     921          86 :                CALL dbcsr_create(mhz(ispin, 1)%matrix, template=msaux(1)%matrix)
     922          86 :                CALL dbcsr_copy(mhz(ispin, 1)%matrix, msaux(1)%matrix)
     923          86 :                CALL dbcsr_set(mhz(ispin, 1)%matrix, 0.0_dp)
     924         164 :                mpe(ispin, 1)%matrix => matrix_pe_admm(ispin)%matrix
     925             :             END DO
     926             :             !
     927             :             ! GAPW/GAPW_XC initializations
     928          78 :             NULLIFY (local_rho_set_admm)
     929          78 :             IF (admm_env%do_gapw) THEN
     930           4 :                basis_type = "AUX_FIT_SOFT"
     931           4 :                task_list => admm_env%admm_gapw_env%task_list
     932           4 :                CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
     933           4 :                CALL get_admm_env(admm_env, sab_aux_fit=sab_aux_fit)
     934           4 :                CALL local_rho_set_create(local_rho_set_admm)
     935             :                CALL allocate_rho_atom_internals(local_rho_set_admm%rho_atom_set, atomic_kind_set, &
     936           4 :                                                 admm_env%admm_gapw_env%admm_kind_set, dft_control, para_env)
     937             :                CALL calculate_rho_atom_coeff(qs_env, matrix_pe_admm, &
     938             :                                              rho_atom_set=local_rho_set_admm%rho_atom_set, &
     939             :                                              qs_kind_set=admm_env%admm_gapw_env%admm_kind_set, &
     940           4 :                                              oce=admm_env%admm_gapw_env%oce, sab=sab_aux_fit, para_env=para_env)
     941             :                CALL prepare_gapw_den(qs_env, local_rho_set=local_rho_set_admm, &
     942           4 :                                      do_rho0=.FALSE., kind_set_external=admm_env%admm_gapw_env%admm_kind_set)
     943             :             END IF
     944             :             !
     945          78 :             xc_section => admm_env%xc_section_aux
     946             :             !
     947          78 :             NULLIFY (rho_g_aux, rho_r_aux, rhoz_g_aux, rhoz_r_aux)
     948          78 :             CALL qs_rho_get(rho_aux_fit, rho_r=rho_r_aux, rho_g=rho_g_aux)
     949             :             ! rhoz_aux
     950         406 :             ALLOCATE (rhoz_r_aux(nspins), rhoz_g_aux(nspins))
     951         164 :             DO ispin = 1, nspins
     952          86 :                CALL auxbas_pw_pool%create_pw(rhoz_r_aux(ispin))
     953         164 :                CALL auxbas_pw_pool%create_pw(rhoz_g_aux(ispin))
     954             :             END DO
     955         164 :             DO ispin = 1, nspins
     956             :                CALL calculate_rho_elec(ks_env=ks_env, matrix_p=mpe(ispin, 1)%matrix, &
     957             :                                        rho=rhoz_r_aux(ispin), rho_gspace=rhoz_g_aux(ispin), &
     958             :                                        basis_type=basis_type, &
     959         164 :                                        task_list_external=task_list)
     960             :             END DO
     961             :             !
     962          78 :             NULLIFY (v_xc)
     963          78 :             deriv2_analytic = section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")
     964          78 :             IF (deriv2_analytic) THEN
     965          78 :                NULLIFY (tau_r)
     966          78 :                CALL qs_fxc_analytic(rho_aux_fit, rhoz_r_aux, tau_r, xc_section, auxbas_pw_pool, .FALSE., v_xc, v_xc_tau)
     967             :             ELSE
     968           0 :                CPABORT("NYA 00007")
     969             :                NULLIFY (rhoz_aux)
     970           0 :                ALLOCATE (rhoz_aux)
     971           0 :                CALL qs_rho_create(rhoz_aux)
     972           0 :                CALL qs_rho_set(rhoz_aux, rho_r=rhoz_r_aux, rho_g=rhoz_g_aux)
     973           0 :                CALL qs_fxc_fdiff(ks_env, rho_aux_fit, rhoz_aux, xc_section, 6, .FALSE., v_xc, v_xc_tau)
     974           0 :                DEALLOCATE (rhoz_aux)
     975             :             END IF
     976             :             !
     977         164 :             DO ispin = 1, nspins
     978          86 :                CALL pw_scale(v_xc(ispin), v_xc(ispin)%pw_grid%dvol)
     979             :                CALL integrate_v_rspace(qs_env=qs_env, v_rspace=v_xc(ispin), &
     980             :                                        hmat=mhz(ispin, 1), basis_type=basis_type, &
     981             :                                        calculate_forces=.FALSE., &
     982         164 :                                        task_list_external=task_list)
     983             :             END DO
     984         164 :             DO ispin = 1, nspins
     985          86 :                CALL auxbas_pw_pool%give_back_pw(v_xc(ispin))
     986          86 :                CALL auxbas_pw_pool%give_back_pw(rhoz_r_aux(ispin))
     987         164 :                CALL auxbas_pw_pool%give_back_pw(rhoz_g_aux(ispin))
     988             :             END DO
     989          78 :             DEALLOCATE (v_xc, rhoz_r_aux, rhoz_g_aux)
     990             :             !
     991          78 :             IF (admm_env%do_gapw) THEN
     992           4 :                rho_atom_set => admm_env%admm_gapw_env%local_rho_set%rho_atom_set
     993           4 :                rho1_atom_set => local_rho_set_admm%rho_atom_set
     994             :                CALL calculate_xc_2nd_deriv_atom(rho_atom_set, rho1_atom_set, qs_env, xc_section, &
     995           4 :                                                 para_env, kind_set_external=admm_env%admm_gapw_env%admm_kind_set)
     996             :                CALL update_ks_atom(qs_env, mhz(:, 1), matrix_pe_admm, forces=.FALSE., tddft=.FALSE., &
     997             :                                    rho_atom_external=rho1_atom_set, &
     998             :                                    kind_set_external=admm_env%admm_gapw_env%admm_kind_set, &
     999             :                                    oce_external=admm_env%admm_gapw_env%oce, &
    1000           4 :                                    sab_external=sab_aux_fit)
    1001             :             END IF
    1002             :             !
    1003          78 :             nao = admm_env%nao_orb
    1004          78 :             nao_aux = admm_env%nao_aux_fit
    1005          78 :             ALLOCATE (dbwork)
    1006          78 :             CALL dbcsr_create(dbwork, template=matrix_hz(1)%matrix)
    1007         164 :             DO ispin = 1, nspins
    1008             :                CALL cp_dbcsr_sm_fm_multiply(mhz(ispin, 1)%matrix, admm_env%A, &
    1009          86 :                                             admm_env%work_aux_orb, nao)
    1010             :                CALL parallel_gemm('T', 'N', nao, nao, nao_aux, &
    1011             :                                   1.0_dp, admm_env%A, admm_env%work_aux_orb, 0.0_dp, &
    1012          86 :                                   admm_env%work_orb_orb)
    1013          86 :                CALL dbcsr_copy(dbwork, matrix_hz(1)%matrix)
    1014          86 :                CALL dbcsr_set(dbwork, 0.0_dp)
    1015          86 :                CALL copy_fm_to_dbcsr(admm_env%work_orb_orb, dbwork, keep_sparsity=.TRUE.)
    1016         164 :                CALL dbcsr_add(matrix_hz(ispin)%matrix, dbwork, 1.0_dp, 1.0_dp)
    1017             :             END DO
    1018          78 :             CALL dbcsr_release(dbwork)
    1019          78 :             DEALLOCATE (dbwork)
    1020          78 :             CALL dbcsr_deallocate_matrix_set(mhz)
    1021          78 :             DEALLOCATE (mpe)
    1022          78 :             IF (admm_env%do_gapw) THEN
    1023           4 :                IF (ASSOCIATED(local_rho_set_admm)) CALL local_rho_set_release(local_rho_set_admm)
    1024             :             END IF
    1025             :          END IF
    1026             :       END IF
    1027         552 :       IF (gapw .OR. gapw_xc) THEN
    1028          78 :          IF (ASSOCIATED(local_rho_set)) CALL local_rho_set_release(local_rho_set)
    1029          78 :          IF (ASSOCIATED(hartree_local)) CALL hartree_local_release(hartree_local)
    1030             :       END IF
    1031             : 
    1032             :       ! HFX
    1033         552 :       hfx_section => section_vals_get_subs_vals(xc_section, "HF")
    1034         552 :       CALL section_vals_get(hfx_section, explicit=do_hfx)
    1035         552 :       IF (do_hfx) THEN
    1036         248 :          CALL section_vals_get(hfx_section, n_repetition=n_rep_hf)
    1037         248 :          CPASSERT(n_rep_hf == 1)
    1038             :          CALL section_vals_val_get(hfx_section, "TREAT_LSD_IN_CORE", l_val=hfx_treat_lsd_in_core, &
    1039         248 :                                    i_rep_section=1)
    1040         248 :          mspin = 1
    1041         248 :          IF (hfx_treat_lsd_in_core) mspin = nspins
    1042             :          !
    1043             :          CALL get_qs_env(qs_env=qs_env, rho=rho, x_data=x_data, para_env=para_env, &
    1044         248 :                          s_mstruct_changed=s_mstruct_changed)
    1045         248 :          distribute_fock_matrix = .TRUE.
    1046         248 :          IF (dft_control%do_admm) THEN
    1047         128 :             CALL get_qs_env(qs_env, admm_env=admm_env)
    1048         128 :             CALL get_admm_env(admm_env, matrix_s_aux_fit=msaux)
    1049         128 :             NULLIFY (mpe, mhz)
    1050         660 :             ALLOCATE (mpe(nspins, 1))
    1051         128 :             CALL dbcsr_allocate_matrix_set(mhz, nspins, 1)
    1052         276 :             DO ispin = 1, nspins
    1053         148 :                ALLOCATE (mhz(ispin, 1)%matrix)
    1054         148 :                CALL dbcsr_create(mhz(ispin, 1)%matrix, template=msaux(1)%matrix)
    1055         148 :                CALL dbcsr_copy(mhz(ispin, 1)%matrix, msaux(1)%matrix)
    1056         148 :                CALL dbcsr_set(mhz(ispin, 1)%matrix, 0.0_dp)
    1057         276 :                mpe(ispin, 1)%matrix => matrix_pe_admm(ispin)%matrix
    1058             :             END DO
    1059         128 :             IF (x_data(1, 1)%do_hfx_ri) THEN
    1060             :                eh1 = 0.0_dp
    1061             :                CALL hfx_ri_update_ks(qs_env, x_data(1, 1)%ri_data, mhz, eh1, rho_ao=mpe, &
    1062             :                                      geometry_did_change=s_mstruct_changed, nspins=nspins, &
    1063           6 :                                      hf_fraction=x_data(1, 1)%general_parameter%fraction)
    1064             :             ELSE
    1065         244 :                DO ispin = 1, mspin
    1066             :                   eh1 = 0.0
    1067             :                   CALL integrate_four_center(qs_env, x_data, mhz, eh1, mpe, hfx_section, &
    1068             :                                              para_env, s_mstruct_changed, 1, distribute_fock_matrix, &
    1069         244 :                                              ispin=ispin)
    1070             :                END DO
    1071             :             END IF
    1072             :             !
    1073         128 :             CPASSERT(ASSOCIATED(admm_env%work_aux_orb))
    1074         128 :             CPASSERT(ASSOCIATED(admm_env%work_orb_orb))
    1075         128 :             nao = admm_env%nao_orb
    1076         128 :             nao_aux = admm_env%nao_aux_fit
    1077         128 :             ALLOCATE (dbwork)
    1078         128 :             CALL dbcsr_create(dbwork, template=matrix_hz(1)%matrix)
    1079         276 :             DO ispin = 1, nspins
    1080             :                CALL cp_dbcsr_sm_fm_multiply(mhz(ispin, 1)%matrix, admm_env%A, &
    1081         148 :                                             admm_env%work_aux_orb, nao)
    1082             :                CALL parallel_gemm('T', 'N', nao, nao, nao_aux, &
    1083             :                                   1.0_dp, admm_env%A, admm_env%work_aux_orb, 0.0_dp, &
    1084         148 :                                   admm_env%work_orb_orb)
    1085         148 :                CALL dbcsr_copy(dbwork, matrix_hz(ispin)%matrix)
    1086         148 :                CALL dbcsr_set(dbwork, 0.0_dp)
    1087         148 :                CALL copy_fm_to_dbcsr(admm_env%work_orb_orb, dbwork, keep_sparsity=.TRUE.)
    1088         276 :                CALL dbcsr_add(matrix_hz(ispin)%matrix, dbwork, 1.0_dp, 1.0_dp)
    1089             :             END DO
    1090         128 :             CALL dbcsr_release(dbwork)
    1091         128 :             DEALLOCATE (dbwork)
    1092         128 :             CALL dbcsr_deallocate_matrix_set(mhz)
    1093         128 :             DEALLOCATE (mpe)
    1094             :          ELSE
    1095         120 :             NULLIFY (mpe, mhz)
    1096        1000 :             ALLOCATE (mpe(nspins, 1), mhz(nspins, 1))
    1097         260 :             DO ispin = 1, nspins
    1098         140 :                mhz(ispin, 1)%matrix => matrix_hz(ispin)%matrix
    1099         260 :                mpe(ispin, 1)%matrix => matrix_pe(ispin)%matrix
    1100             :             END DO
    1101         120 :             IF (x_data(1, 1)%do_hfx_ri) THEN
    1102             :                eh1 = 0.0_dp
    1103             :                CALL hfx_ri_update_ks(qs_env, x_data(1, 1)%ri_data, mhz, eh1, rho_ao=mpe, &
    1104             :                                      geometry_did_change=s_mstruct_changed, nspins=nspins, &
    1105          18 :                                      hf_fraction=x_data(1, 1)%general_parameter%fraction)
    1106             :             ELSE
    1107         204 :                DO ispin = 1, mspin
    1108             :                   eh1 = 0.0
    1109             :                   CALL integrate_four_center(qs_env, x_data, mhz, eh1, mpe, hfx_section, &
    1110             :                                              para_env, s_mstruct_changed, 1, distribute_fock_matrix, &
    1111         204 :                                              ispin=ispin)
    1112             :                END DO
    1113             :             END IF
    1114         120 :             DEALLOCATE (mpe, mhz)
    1115             :          END IF
    1116             :       END IF
    1117             : 
    1118         552 :       focc = 4.0_dp
    1119         552 :       IF (nspins == 2) focc = 2.0_dp
    1120        1200 :       DO ispin = 1, nspins
    1121         648 :          mos => gs_mos(ispin)%mos_occ
    1122         648 :          CALL cp_fm_get_info(mos, ncol_global=norb)
    1123             :          CALL cp_dbcsr_sm_fm_multiply(matrix_hz(ispin)%matrix, mos, cpmos(ispin), &
    1124        1200 :                                       norb, alpha=focc, beta=0.0_dp)
    1125             :       END DO
    1126             : 
    1127         552 :       CALL timestop(handle)
    1128             : 
    1129        1656 :    END SUBROUTINE tddfpt_resvec2
    1130             : 
    1131             : ! **************************************************************************************************
    1132             : !> \brief ...
    1133             : !> \param qs_env ...
    1134             : !> \param matrix_pe ...
    1135             : !> \param gs_mos ...
    1136             : !> \param matrix_hz ...
    1137             : !> \param cpmos ...
    1138             : ! **************************************************************************************************
    1139          16 :    SUBROUTINE tddfpt_resvec2_xtb(qs_env, matrix_pe, gs_mos, matrix_hz, cpmos)
    1140             : 
    1141             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1142             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_pe
    1143             :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
    1144             :          POINTER                                         :: gs_mos
    1145             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_hz
    1146             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT)      :: cpmos
    1147             : 
    1148             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_resvec2_xtb'
    1149             : 
    1150             :       INTEGER                                            :: atom_a, handle, iatom, ikind, is, ispin, &
    1151             :                                                             na, natom, natorb, nkind, norb, ns, &
    1152             :                                                             nsgf, nspins
    1153             :       INTEGER, DIMENSION(25)                             :: lao
    1154             :       INTEGER, DIMENSION(5)                              :: occ
    1155          16 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: mcharge, mcharge1
    1156          16 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: aocg, aocg1, charges, charges1
    1157             :       REAL(KIND=dp)                                      :: focc
    1158          16 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1159             :       TYPE(cp_fm_type), POINTER                          :: mos
    1160          16 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: p_matrix
    1161          16 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_s
    1162             :       TYPE(dbcsr_type), POINTER                          :: s_matrix
    1163             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1164             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1165          16 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1166          16 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1167             :       TYPE(qs_rho_type), POINTER                         :: rho
    1168             :       TYPE(xtb_atom_type), POINTER                       :: xtb_kind
    1169             : 
    1170          16 :       CALL timeset(routineN, handle)
    1171             : 
    1172          16 :       CPASSERT(ASSOCIATED(matrix_pe))
    1173             : 
    1174          16 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
    1175          16 :       nspins = dft_control%nspins
    1176             : 
    1177          32 :       DO ispin = 1, nspins
    1178          32 :          CALL dbcsr_set(matrix_hz(ispin)%matrix, 0.0_dp)
    1179             :       END DO
    1180             : 
    1181          16 :       IF (dft_control%qs_control%xtb_control%coulomb_interaction) THEN
    1182             :          ! Mulliken charges
    1183             :          CALL get_qs_env(qs_env, rho=rho, particle_set=particle_set, &
    1184          14 :                          matrix_s_kp=matrix_s, para_env=para_env)
    1185          14 :          natom = SIZE(particle_set)
    1186          14 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
    1187          70 :          ALLOCATE (mcharge(natom), charges(natom, 5))
    1188          42 :          ALLOCATE (mcharge1(natom), charges1(natom, 5))
    1189        1254 :          charges = 0.0_dp
    1190        1254 :          charges1 = 0.0_dp
    1191          14 :          CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
    1192          14 :          nkind = SIZE(atomic_kind_set)
    1193          14 :          CALL get_qs_kind_set(qs_kind_set, maxsgf=nsgf)
    1194          56 :          ALLOCATE (aocg(nsgf, natom))
    1195        1184 :          aocg = 0.0_dp
    1196          42 :          ALLOCATE (aocg1(nsgf, natom))
    1197        1184 :          aocg1 = 0.0_dp
    1198          14 :          p_matrix => matrix_p(:, 1)
    1199          14 :          s_matrix => matrix_s(1, 1)%matrix
    1200          14 :          CALL ao_charges(p_matrix, s_matrix, aocg, para_env)
    1201          14 :          CALL ao_charges(matrix_pe, s_matrix, aocg1, para_env)
    1202          48 :          DO ikind = 1, nkind
    1203          34 :             CALL get_atomic_kind(atomic_kind_set(ikind), natom=na)
    1204          34 :             CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_kind)
    1205          34 :             CALL get_xtb_atom_param(xtb_kind, natorb=natorb, lao=lao, occupation=occ)
    1206         316 :             DO iatom = 1, na
    1207         234 :                atom_a = atomic_kind_set(ikind)%atom_list(iatom)
    1208        1404 :                charges(atom_a, :) = REAL(occ(:), KIND=dp)
    1209         900 :                DO is = 1, natorb
    1210         632 :                   ns = lao(is) + 1
    1211         632 :                   charges(atom_a, ns) = charges(atom_a, ns) - aocg(is, atom_a)
    1212         866 :                   charges1(atom_a, ns) = charges1(atom_a, ns) - aocg1(is, atom_a)
    1213             :                END DO
    1214             :             END DO
    1215             :          END DO
    1216          14 :          DEALLOCATE (aocg, aocg1)
    1217         248 :          DO iatom = 1, natom
    1218        1404 :             mcharge(iatom) = SUM(charges(iatom, :))
    1219        1418 :             mcharge1(iatom) = SUM(charges1(iatom, :))
    1220             :          END DO
    1221             :          ! Coulomb Kernel
    1222          14 :          CALL xtb_coulomb_hessian(qs_env, matrix_hz, charges1, mcharge1, mcharge)
    1223             :          !
    1224          28 :          DEALLOCATE (charges, mcharge, charges1, mcharge1)
    1225             :       END IF
    1226             : 
    1227          16 :       focc = 2.0_dp
    1228          16 :       IF (nspins == 2) focc = 1.0_dp
    1229          32 :       DO ispin = 1, nspins
    1230          16 :          mos => gs_mos(ispin)%mos_occ
    1231          16 :          CALL cp_fm_get_info(mos, ncol_global=norb)
    1232             :          CALL cp_dbcsr_sm_fm_multiply(matrix_hz(ispin)%matrix, mos, cpmos(ispin), &
    1233          32 :                                       norb, alpha=focc, beta=0.0_dp)
    1234             :       END DO
    1235             : 
    1236          16 :       CALL timestop(handle)
    1237             : 
    1238          32 :    END SUBROUTINE tddfpt_resvec2_xtb
    1239             : 
    1240             : ! **************************************************************************************************
    1241             : !> \brief ...
    1242             : !> \param qs_env ...
    1243             : !> \param cpmos ...
    1244             : !> \param work ...
    1245             : ! **************************************************************************************************
    1246         568 :    SUBROUTINE tddfpt_resvec3(qs_env, cpmos, work)
    1247             : 
    1248             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1249             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: cpmos
    1250             :       TYPE(tddfpt_work_matrices)                         :: work
    1251             : 
    1252             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'tddfpt_resvec3'
    1253             : 
    1254             :       INTEGER                                            :: handle, ispin, nao, norb, nspins
    1255             :       TYPE(cp_fm_struct_type), POINTER                   :: fmstruct
    1256             :       TYPE(cp_fm_type)                                   :: cvec, umat
    1257             :       TYPE(cp_fm_type), POINTER                          :: omos
    1258             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1259         568 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
    1260             : 
    1261         568 :       CALL timeset(routineN, handle)
    1262             : 
    1263         568 :       CALL get_qs_env(qs_env, mos=mos, dft_control=dft_control)
    1264         568 :       nspins = dft_control%nspins
    1265             : 
    1266        1232 :       DO ispin = 1, nspins
    1267         664 :          CALL get_mo_set(mos(ispin), mo_coeff=omos)
    1268             :          ASSOCIATE (rvecs => cpmos(ispin))
    1269         664 :             CALL cp_fm_get_info(rvecs, nrow_global=nao, ncol_global=norb)
    1270         664 :             CALL cp_fm_create(cvec, rvecs%matrix_struct, "cvec")
    1271             :             CALL cp_fm_struct_create(fmstruct, context=rvecs%matrix_struct%context, nrow_global=norb, &
    1272         664 :                                      ncol_global=norb, para_env=rvecs%matrix_struct%para_env)
    1273         664 :             CALL cp_fm_create(umat, fmstruct, "umat")
    1274         664 :             CALL cp_fm_struct_release(fmstruct)
    1275             :             !
    1276         664 :             CALL parallel_gemm("T", "N", norb, norb, nao, 1.0_dp, omos, work%S_C0(ispin), 0.0_dp, umat)
    1277         664 :             CALL cp_fm_copy_general(rvecs, cvec, rvecs%matrix_struct%para_env)
    1278         664 :             CALL parallel_gemm("N", "T", nao, norb, norb, 1.0_dp, cvec, umat, 0.0_dp, rvecs)
    1279             :          END ASSOCIATE
    1280         664 :          CALL cp_fm_release(cvec)
    1281        2560 :          CALL cp_fm_release(umat)
    1282             :       END DO
    1283             : 
    1284         568 :       CALL timestop(handle)
    1285             : 
    1286         568 :    END SUBROUTINE tddfpt_resvec3
    1287             : 
    1288             : ! **************************************************************************************************
    1289             : !> \brief Calculate direct tddft forces
    1290             : !> \param qs_env ...
    1291             : !> \param ex_env ...
    1292             : !> \param gs_mos ...
    1293             : !> \param kernel_env ...
    1294             : !> \param sub_env ...
    1295             : !> \param work_matrices ...
    1296             : !> \param debug_forces ...
    1297             : !> \par History
    1298             : !>    * 01.2020 screated [JGH]
    1299             : ! **************************************************************************************************
    1300         568 :    SUBROUTINE tddfpt_kernel_force(qs_env, ex_env, gs_mos, kernel_env, sub_env, work_matrices, debug_forces)
    1301             : 
    1302             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1303             :       TYPE(excited_energy_type), POINTER                 :: ex_env
    1304             :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
    1305             :          POINTER                                         :: gs_mos
    1306             :       TYPE(kernel_env_type), INTENT(IN)                  :: kernel_env
    1307             :       TYPE(tddfpt_subgroup_env_type)                     :: sub_env
    1308             :       TYPE(tddfpt_work_matrices)                         :: work_matrices
    1309             :       LOGICAL, INTENT(IN)                                :: debug_forces
    1310             : 
    1311             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_kernel_force'
    1312             : 
    1313             :       INTEGER                                            :: handle
    1314             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1315             :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
    1316             : 
    1317             :       MARK_USED(work_matrices)
    1318             : 
    1319         568 :       CALL timeset(routineN, handle)
    1320             : 
    1321         568 :       CALL get_qs_env(qs_env, dft_control=dft_control)
    1322         568 :       tddfpt_control => dft_control%tddfpt2_control
    1323             : 
    1324         568 :       IF (tddfpt_control%kernel == tddfpt_kernel_full) THEN
    1325             :          ! full Kernel
    1326         342 :          CALL fhxc_force(qs_env, ex_env, gs_mos, kernel_env%full_kernel, debug_forces)
    1327         226 :       ELSE IF (tddfpt_control%kernel == tddfpt_kernel_stda) THEN
    1328             :          ! sTDA Kernel
    1329         158 :          CALL stda_force(qs_env, ex_env, gs_mos, kernel_env%stda_kernel, sub_env, work_matrices, debug_forces)
    1330          68 :       ELSE IF (tddfpt_control%kernel == tddfpt_kernel_none) THEN
    1331             :          ! nothing to be done here
    1332          68 :          ex_env%matrix_wx1 => NULL()
    1333             :       ELSE
    1334           0 :          CPABORT('Unknown kernel type')
    1335             :       END IF
    1336             : 
    1337         568 :       CALL timestop(handle)
    1338             : 
    1339         568 :    END SUBROUTINE tddfpt_kernel_force
    1340             : 
    1341             : END MODULE qs_tddfpt2_forces

Generated by: LCOV version 1.15