LCOV - code coverage report
Current view: top level - src - qs_tddfpt2_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:24d69ee) Lines: 91.7 % 927 850
Test Date: 2026-09-03 07:32:15 Functions: 100.0 % 7 7

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : MODULE qs_tddfpt2_methods
       9              :    USE admm_methods,                    ONLY: admm_fit_mo_coeffs
      10              :    USE admm_types,                      ONLY: admm_type,&
      11              :                                               get_admm_env
      12              :    USE atomic_kind_types,               ONLY: atomic_kind_type
      13              :    USE bibliography,                    ONLY: Grimme2013,&
      14              :                                               Grimme2016,&
      15              :                                               Hernandez2025,&
      16              :                                               Iannuzzi2005,&
      17              :                                               cite_reference
      18              :    USE cell_types,                      ONLY: cell_type
      19              :    USE cp_blacs_env,                    ONLY: cp_blacs_env_type
      20              :    USE cp_control_types,                ONLY: dft_control_type,&
      21              :                                               rixs_control_type,&
      22              :                                               tddfpt2_control_type
      23              :    USE cp_dbcsr_api,                    ONLY: dbcsr_create,&
      24              :                                               dbcsr_deallocate_matrix,&
      25              :                                               dbcsr_p_type,&
      26              :                                               dbcsr_set,&
      27              :                                               dbcsr_type,&
      28              :                                               dbcsr_type_antisymmetric,&
      29              :                                               dbcsr_type_symmetric
      30              :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      31              :    USE cp_dbcsr_operations,             ONLY: cp_dbcsr_sm_fm_multiply,&
      32              :                                               dbcsr_deallocate_matrix_set
      33              :    USE cp_fm_pool_types,                ONLY: fm_pool_create_fm
      34              :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      35              :                                               cp_fm_struct_release,&
      36              :                                               cp_fm_struct_type
      37              :    USE cp_fm_types,                     ONLY: cp_fm_copy_general,&
      38              :                                               cp_fm_create,&
      39              :                                               cp_fm_get_element,&
      40              :                                               cp_fm_get_info,&
      41              :                                               cp_fm_release,&
      42              :                                               cp_fm_to_fm,&
      43              :                                               cp_fm_to_fm_submat,&
      44              :                                               cp_fm_type
      45              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      46              :                                               cp_logger_get_default_io_unit,&
      47              :                                               cp_logger_type
      48              :    USE cp_output_handling,              ONLY: cp_add_iter_level,&
      49              :                                               cp_iterate,&
      50              :                                               cp_print_key_finished_output,&
      51              :                                               cp_print_key_unit_nr,&
      52              :                                               cp_rm_iter_level
      53              :    USE exstates_types,                  ONLY: excited_energy_type
      54              :    USE header,                          ONLY: tddfpt_header,&
      55              :                                               tddfpt_soc_header
      56              :    USE hfx_admm_utils,                  ONLY: aux_admm_init
      57              :    USE hfx_types,                       ONLY: compare_hfx_sections,&
      58              :                                               hfx_create
      59              :    USE input_constants,                 ONLY: &
      60              :         do_admm_aux_exch_func_none, do_admm_basis_projection, do_admm_exch_scaling_none, &
      61              :         do_admm_purify_none, do_potential_truncated, no_sf_tddfpt, oe_none, &
      62              :         tddfpt_dipole_scf_moment, tddfpt_dipole_velocity, tddfpt_kernel_full, tddfpt_kernel_none, &
      63              :         tddfpt_kernel_stda, tddfpt_sf_col, tddfpt_sf_noncol
      64              :    USE input_section_types,             ONLY: section_vals_get,&
      65              :                                               section_vals_get_subs_vals,&
      66              :                                               section_vals_type,&
      67              :                                               section_vals_val_get,&
      68              :                                               section_vals_val_set
      69              :    USE kinds,                           ONLY: dp
      70              :    USE kpoint_methods,                  ONLY: rskp_transform
      71              :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      72              :                                               kpoint_env_p_type,&
      73              :                                               kpoint_env_type,&
      74              :                                               kpoint_type
      75              :    USE lri_environment_methods,         ONLY: lri_print_stat
      76              :    USE lri_environment_types,           ONLY: lri_density_release,&
      77              :                                               lri_env_release
      78              :    USE machine,                         ONLY: m_flush
      79              :    USE message_passing,                 ONLY: mp_para_env_type
      80              :    USE min_basis_set,                   ONLY: create_minbas_set
      81              :    USE parallel_gemm_api,               ONLY: parallel_gemm
      82              :    USE particle_types,                  ONLY: particle_type
      83              :    USE physcon,                         ONLY: evolt
      84              :    USE qs_environment_types,            ONLY: get_qs_env,&
      85              :                                               qs_environment_type
      86              :    USE qs_kernel_methods,               ONLY: create_fxc_kernel,&
      87              :                                               create_kernel_env
      88              :    USE qs_kernel_types,                 ONLY: full_kernel_env_type,&
      89              :                                               kernel_env_type,&
      90              :                                               release_kernel_env
      91              :    USE qs_kind_types,                   ONLY: qs_kind_type
      92              :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      93              :    USE qs_mo_types,                     ONLY: get_mo_set,&
      94              :                                               mo_set_type
      95              :    USE qs_moments,                      ONLY: qs_moment_kpoints_scf_mos
      96              :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
      97              :    USE qs_overlap,                      ONLY: build_overlap_matrix
      98              :    USE qs_rho_types,                    ONLY: qs_rho_type
      99              :    USE qs_scf_methods,                  ONLY: eigensolver
     100              :    USE qs_scf_types,                    ONLY: qs_scf_env_type
     101              :    USE qs_tddfpt2_assign,               ONLY: assign_state
     102              :    USE qs_tddfpt2_densities,            ONLY: tddfpt_construct_aux_fit_density,&
     103              :                                               tddfpt_construct_ground_state_orb_density
     104              :    USE qs_tddfpt2_eigensolver,          ONLY: tddfpt_davidson_solver,&
     105              :                                               tddfpt_orthogonalize_psi1_psi0,&
     106              :                                               tddfpt_orthonormalize_psi1_psi1
     107              :    USE qs_tddfpt2_forces,               ONLY: tddfpt_forces_main
     108              :    USE qs_tddfpt2_fprint,               ONLY: tddfpt_print_forces
     109              :    USE qs_tddfpt2_lri_utils,            ONLY: tddfpt2_lri_init
     110              :    USE qs_tddfpt2_properties,           ONLY: tddfpt_dipole_operator,&
     111              :                                               tddfpt_print_excitation_analysis,&
     112              :                                               tddfpt_print_exciton_descriptors,&
     113              :                                               tddfpt_print_nto_analysis,&
     114              :                                               tddfpt_print_summary
     115              :    USE qs_tddfpt2_restart,              ONLY: tddfpt_read_restart,&
     116              :                                               tddfpt_write_newtonx_output,&
     117              :                                               tddfpt_write_restart
     118              :    USE qs_tddfpt2_smearing_methods,     ONLY: tddfpt_smeared_occupation
     119              :    USE qs_tddfpt2_soc,                  ONLY: tddfpt_soc
     120              :    USE qs_tddfpt2_stda_types,           ONLY: allocate_stda_env,&
     121              :                                               deallocate_stda_env,&
     122              :                                               stda_env_type,&
     123              :                                               stda_init_param
     124              :    USE qs_tddfpt2_stda_utils,           ONLY: get_lowdin_mo_coefficients,&
     125              :                                               stda_init_matrices
     126              :    USE qs_tddfpt2_subgroups,            ONLY: tddfpt_sub_env_init,&
     127              :                                               tddfpt_sub_env_release,&
     128              :                                               tddfpt_subgroup_env_type
     129              :    USE qs_tddfpt2_types,                ONLY: hfxsr_create_work_matrices,&
     130              :                                               stda_create_work_matrices,&
     131              :                                               tddfpt_create_work_matrices,&
     132              :                                               tddfpt_ground_state_mos,&
     133              :                                               tddfpt_release_work_matrices,&
     134              :                                               tddfpt_work_matrices
     135              :    USE qs_tddfpt2_utils,                ONLY: tddfpt_guess_vectors,&
     136              :                                               tddfpt_init_mos,&
     137              :                                               tddfpt_oecorr,&
     138              :                                               tddfpt_release_ground_state_mos
     139              :    USE rixs_types,                      ONLY: rixs_env_type,&
     140              :                                               tddfpt2_valence_type
     141              :    USE string_utilities,                ONLY: integer_to_string
     142              :    USE util,                            ONLY: sort
     143              :    USE xc_write_output,                 ONLY: xc_write
     144              : #include "./base/base_uses.f90"
     145              : 
     146              :    IMPLICIT NONE
     147              : 
     148              :    PRIVATE
     149              : 
     150              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_tddfpt2_methods'
     151              : 
     152              :    LOGICAL, PARAMETER, PRIVATE          :: debug_this_module = .FALSE.
     153              :    ! number of first derivative components (3: d/dx, d/dy, d/dz)
     154              :    INTEGER, PARAMETER, PRIVATE          :: nderivs = 3
     155              :    INTEGER, PARAMETER, PRIVATE          :: maxspins = 2
     156              : 
     157              :    PUBLIC :: tddfpt, tddfpt_energies, tddfpt_input
     158              : 
     159              : ! **************************************************************************************************
     160              : 
     161              : CONTAINS
     162              : 
     163              : ! **************************************************************************************************
     164              : !> \brief Perform TDDFPT calculation. If calc_forces then it also builds the response vector for the
     165              : !>        Z-vector method and calculates some contributions to the force
     166              : !> \param qs_env  Quickstep environment
     167              : !> \param calc_forces ...
     168              : !> \param rixs_env ...
     169              : !> \par History
     170              : !>    * 05.2016 created [Sergey Chulkov]
     171              : !>    * 06.2016 refactored to be used with Davidson eigensolver [Sergey Chulkov]
     172              : !>    * 03.2017 cleaned and refactored [Sergey Chulkov]
     173              : !> \note Based on the subroutines tddfpt_env_init(), and tddfpt_env_deallocate().
     174              : ! **************************************************************************************************
     175         1424 :    SUBROUTINE tddfpt(qs_env, calc_forces, rixs_env)
     176              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     177              :       LOGICAL, INTENT(IN)                                :: calc_forces
     178              :       TYPE(rixs_env_type), OPTIONAL, POINTER             :: rixs_env
     179              : 
     180              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'tddfpt'
     181              : 
     182              :       INTEGER                                            :: handle, ispin, istate, log_unit, mult, &
     183              :                                                             my_state, nao, nocc, nspins, &
     184              :                                                             nstate_max, nstates, nvirt, old_state
     185              :       INTEGER, DIMENSION(maxspins)                       :: nactive
     186              :       LOGICAL                                            :: do_admm, do_exck, do_hfx, do_hfxlr, &
     187              :                                                             do_hfxsr, do_kpoints, do_rixs, do_sf, &
     188              :                                                             do_soc, lmult_tmp, state_change
     189              :       REAL(kind=dp)                                      :: gsmin, gsval, xsval
     190         1424 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: evals, ostrength
     191         1424 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     192              :       TYPE(cell_type), POINTER                           :: cell
     193              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     194              :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
     195         1424 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: my_active, my_mos
     196         1424 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: dipole_op_mos_occ, evects, S_evects
     197              :       TYPE(cp_logger_type), POINTER                      :: logger
     198         1424 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks, matrix_ks_oep, matrix_s, &
     199         1424 :                                                             matrix_s_aux_fit, &
     200         1424 :                                                             matrix_s_aux_fit_vs_orb
     201              :       TYPE(dft_control_type), POINTER                    :: dft_control
     202              :       TYPE(excited_energy_type), POINTER                 :: ex_env
     203              :       TYPE(full_kernel_env_type), TARGET                 :: full_kernel_env, kernel_env_admm_aux
     204              :       TYPE(kernel_env_type)                              :: kernel_env
     205         1424 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos, mos_aux_fit
     206              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     207         1424 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     208         1424 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     209              :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     210              :       TYPE(rixs_control_type), POINTER                   :: rixs_control
     211              :       TYPE(section_vals_type), POINTER                   :: hfxsr_section, kernel_section, &
     212              :                                                             lri_section, soc_section, &
     213              :                                                             tddfpt_print_section, tddfpt_section, &
     214              :                                                             xc_section
     215              :       TYPE(stda_env_type), TARGET                        :: stda_kernel
     216              :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
     217              :       TYPE(tddfpt2_valence_type), POINTER                :: valence_state
     218              :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
     219         1424 :          POINTER                                         :: gs_mos
     220         1424 :       TYPE(tddfpt_subgroup_env_type)                     :: sub_env
     221         1424 :       TYPE(tddfpt_work_matrices)                         :: work_matrices
     222              : 
     223         1424 :       CALL timeset(routineN, handle)
     224              : 
     225         1424 :       NULLIFY (logger)
     226         1424 :       logger => cp_get_default_logger()
     227              : 
     228         1424 :       NULLIFY (tddfpt_section, tddfpt_control)
     229              : 
     230              :       CALL get_qs_env(qs_env, &
     231              :                       dft_control=dft_control, &
     232         1424 :                       do_rixs=do_rixs)
     233         1424 :       do_kpoints = dft_control%nimages > 1
     234              : 
     235         1424 :       IF (do_rixs) THEN
     236           16 :          tddfpt_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%RIXS%TDDFPT")
     237           16 :          NULLIFY (rixs_control, valence_state)
     238           16 :          rixs_control => dft_control%rixs_control
     239           16 :          tddfpt_control => rixs_control%tddfpt2_control
     240           16 :          valence_state => rixs_env%valence_state
     241              :       ELSE
     242         1408 :          tddfpt_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%TDDFPT")
     243         1408 :          tddfpt_control => dft_control%tddfpt2_control
     244              :       END IF
     245              : 
     246              :       ! input section print/xc
     247              :       CALL tddfpt_input(qs_env, tddfpt_section, tddfpt_control, do_hfx, do_admm, do_exck, &
     248              :                         do_hfxsr, do_hfxlr, xc_section, tddfpt_print_section, &
     249         1424 :                         lri_section, hfxsr_section)
     250              : 
     251              :       log_unit = cp_print_key_unit_nr(logger, tddfpt_print_section, "PROGRAM_BANNER", &
     252         1424 :                                       extension=".tddfptLog")
     253              : 
     254         1424 :       tddfpt_control%do_hfx = do_hfx
     255         1424 :       tddfpt_control%do_admm = do_admm
     256         1424 :       tddfpt_control%do_hfxsr = do_hfxsr
     257         1424 :       tddfpt_control%hfxsr_primbas = 0
     258         1424 :       tddfpt_control%hfxsr_re_int = .TRUE.
     259         1424 :       tddfpt_control%do_hfxlr = do_hfxlr
     260         1424 :       tddfpt_control%do_exck = do_exck
     261         1424 :       do_sf = tddfpt_control%spinflip /= no_sf_tddfpt
     262         1424 :       IF (do_sf) CALL cite_reference(Hernandez2025)
     263         1424 :       IF (tddfpt_control%do_hfxlr) THEN
     264            6 :          kernel_section => section_vals_get_subs_vals(tddfpt_section, "XC%HFX_KERNEL%HFXLR")
     265            6 :          CALL section_vals_val_get(kernel_section, "RCUT", r_val=tddfpt_control%hfxlr_rcut)
     266            6 :          CALL section_vals_val_get(kernel_section, "SCALE", r_val=tddfpt_control%hfxlr_scale)
     267              :       END IF
     268              : 
     269         1424 :       soc_section => section_vals_get_subs_vals(tddfpt_section, "SOC")
     270         1424 :       CALL section_vals_get(soc_section, explicit=do_soc)
     271              : 
     272         1424 :       IF (do_soc) THEN
     273              :          ! start with multiplicity that is not specified in input
     274              :          ! so that excited-state gradient is for multiplicity given in input
     275           10 :          lmult_tmp = tddfpt_control%rks_triplets
     276           10 :          tddfpt_control%rks_triplets = .NOT. (tddfpt_control%rks_triplets)
     277              :       END IF
     278              : 
     279         1424 :       CALL cite_reference(Iannuzzi2005)
     280         1424 :       IF (tddfpt_control%kernel == tddfpt_kernel_stda) THEN
     281          440 :          CALL cite_reference(Grimme2013)
     282          440 :          CALL cite_reference(Grimme2016)
     283              :       END IF
     284              : 
     285         1424 :       CALL tddfpt_header(log_unit)
     286         1424 :       CALL kernel_info(log_unit, dft_control, tddfpt_control, xc_section)
     287              : 
     288         1424 :       IF (do_kpoints) THEN
     289            8 :          IF (calc_forces) THEN
     290            0 :             CPABORT("TDDFPT forces are not implemented for k-points")
     291              :          END IF
     292            8 :          IF (do_rixs) THEN
     293            0 :             CPABORT("RIXS/TDDFPT is not implemented for k-points")
     294              :          END IF
     295            8 :          IF (do_soc) THEN
     296            0 :             CPABORT("TDDFPT-SOC is not implemented for k-points")
     297              :          END IF
     298            8 :          CALL tddfpt_kpoint_independent_particle(qs_env, logger, tddfpt_control)
     299              :          CALL cp_print_key_finished_output(log_unit, &
     300              :                                            logger, &
     301              :                                            tddfpt_print_section, &
     302            8 :                                            "PROGRAM_BANNER")
     303            8 :          CALL timestop(handle)
     304            8 :          RETURN
     305              :       END IF
     306              : 
     307              :       CALL get_qs_env(qs_env, &
     308              :                       blacs_env=blacs_env, &
     309              :                       cell=cell, &
     310              :                       matrix_ks=matrix_ks, &
     311              :                       matrix_s=matrix_s, &
     312              :                       mos=mos, &
     313         1416 :                       scf_env=scf_env)
     314              : 
     315              :       ! obtain occupied and virtual (unoccupied) ground-state Kohn-Sham orbitals
     316         1416 :       NULLIFY (gs_mos)
     317         1416 :       CALL tddfpt_init_mos(qs_env, gs_mos, log_unit)
     318              : 
     319              :       ! obtain smeared occupation numbers
     320         1416 :       IF (tddfpt_control%do_smearing) THEN
     321            2 :          CALL tddfpt_smeared_occupation(qs_env, gs_mos, log_unit)
     322              :       END IF
     323              : 
     324              :       ! obtain corrected KS-matrix
     325         1416 :       CALL tddfpt_oecorr(qs_env, gs_mos, matrix_ks_oep)
     326              : 
     327         1416 :       IF ((tddfpt_control%do_lrigpw) .AND. &
     328              :           (tddfpt_control%kernel /= tddfpt_kernel_full)) THEN
     329            0 :          CALL cp_abort(__LOCATION__, "LRI only implemented for full kernel")
     330              :       END IF
     331              : 
     332         1416 :       IF (ASSOCIATED(matrix_ks_oep)) matrix_ks => matrix_ks_oep
     333              : 
     334              :       ! determine active orbitals
     335              :       ! default is all occupied MOs
     336         1416 :       CALL init_res_method(qs_env, gs_mos, tddfpt_control, tddfpt_section, log_unit)
     337              : 
     338              :       ! components of the dipole operator
     339              :       CALL tddfpt_dipole_operator(dipole_op_mos_occ, &
     340              :                                   tddfpt_control, &
     341              :                                   gs_mos, &
     342         1416 :                                   qs_env)
     343              : 
     344         1416 :       nspins = SIZE(gs_mos)
     345              :       ! multiplicity of molecular system
     346         1416 :       IF (nspins > 1) THEN
     347          194 :          mult = ABS(SIZE(gs_mos(1)%evals_occ) - SIZE(gs_mos(2)%evals_occ)) + 1
     348          194 :          IF (mult > 2) THEN
     349           30 :             CALL cp_warn(__LOCATION__, "There is a convergence issue for multiplicity >= 3")
     350              :          END IF
     351              :       ELSE
     352         1222 :          IF (tddfpt_control%rks_triplets) THEN
     353          204 :             mult = 3
     354              :          ELSE
     355         1018 :             mult = 1
     356              :          END IF
     357              :       END IF
     358              : 
     359              :       ! split mpi communicator
     360         8884 :       ALLOCATE (my_mos(nspins), my_active(nspins))
     361         3026 :       DO ispin = 1, nspins
     362         1610 :          my_mos(ispin) = gs_mos(ispin)%mos_occ
     363         3026 :          my_active(ispin) = gs_mos(ispin)%mos_active
     364              :       END DO
     365              :       CALL tddfpt_sub_env_init(sub_env, qs_env, &
     366              :                                mos_occ=my_mos(:), mos_active=my_active(:), &
     367         1416 :                                kernel=tddfpt_control%kernel)
     368         1416 :       DEALLOCATE (my_mos, my_active)
     369              : 
     370         1416 :       IF (tddfpt_control%kernel == tddfpt_kernel_full) THEN
     371              :          ! create environment for Full Kernel
     372          852 :          IF (dft_control%qs_control%xtb) THEN
     373            0 :             CPABORT("TDDFPT: xTB only works with sTDA Kernel")
     374              :          END IF
     375              : 
     376          852 :          IF (tddfpt_control%do_hfxsr) THEN
     377            4 :             kernel_section => section_vals_get_subs_vals(tddfpt_section, "XC%HFX_KERNEL")
     378              :             CALL section_vals_val_get(kernel_section, "HFXSR_PRIMBAS", &
     379            4 :                                       i_val=tddfpt_control%hfxsr_primbas)
     380              :             ! basis set
     381              :             CALL create_minbas_set(qs_env, log_unit, basis_type="TDA_HFX", &
     382            4 :                                    primitive=tddfpt_control%hfxsr_primbas)
     383              :             ! admm control
     384           16 :             ALLOCATE (full_kernel_env%admm_control)
     385            4 :             full_kernel_env%admm_control%purification_method = do_admm_purify_none
     386              :             full_kernel_env%admm_control%method = do_admm_basis_projection
     387              :             full_kernel_env%admm_control%scaling_model = do_admm_exch_scaling_none
     388            4 :             full_kernel_env%admm_control%aux_exch_func = do_admm_aux_exch_func_none
     389              :             ! hfx section
     390            4 :             full_kernel_env%hfxsr_section => hfxsr_section
     391              :             !
     392              :             CALL aux_admm_init(qs_env, mos, full_kernel_env%admm_env, &
     393            4 :                                full_kernel_env%admm_control, "TDA_HFX")
     394              :             CALL get_admm_env(full_kernel_env%admm_env, mos_aux_fit=mos_aux_fit, &
     395              :                               matrix_s_aux_fit=matrix_s_aux_fit, &
     396            4 :                               matrix_s_aux_fit_vs_orb=matrix_s_aux_fit_vs_orb)
     397              :             CALL admm_fit_mo_coeffs(full_kernel_env%admm_env, matrix_s_aux_fit, &
     398            4 :                                     matrix_s_aux_fit_vs_orb, mos, mos_aux_fit, .TRUE.)
     399              :             ! x_data
     400              :             CALL get_qs_env(qs_env, cell=cell, atomic_kind_set=atomic_kind_set, &
     401              :                             qs_kind_set=qs_kind_set, particle_set=particle_set, &
     402            4 :                             para_env=para_env)
     403              :             CALL hfx_create(full_kernel_env%x_data, para_env, hfxsr_section, atomic_kind_set, &
     404            4 :                             qs_kind_set, particle_set, dft_control, cell, orb_basis="TDA_HFX")
     405              :          END IF
     406              : 
     407              :          ! allocate pools and work matrices
     408          852 :          nstates = tddfpt_control%nstates
     409              :          !! Too many states can lead to Problems
     410              :          !! You should be warned if there are more states
     411              :          !! than occ-virt Combinations!!
     412          852 :          CALL cp_fm_get_info(gs_mos(1)%mos_occ, ncol_global=nocc)
     413          852 :          IF (tddfpt_control%spinflip == no_sf_tddfpt) THEN
     414          830 :             CALL cp_fm_get_info(gs_mos(1)%mos_virt, ncol_global=nvirt)
     415              :          ELSE
     416           22 :             CALL cp_fm_get_info(gs_mos(2)%mos_virt, ncol_global=nvirt)
     417              :          END IF
     418          852 :          nstate_max = nocc*nvirt
     419          852 :          IF (nstates > nstate_max) THEN
     420            0 :             CPWARN("NUMBER OF EXCITED STATES COULD LEAD TO PROBLEMS!")
     421            0 :             CPWARN("Experimental: CHANGED NSTATES TO ITS MAXIMUM VALUE!")
     422            0 :             nstates = nstate_max
     423            0 :             tddfpt_control%nstates = nstate_max
     424              :          END IF
     425              :          CALL tddfpt_create_work_matrices(work_matrices, gs_mos, nstates, &
     426          852 :                                           do_hfx, do_admm, do_hfxlr, do_exck, do_sf, qs_env, sub_env)
     427              : 
     428              :          ! create full_kernel and admm_kernel within tddfpt_energies
     429          852 :          kernel_env%full_kernel => full_kernel_env
     430          852 :          kernel_env%admm_kernel => kernel_env_admm_aux
     431          852 :          NULLIFY (kernel_env%stda_kernel)
     432          852 :          IF (do_hfxsr) THEN
     433              :             ! work matrices for SR HFX
     434            4 :             CALL hfxsr_create_work_matrices(work_matrices, qs_env, full_kernel_env%admm_env)
     435              :          END IF
     436          852 :          IF (do_hfxlr) THEN
     437              :             ! calculate S_half and Lowdin MO coefficients
     438            6 :             CALL get_lowdin_mo_coefficients(qs_env, sub_env, work_matrices)
     439              :          END IF
     440          564 :       ELSE IF (tddfpt_control%kernel == tddfpt_kernel_stda) THEN
     441              :          ! setup for kernel_stda outside tddfpt_energies
     442          440 :          CALL cp_fm_get_info(gs_mos(1)%mos_occ, nrow_global=nao)
     443         1320 :          nactive = tddfpt_control%nactive
     444          440 :          CALL allocate_stda_env(qs_env, stda_kernel, nao, nactive)
     445              :          ! sTDA parameters
     446          440 :          CALL stda_init_param(qs_env, stda_kernel, tddfpt_control%stda_control)
     447              :          ! allocate pools and work matrices
     448          440 :          nstates = tddfpt_control%nstates
     449          440 :          CALL stda_create_work_matrices(work_matrices, gs_mos, nstates, qs_env, sub_env)
     450              :          !
     451              :          CALL stda_init_matrices(qs_env, stda_kernel, sub_env, &
     452          440 :                                  work_matrices, tddfpt_control)
     453              :          !
     454          440 :          kernel_env%stda_kernel => stda_kernel
     455          440 :          NULLIFY (kernel_env%full_kernel)
     456          440 :          NULLIFY (kernel_env%admm_kernel)
     457          124 :       ELSE IF (tddfpt_control%kernel == tddfpt_kernel_none) THEN
     458              :          ! allocate pools and work matrices
     459          124 :          nstates = tddfpt_control%nstates
     460          124 :          CALL stda_create_work_matrices(work_matrices, gs_mos, nstates, qs_env, sub_env)
     461          124 :          NULLIFY (kernel_env%full_kernel)
     462          124 :          NULLIFY (kernel_env%admm_kernel)
     463          124 :          NULLIFY (kernel_env%stda_kernel)
     464              :       END IF
     465              : 
     466         1416 :       IF (do_sf) THEN
     467              :          ! only alpha -> beta excitations are considered in spin-flip TDDFT
     468          246 :          ALLOCATE (evects(1, nstates))
     469              :       ELSE
     470        13252 :          ALLOCATE (evects(nspins, nstates))
     471              :       END IF
     472         4248 :       ALLOCATE (evals(nstates))
     473        13520 :       ALLOCATE (S_evects(SIZE(evects, 1), nstates))
     474              : 
     475         5042 :       DO istate = 1, nstates
     476         9272 :          DO ispin = 1, SIZE(evects, 1)
     477              :             CALL fm_pool_create_fm( &
     478              :                work_matrices%fm_pool_ao_mo_active(ispin)%pool, &
     479         7856 :                S_evects(ispin, istate))
     480              :          END DO
     481              :       END DO
     482              : 
     483         1416 :       IF (.NOT. do_soc) THEN
     484              :          ! compute tddfpt excitation energies of multiplicity mult
     485              :          CALL tddfpt_energies(qs_env, nstates, nspins, work_matrices, &
     486              :                               tddfpt_control, logger, tddfpt_print_section, evects, evals, &
     487              :                               gs_mos, tddfpt_section, S_evects, matrix_s, kernel_env, matrix_ks, &
     488              :                               sub_env, ostrength, dipole_op_mos_occ, mult, xc_section, full_kernel_env, &
     489         1406 :                               kernel_env_admm_aux)
     490              :       ELSE
     491              :          CALL tddfpt_soc_energies(qs_env, nstates, work_matrices, &
     492              :                                   tddfpt_control, logger, tddfpt_print_section, &
     493              :                                   evects, evals, ostrength, &
     494              :                                   gs_mos, tddfpt_section, S_evects, matrix_s, kernel_env, matrix_ks, &
     495              :                                   sub_env, dipole_op_mos_occ, lmult_tmp, xc_section, full_kernel_env, &
     496           10 :                                   kernel_env_admm_aux)
     497              :       END IF
     498              : 
     499              :       !print forces for selected states
     500         1416 :       IF (calc_forces) THEN
     501              :          CALL tddfpt_print_forces(qs_env, evects, evals, ostrength, &
     502              :                                   tddfpt_print_section, gs_mos, &
     503          654 :                                   kernel_env, sub_env, work_matrices)
     504              :       END IF
     505              : 
     506              :       ! excited state potential energy surface
     507         1416 :       IF (qs_env%excited_state) THEN
     508         1176 :          IF (sub_env%is_split) THEN
     509              :             CALL cp_abort(__LOCATION__, &
     510              :                           "Excited state forces not possible when states"// &
     511            0 :                           " are distributed to different CPU pools.")
     512              :          END IF
     513              :          ! for gradients unshifted KS matrix
     514         1176 :          IF (ASSOCIATED(matrix_ks_oep)) CALL get_qs_env(qs_env, matrix_ks=matrix_ks)
     515         1176 :          CALL get_qs_env(qs_env, exstate_env=ex_env)
     516         1176 :          state_change = .FALSE.
     517         1176 :          IF (ex_env%state > 0) THEN
     518         1168 :             my_state = ex_env%state
     519            8 :          ELSE IF (ex_env%state < 0) THEN
     520              :             ! state following
     521           32 :             ALLOCATE (my_mos(nspins))
     522           16 :             DO ispin = 1, nspins
     523           16 :                my_mos(ispin) = gs_mos(ispin)%mos_occ
     524              :             END DO
     525            8 :             my_state = ABS(ex_env%state)
     526            8 :             CALL assign_state(qs_env, matrix_s, evects, my_mos, ex_env%wfn_history, my_state)
     527            8 :             DEALLOCATE (my_mos)
     528            8 :             IF (my_state /= ABS(ex_env%state)) THEN
     529            0 :                state_change = .TRUE.
     530            0 :                old_state = ABS(ex_env%state)
     531              :             END IF
     532            8 :             ex_env%state = -my_state
     533              :          ELSE
     534              :             CALL cp_warn(__LOCATION__, &
     535            0 :                          "Active excited state not assigned. Use the first state.")
     536            0 :             my_state = 1
     537              :          END IF
     538         1176 :          CPASSERT(my_state > 0)
     539         1176 :          IF (my_state > nstates) THEN
     540              :             CALL cp_warn(__LOCATION__, &
     541            0 :                          "There were not enough excited states calculated.")
     542            0 :             CPABORT("excited state potential energy surface")
     543              :          END IF
     544              :          !
     545              :          ! energy
     546         1176 :          ex_env%evalue = evals(my_state)
     547              :          ! excitation vector
     548         1176 :          CALL cp_fm_release(ex_env%evect)
     549         4830 :          ALLOCATE (ex_env%evect(SIZE(evects, 1)))
     550         2478 :          DO ispin = 1, SIZE(evects, 1)
     551              :             CALL cp_fm_get_info(matrix=evects(ispin, 1), &
     552         1302 :                                 matrix_struct=matrix_struct)
     553         1302 :             CALL cp_fm_create(ex_env%evect(ispin), matrix_struct)
     554         2478 :             CALL cp_fm_to_fm(evects(ispin, my_state), ex_env%evect(ispin))
     555              :          END DO
     556              : 
     557         1176 :          IF (log_unit > 0) THEN
     558          588 :             gsval = ex_env%wfn_history%gsval
     559          588 :             gsmin = ex_env%wfn_history%gsmin
     560          588 :             xsval = ex_env%wfn_history%xsval
     561          588 :             WRITE (log_unit, "(1X,A,T40,F10.6,A,T62,F10.6,A)") "Ground state orbital alignment:", &
     562         1176 :                gsmin, "[MinVal]", gsval, "[Average]"
     563          588 :             WRITE (log_unit, "(1X,A,T71,F10.6)") "Excitation vector alignment:", xsval
     564          588 :             IF (state_change) THEN
     565              :                WRITE (log_unit, "(1X,A,I5,T60,A14,T76,I5)") &
     566            0 :                   "Target state has been changed from state ", &
     567            0 :                   old_state, " to new state ", my_state
     568              :             END IF
     569          588 :             WRITE (log_unit, "(1X,A,I4,A,F12.5,A)") "Calculate properties for state:", &
     570         1176 :                my_state, "      with excitation energy ", ex_env%evalue*evolt, " eV"
     571              :          END IF
     572              : 
     573              :          ! Calculate response vector
     574         1176 :          IF (calc_forces) THEN
     575              :             CALL tddfpt_forces_main(qs_env, gs_mos, ex_env, kernel_env, &
     576          652 :                                     sub_env, work_matrices)
     577              :          END IF
     578              :       END IF
     579              : 
     580              :       ! share evals, evects and mo_coefs with rixs
     581         1416 :       IF (do_rixs) THEN
     582              :          ! copy evals
     583           16 :          valence_state%nstates = nstates
     584           48 :          ALLOCATE (valence_state%evals(SIZE(evals)))
     585           70 :          valence_state%evals(:) = evals(:)
     586              : 
     587          192 :          ALLOCATE (valence_state%evects(nspins, nstates))
     588           68 :          ALLOCATE (valence_state%mos_active(nspins))
     589           36 :          DO ispin = 1, nspins
     590              :             ! copy evects
     591           94 :             DO istate = 1, nstates
     592              :                CALL cp_fm_get_info(matrix=evects(ispin, istate), &
     593           74 :                                    matrix_struct=matrix_struct)
     594           74 :                CALL cp_fm_create(valence_state%evects(ispin, istate), matrix_struct)
     595           94 :                CALL cp_fm_to_fm(evects(ispin, istate), valence_state%evects(ispin, istate))
     596              :             END DO
     597              :             ! copy mos_occ
     598              :             CALL cp_fm_get_info(matrix=gs_mos(ispin)%mos_active, &
     599           20 :                                 matrix_struct=matrix_struct)
     600           20 :             CALL cp_fm_create(valence_state%mos_active(ispin), matrix_struct)
     601           36 :             CALL cp_fm_to_fm(gs_mos(ispin)%mos_active, valence_state%mos_active(ispin))
     602              :          END DO
     603              :       END IF
     604              : 
     605              :       ! clean up
     606         1416 :       CALL cp_fm_release(evects)
     607         1416 :       CALL cp_fm_release(S_evects)
     608              : 
     609              :       CALL cp_print_key_finished_output(log_unit, &
     610              :                                         logger, &
     611              :                                         tddfpt_print_section, &
     612         1416 :                                         "PROGRAM_BANNER")
     613              : 
     614         1416 :       DEALLOCATE (evals, ostrength)
     615              : 
     616         1416 :       IF (tddfpt_control%kernel == tddfpt_kernel_full) THEN
     617          852 :          IF (do_admm) CALL release_kernel_env(kernel_env%admm_kernel)
     618          852 :          IF (tddfpt_control%do_lrigpw) THEN
     619           10 :             CALL lri_env_release(kernel_env%full_kernel%lri_env)
     620           10 :             DEALLOCATE (kernel_env%full_kernel%lri_env)
     621           10 :             CALL lri_density_release(kernel_env%full_kernel%lri_density)
     622           10 :             DEALLOCATE (kernel_env%full_kernel%lri_density)
     623              :          END IF
     624          852 :          CALL release_kernel_env(kernel_env%full_kernel)
     625          564 :       ELSE IF (tddfpt_control%kernel == tddfpt_kernel_stda) THEN
     626          440 :          CALL deallocate_stda_env(stda_kernel)
     627          124 :       ELSE IF (tddfpt_control%kernel == tddfpt_kernel_none) THEN
     628              :          !
     629              :       ELSE
     630            0 :          CPABORT('Unknown kernel type')
     631              :       END IF
     632         1416 :       CALL tddfpt_release_work_matrices(work_matrices, sub_env)
     633         1416 :       CALL tddfpt_sub_env_release(sub_env)
     634              : 
     635         1416 :       CALL cp_fm_release(dipole_op_mos_occ)
     636              : 
     637         3026 :       DO ispin = nspins, 1, -1
     638         3026 :          CALL tddfpt_release_ground_state_mos(gs_mos(ispin))
     639              :       END DO
     640         1416 :       DEALLOCATE (gs_mos)
     641              : 
     642         1416 :       IF (ASSOCIATED(matrix_ks_oep)) THEN
     643           32 :          CALL dbcsr_deallocate_matrix_set(matrix_ks_oep)
     644              :       END IF
     645              : 
     646         1416 :       CALL timestop(handle)
     647              : 
     648         9968 :    END SUBROUTINE tddfpt
     649              : 
     650              : ! **************************************************************************************************
     651              : !> \brief TDDFPT input
     652              : !> \param qs_env  Quickstep environment
     653              : !> \param tddfpt_section ...
     654              : !> \param tddfpt_control ...
     655              : !> \param do_hfx ...
     656              : !> \param do_admm ...
     657              : !> \param do_exck ...
     658              : !> \param do_hfxsr ...
     659              : !> \param do_hfxlr ...
     660              : !> \param xc_section ...
     661              : !> \param tddfpt_print_section ...
     662              : !> \param lri_section ...
     663              : !> \param hfxsr_section ...
     664              : ! **************************************************************************************************
     665         1424 :    SUBROUTINE tddfpt_input(qs_env, tddfpt_section, tddfpt_control, do_hfx, do_admm, do_exck, &
     666              :                            do_hfxsr, do_hfxlr, xc_section, tddfpt_print_section, lri_section, &
     667              :                            hfxsr_section)
     668              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     669              :       TYPE(section_vals_type), POINTER                   :: tddfpt_section
     670              :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
     671              :       LOGICAL, INTENT(INOUT)                             :: do_hfx, do_admm, do_exck, do_hfxsr, &
     672              :                                                             do_hfxlr
     673              :       TYPE(section_vals_type), POINTER                   :: xc_section, tddfpt_print_section, &
     674              :                                                             lri_section, hfxsr_section
     675              : 
     676              :       CHARACTER(len=20)                                  :: nstates_str
     677              :       LOGICAL                                            :: exar, exf, exgcp, exhf, exhfxk, exk, &
     678              :                                                             explicit, explicit_root, expot, exvdw, &
     679              :                                                             exwfn, found, same_hfx, use_real_wfn
     680              :       REAL(kind=dp)                                      :: C_hf
     681              :       TYPE(dft_control_type), POINTER                    :: dft_control
     682              :       TYPE(kpoint_type), POINTER                         :: kpoints
     683              :       TYPE(section_vals_type), POINTER                   :: hfx_section, hfx_section_gs, input, &
     684              :                                                             print_sub, xc_root, xc_sub
     685              : 
     686         1424 :       NULLIFY (dft_control, input, kpoints)
     687         1424 :       CALL get_qs_env(qs_env, dft_control=dft_control, input=input, kpoints=kpoints)
     688              : 
     689         1424 :       IF (dft_control%nimages > 1) THEN
     690            8 :          IF (tddfpt_control%kernel /= tddfpt_kernel_none) THEN
     691            0 :             CPABORT("TDDFPT with k-points currently supports only KERNEL NONE")
     692              :          END IF
     693            8 :          CALL get_kpoint_info(kpoints, use_real_wfn=use_real_wfn)
     694            8 :          IF (use_real_wfn) THEN
     695            0 :             CPABORT("K-point TDDFPT requires complex wavefunctions")
     696              :          END IF
     697            8 :          IF (tddfpt_control%spinflip /= no_sf_tddfpt) THEN
     698            0 :             CPABORT("Spin-flip TDDFPT is not implemented for k-points")
     699              :          END IF
     700            8 :          IF (tddfpt_control%do_smearing) THEN
     701            0 :             CPABORT("Smeared-occupation TDDFPT is not implemented for k-points")
     702              :          END IF
     703            8 :          IF (tddfpt_control%oe_corr /= oe_none) THEN
     704            0 :             CPABORT("Orbital-energy-corrected TDDFPT is not implemented for k-points")
     705              :          END IF
     706              :          IF (tddfpt_control%dipole_form /= 0 .AND. &
     707            8 :              tddfpt_control%dipole_form /= tddfpt_dipole_velocity .AND. &
     708              :              tddfpt_control%dipole_form /= tddfpt_dipole_scf_moment) THEN
     709            0 :             CPABORT("K-point TDDFPT supports only velocity-form or SCF_MOMENT transition dipoles")
     710              :          END IF
     711              :       END IF
     712              : 
     713         1424 :       IF (tddfpt_control%nstates <= 0) THEN
     714            0 :          CALL integer_to_string(tddfpt_control%nstates, nstates_str)
     715              :          CALL cp_warn(__LOCATION__, "TDDFPT calculation was requested for "// &
     716            0 :                       TRIM(nstates_str)//" excited states: nothing to do.")
     717            0 :          RETURN
     718              :       END IF
     719              : 
     720         1424 :       NULLIFY (tddfpt_print_section)
     721         1424 :       tddfpt_print_section => section_vals_get_subs_vals(tddfpt_section, "PRINT")
     722              : 
     723         1424 :       IF (dft_control%nimages > 1) THEN
     724            8 :          IF (tddfpt_control%do_exciton_descriptors .OR. &
     725              :              tddfpt_control%do_directional_exciton_descriptors) THEN
     726            0 :             CPABORT("Exciton descriptors are not implemented for k-point TDDFPT")
     727              :          END IF
     728            8 :          print_sub => section_vals_get_subs_vals(tddfpt_print_section, "NTO_ANALYSIS")
     729            8 :          CALL section_vals_get(print_sub, explicit=explicit)
     730            8 :          IF (explicit) CPABORT("NTO analysis is not implemented for k-point TDDFPT")
     731            8 :          print_sub => section_vals_get_subs_vals(tddfpt_print_section, "NAMD_PRINT")
     732            8 :          CALL section_vals_get(print_sub, explicit=explicit)
     733            8 :          IF (explicit) CPABORT("NAMD_PRINT is not implemented for k-point TDDFPT")
     734              :       END IF
     735              : 
     736         1424 :       IF (tddfpt_control%kernel == tddfpt_kernel_full) THEN
     737          852 :          NULLIFY (xc_root)
     738          852 :          xc_root => section_vals_get_subs_vals(tddfpt_section, "XC")
     739          852 :          CALL section_vals_get(xc_root, explicit=explicit_root)
     740          852 :          NULLIFY (xc_section)
     741          852 :          IF (explicit_root) THEN
     742              :             ! No ADIABATIC_RESCALING option possible
     743          504 :             NULLIFY (xc_sub)
     744          504 :             xc_sub => section_vals_get_subs_vals(xc_root, "ADIABATIC_RESCALING")
     745          504 :             CALL section_vals_get(xc_sub, explicit=exar)
     746          504 :             IF (exar) THEN
     747            0 :                CALL cp_warn(__LOCATION__, "TDDFPT Kernel with ADIABATIC_RESCALING not possible.")
     748            0 :                CPABORT("TDDFPT Input")
     749              :             END IF
     750              :             ! No GCP_POTENTIAL option possible
     751          504 :             NULLIFY (xc_sub)
     752          504 :             xc_sub => section_vals_get_subs_vals(xc_root, "GCP_POTENTIAL")
     753          504 :             CALL section_vals_get(xc_sub, explicit=exgcp)
     754          504 :             IF (exgcp) THEN
     755            0 :                CALL cp_warn(__LOCATION__, "TDDFPT Kernel with GCP_POTENTIAL not possible.")
     756            0 :                CPABORT("TDDFPT Input")
     757              :             END IF
     758              :             ! No VDW_POTENTIAL option possible
     759          504 :             NULLIFY (xc_sub)
     760          504 :             xc_sub => section_vals_get_subs_vals(xc_root, "VDW_POTENTIAL")
     761          504 :             CALL section_vals_get(xc_sub, explicit=exvdw)
     762          504 :             IF (exvdw) THEN
     763            0 :                CALL cp_warn(__LOCATION__, "TDDFPT Kernel with VDW_POTENTIAL not possible.")
     764            0 :                CPABORT("TDDFPT Input")
     765              :             END IF
     766              :             ! No WF_CORRELATION option possible
     767          504 :             NULLIFY (xc_sub)
     768          504 :             xc_sub => section_vals_get_subs_vals(xc_root, "WF_CORRELATION")
     769          504 :             CALL section_vals_get(xc_sub, explicit=exwfn)
     770          504 :             IF (exwfn) THEN
     771            0 :                CALL cp_warn(__LOCATION__, "TDDFPT Kernel with WF_CORRELATION not possible.")
     772            0 :                CPABORT("TDDFPT Input")
     773              :             END IF
     774              :             ! No XC_POTENTIAL option possible
     775          504 :             NULLIFY (xc_sub)
     776          504 :             xc_sub => section_vals_get_subs_vals(xc_root, "XC_POTENTIAL")
     777          504 :             CALL section_vals_get(xc_sub, explicit=expot)
     778          504 :             IF (expot) THEN
     779            0 :                CALL cp_warn(__LOCATION__, "TDDFPT Kernel with XC_POTENTIAL not possible.")
     780            0 :                CPABORT("TDDFPT Input")
     781              :             END IF
     782              :             !
     783          504 :             NULLIFY (xc_sub)
     784          504 :             xc_sub => section_vals_get_subs_vals(xc_root, "XC_FUNCTIONAL")
     785          504 :             CALL section_vals_get(xc_sub, explicit=exf)
     786          504 :             NULLIFY (xc_sub)
     787          504 :             xc_sub => section_vals_get_subs_vals(xc_root, "XC_KERNEL")
     788          504 :             CALL section_vals_get(xc_sub, explicit=exk)
     789          504 :             IF ((exf .AND. exk) .OR. .NOT. (exf .OR. exk)) THEN
     790            0 :                CALL cp_warn(__LOCATION__, "TDDFPT Kernel needs XC_FUNCTIONAL or XC_KERNEL section.")
     791            0 :                CPABORT("TDDFPT Input")
     792              :             END IF
     793          504 :             NULLIFY (xc_sub)
     794          504 :             xc_sub => section_vals_get_subs_vals(xc_root, "HF")
     795          504 :             CALL section_vals_get(xc_sub, explicit=exhf)
     796          504 :             NULLIFY (xc_sub)
     797          504 :             xc_sub => section_vals_get_subs_vals(xc_root, "HFX_KERNEL")
     798          504 :             CALL section_vals_get(xc_sub, explicit=exhfxk)
     799              :             !
     800          504 :             xc_section => xc_root
     801          504 :             hfx_section => section_vals_get_subs_vals(xc_section, "HF")
     802          504 :             CALL section_vals_get(hfx_section, explicit=do_hfx)
     803          504 :             IF (do_hfx) THEN
     804           24 :                CALL section_vals_val_get(hfx_section, "FRACTION", r_val=C_hf)
     805           24 :                do_hfx = (C_hf /= 0.0_dp)
     806              :             END IF
     807              :             !TDDFPT only works if the kernel has the same HF section as the DFT%XC one
     808          504 :             IF (do_hfx) THEN
     809           24 :                hfx_section_gs => section_vals_get_subs_vals(input, "DFT%XC%HF")
     810           24 :                CALL compare_hfx_sections(hfx_section, hfx_section_gs, same_hfx)
     811           24 :                IF (.NOT. same_hfx) THEN
     812            0 :                   CPABORT("TDDFPT Kernel must use the same HF section as DFT%XC or no HF at all.")
     813              :                END IF
     814              :             END IF
     815              : 
     816          504 :             do_admm = do_hfx .AND. dft_control%do_admm
     817          504 :             IF (do_admm) THEN
     818              :                ! 'admm_env%xc_section_primary' and 'admm_env%xc_section_aux' need to be redefined
     819              :                CALL cp_abort(__LOCATION__, &
     820              :                              "ADMM is not implemented for a TDDFT kernel XC-functional which is different from "// &
     821            0 :                              "the one used for the ground-state calculation. A ground-state 'admm_env' cannot be reused.")
     822              :             END IF
     823              :             ! SET HFX_KERNEL and/or XC_KERNEL
     824          504 :             IF (exk) THEN
     825           12 :                do_exck = .TRUE.
     826              :             ELSE
     827          492 :                do_exck = .FALSE.
     828              :             END IF
     829          504 :             IF (exhfxk) THEN
     830            6 :                xc_sub => section_vals_get_subs_vals(xc_root, "HFX_KERNEL")
     831            6 :                CALL section_vals_val_get(xc_sub, "DO_HFXSR", l_val=do_hfxsr)
     832            6 :                xc_sub => section_vals_get_subs_vals(xc_root, "HFX_KERNEL%HFXLR")
     833            6 :                CALL section_vals_get(xc_sub, explicit=do_hfxlr)
     834              :             ELSE
     835          498 :                do_hfxsr = .FALSE.
     836          498 :                do_hfxlr = .FALSE.
     837              :             END IF
     838              :          ELSE
     839          348 :             xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     840          348 :             hfx_section => section_vals_get_subs_vals(xc_section, "HF")
     841          348 :             CALL section_vals_get(hfx_section, explicit=do_hfx)
     842          348 :             IF (do_hfx) THEN
     843          274 :                CALL section_vals_val_get(hfx_section, "FRACTION", r_val=C_hf)
     844          274 :                do_hfx = (C_hf /= 0.0_dp)
     845              :             END IF
     846          348 :             do_admm = do_hfx .AND. dft_control%do_admm
     847          348 :             do_exck = .FALSE.
     848          348 :             do_hfxsr = .FALSE.
     849          348 :             do_hfxlr = .FALSE.
     850              :          END IF
     851              :       ELSE
     852          572 :          do_hfx = .FALSE.
     853          572 :          do_admm = .FALSE.
     854          572 :          do_exck = .FALSE.
     855          572 :          do_hfxsr = .FALSE.
     856          572 :          do_hfxlr = .FALSE.
     857              :       END IF
     858              : 
     859              :       ! reset rks_triplets if UKS is in use
     860         1424 :       IF (tddfpt_control%rks_triplets .AND. dft_control%nspins > 1) THEN
     861           10 :          tddfpt_control%rks_triplets = .FALSE.
     862           10 :          CALL cp_warn(__LOCATION__, "Keyword RKS_TRIPLETS has been ignored for spin-polarised calculations")
     863              :       END IF
     864              : 
     865              :       ! lri input
     866         1424 :       IF (tddfpt_control%do_lrigpw) THEN
     867           10 :          lri_section => section_vals_get_subs_vals(tddfpt_section, "LRIGPW")
     868              :       END IF
     869              : 
     870              :       ! set defaults for short range HFX
     871         1424 :       NULLIFY (hfxsr_section)
     872         1424 :       IF (do_hfxsr) THEN
     873            4 :          hfxsr_section => section_vals_get_subs_vals(tddfpt_section, "XC%HFX_KERNEL%HF")
     874            4 :          CALL section_vals_get(hfxsr_section, explicit=found)
     875            4 :          IF (.NOT. found) THEN
     876            0 :             CPABORT("HFXSR option needs &HF section defined")
     877              :          END IF
     878            4 :          CALL section_vals_val_get(hfxsr_section, "INTERACTION_POTENTIAL%POTENTIAL_TYPE", explicit=found)
     879            4 :          IF (.NOT. found) THEN
     880              :             CALL section_vals_val_set(hfxsr_section, "INTERACTION_POTENTIAL%POTENTIAL_TYPE", &
     881            4 :                                       i_val=do_potential_truncated)
     882              :          END IF
     883            4 :          CALL section_vals_val_get(hfxsr_section, "INTERACTION_POTENTIAL%CUTOFF_RADIUS", explicit=found)
     884            4 :          IF (.NOT. found) THEN
     885            4 :             CALL section_vals_val_set(hfxsr_section, "INTERACTION_POTENTIAL%CUTOFF_RADIUS", r_val=7.5589_dp)
     886              :          END IF
     887            4 :          CALL section_vals_val_get(hfxsr_section, "RI%_SECTION_PARAMETERS_", l_val=found)
     888            4 :          IF (found) THEN
     889            0 :             CALL cp_abort(__LOCATION__, "Short range TDA kernel with RI not possible")
     890              :          END IF
     891              :       END IF
     892              : 
     893              :    END SUBROUTINE tddfpt_input
     894              : 
     895              : ! **************************************************************************************************
     896              : !> \brief ...
     897              : !> \param log_unit ...
     898              : !> \param dft_control ...
     899              : !> \param tddfpt_control ...
     900              : !> \param xc_section ...
     901              : ! **************************************************************************************************
     902         1424 :    SUBROUTINE kernel_info(log_unit, dft_control, tddfpt_control, xc_section)
     903              :       INTEGER, INTENT(IN)                                :: log_unit
     904              :       TYPE(dft_control_type), POINTER                    :: dft_control
     905              :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
     906              :       TYPE(section_vals_type), POINTER                   :: xc_section
     907              : 
     908              :       CHARACTER(LEN=4)                                   :: ktype
     909              :       LOGICAL                                            :: lsd
     910              : 
     911         1424 :       lsd = (dft_control%nspins > 1)
     912         1424 :       IF (tddfpt_control%kernel == tddfpt_kernel_full) THEN
     913          852 :          ktype = "FULL"
     914          852 :          IF (log_unit > 0) THEN
     915          426 :             WRITE (log_unit, "(T2,A,T77,A4)") "KERNEL|", TRIM(ktype)
     916          426 :             CALL xc_write(log_unit, xc_section, lsd)
     917          426 :             IF (tddfpt_control%do_hfx) THEN
     918          149 :                IF (tddfpt_control%do_admm) THEN
     919           87 :                   WRITE (log_unit, "(T2,A,T62,A19)") "KERNEL|", "ADMM Exact Exchange"
     920           87 :                   IF (tddfpt_control%admm_xc_correction) THEN
     921           67 :                      WRITE (log_unit, "(T2,A,T60,A21)") "KERNEL|", "Apply ADMM Kernel XC Correction"
     922              :                   END IF
     923           87 :                   IF (tddfpt_control%admm_symm) THEN
     924           87 :                      WRITE (log_unit, "(T2,A,T60,A21)") "KERNEL|", "Symmetric ADMM Kernel"
     925              :                   END IF
     926              :                ELSE
     927           62 :                   WRITE (log_unit, "(T2,A,T67,A14)") "KERNEL|", "Exact Exchange"
     928              :                END IF
     929              :             END IF
     930          426 :             IF (tddfpt_control%do_hfxsr) THEN
     931            2 :                WRITE (log_unit, "(T2,A,T43,A38)") "KERNEL|", "Short range HFX approximation"
     932              :             END IF
     933          426 :             IF (tddfpt_control%do_hfxlr) THEN
     934            3 :                WRITE (log_unit, "(T2,A,T43,A38)") "KERNEL|", "Long range HFX approximation"
     935              :             END IF
     936          426 :             IF (tddfpt_control%do_lrigpw) THEN
     937            5 :                WRITE (log_unit, "(T2,A,T42,A39)") "KERNEL|", "LRI approximation of transition density"
     938              :             END IF
     939              :          END IF
     940          572 :       ELSE IF (tddfpt_control%kernel == tddfpt_kernel_stda) THEN
     941          440 :          ktype = "sTDA"
     942          440 :          IF (log_unit > 0) THEN
     943          220 :             WRITE (log_unit, "(T2,A,T77,A4)") "KERNEL|", TRIM(ktype)
     944          220 :             IF (tddfpt_control%stda_control%do_ewald) THEN
     945           53 :                WRITE (log_unit, "(T2,A,T78,A3)") "KERNEL| Coulomb term uses Ewald summation"
     946              :             ELSE
     947          167 :                WRITE (log_unit, "(T2,A,T78,A3)") "KERNEL| Coulomb term uses direct summation (MIC)"
     948              :             END IF
     949          220 :             IF (tddfpt_control%stda_control%do_exchange) THEN
     950          204 :                WRITE (log_unit, "(T2,A,T78,A3)") "KERNEL| Exact exchange term", "YES"
     951          204 :                WRITE (log_unit, "(T2,A,T71,F10.3)") "KERNEL| Short range HFX fraction:", &
     952          408 :                   tddfpt_control%stda_control%hfx_fraction
     953              :             ELSE
     954           16 :                WRITE (log_unit, "(T2,A,T79,A2)") "KERNEL| Exact exchange term", "NO"
     955              :             END IF
     956          220 :             WRITE (log_unit, "(T2,A,T66,E15.3)") "KERNEL| Transition density filter", &
     957          440 :                tddfpt_control%stda_control%eps_td_filter
     958              :          END IF
     959          132 :       ELSE IF (tddfpt_control%kernel == tddfpt_kernel_none) THEN
     960          132 :          ktype = "NONE"
     961          132 :          IF (log_unit > 0) THEN
     962           66 :             WRITE (log_unit, "(T2,A,T77,A4)") "KERNEL|", TRIM(ktype)
     963              :          END IF
     964              :       ELSE
     965              :          !CPABORT("Unknown kernel")
     966              :       END IF
     967              :       !
     968         1424 :       IF (log_unit > 0) THEN
     969          712 :          IF (tddfpt_control%rks_triplets) THEN
     970          102 :             WRITE (log_unit, "(T2,A,T74,A7)") "KERNEL| Spin symmetry of excitations", "Triplet"
     971          610 :          ELSE IF (lsd) THEN
     972              :             ! Spin-conserving excitations where requested
     973           97 :             IF (tddfpt_control%spinflip == no_sf_tddfpt) THEN
     974           86 :                WRITE (log_unit, "(T2,A,T69,A12)") "KERNEL| Spin symmetry of excitations", "Unrestricted"
     975              :                ! Spin-flip excitations with collinear exchange-correlation kernel requested
     976           11 :             ELSE IF (tddfpt_control%spinflip == tddfpt_sf_col) THEN
     977            5 :                WRITE (log_unit, "(T2,A,T72,A9)") "KERNEL| Spin flip", "Collinear"
     978              :                ! Spin-flip excitations with noncollinear exchange-correlation kernel requested
     979            6 :             ELSE IF (tddfpt_control%spinflip == tddfpt_sf_noncol) THEN
     980            6 :                WRITE (log_unit, "(T2,A,T69,A12)") "KERNEL| Spin flip", "Noncollinear"
     981              :             END IF
     982              :          ELSE
     983          513 :             WRITE (log_unit, "(T2,A,T74,A7)") "KERNEL| Spin symmetry of excitations", "Singlet"
     984              :          END IF
     985          712 :          WRITE (log_unit, "(T2,A,T73,I8)") "TDDFPT| Number of states calculated", tddfpt_control%nstates
     986          712 :          WRITE (log_unit, "(T2,A,T73,I8)") "TDDFPT| Number of Davidson iterations", tddfpt_control%niters
     987          712 :          WRITE (log_unit, "(T2,A,T66,E15.3)") "TDDFPT| Davidson iteration convergence", tddfpt_control%conv
     988          712 :          WRITE (log_unit, "(T2,A,T73,I8)") "TDDFPT| Max. number of Krylov space vectors", tddfpt_control%nkvs
     989              :       END IF
     990              : 
     991         1424 :    END SUBROUTINE kernel_info
     992              : 
     993              : ! **************************************************************************************************
     994              : !> \brief Print independent-particle vertical transitions for k-point calculations.
     995              : !> \param qs_env ...
     996              : !> \param logger ...
     997              : !> \param tddfpt_control ...
     998              : ! **************************************************************************************************
     999            8 :    SUBROUTINE tddfpt_kpoint_independent_particle(qs_env, logger, tddfpt_control)
    1000              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1001              :       TYPE(cp_logger_type), POINTER                      :: logger
    1002              :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
    1003              : 
    1004              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_kpoint_independent_particle'
    1005              : 
    1006              :       COMPLEX(KIND=dp), ALLOCATABLE, &
    1007            8 :          DIMENSION(:, :, :, :, :)                        :: kpoint_dipole
    1008              :       INTEGER :: handle, ideriv, ikp, ikp_local, iocc, ispin, istate, itrans, ivirt, log_unit, &
    1009              :          nao, nkp, nkp_local, nspins, nstates, ntrans_kpoint, ntrans_spin, ntrans_total, &
    1010              :          spin_offset, trans_index
    1011            8 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: inds
    1012              :       INTEGER, DIMENSION(2)                              :: kp_range
    1013            8 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
    1014              :       INTEGER, DIMENSION(maxspins)                       :: homo_spin, nao_spin, nmo_spin, nvirt_spin
    1015              :       LOGICAL                                            :: my_kpgrp, use_scf_moment_dipoles
    1016              :       REAL(kind=dp)                                      :: checksum, dipole_im, dipole_re, fsum, &
    1017              :                                                             gap, oscillator_factor, spin_factor
    1018            8 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: eigenvalues_kp, evals, &
    1019            8 :                                                             oscillator_strength, transition_energy
    1020            8 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :)        :: transition_dipole_im, &
    1021            8 :                                                             transition_dipole_re
    1022            8 :       REAL(kind=dp), DIMENSION(:), POINTER               :: eigenvalues, wkp
    1023              :       REAL(kind=dp), DIMENSION(nderivs)                  :: transition_dipole_abs
    1024              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env, blacs_env_all
    1025              :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct, moment_struct
    1026              :       TYPE(cp_fm_type)                                   :: fm_dummy, fm_tmp, mo_coeff_im_global, &
    1027              :                                                             mo_coeff_re_global, moment_im, &
    1028              :                                                             moment_re
    1029              :       TYPE(cp_fm_type), POINTER                          :: mo_coeff_im, mo_coeff_re
    1030            8 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: overlap_deriv
    1031              :       TYPE(dbcsr_type), POINTER                          :: cmatrix, rmatrix
    1032              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1033            8 :       TYPE(kpoint_env_p_type), DIMENSION(:), POINTER     :: kp_env
    1034              :       TYPE(kpoint_env_type), POINTER                     :: kp
    1035              :       TYPE(kpoint_type), POINTER                         :: kpoints
    1036            8 :       TYPE(mo_set_type), DIMENSION(:, :), POINTER        :: mos_kp
    1037              :       TYPE(mp_para_env_type), POINTER                    :: para_env, para_env_inter_kp, para_env_kp
    1038              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1039            8 :          POINTER                                         :: sab_kp, sab_orb
    1040              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1041              : 
    1042            8 :       CALL timeset(routineN, handle)
    1043              : 
    1044            8 :       NULLIFY (blacs_env, blacs_env_all, cell_to_index, cmatrix, dft_control, eigenvalues, &
    1045            8 :                fm_struct, kp, kp_env, kpoints, ks_env, mo_coeff_im, mo_coeff_re, &
    1046            8 :                moment_struct, mos_kp, overlap_deriv, para_env, para_env_inter_kp, para_env_kp, &
    1047            8 :                rmatrix, sab_kp, sab_orb, wkp)
    1048              :       CALL get_qs_env(qs_env, dft_control=dft_control, kpoints=kpoints, ks_env=ks_env, &
    1049            8 :                       sab_orb=sab_orb)
    1050            8 :       CPASSERT(ASSOCIATED(kpoints))
    1051              : 
    1052              :       CALL get_kpoint_info(kpoints, nkp=nkp, kp_range=kp_range, kp_env=kp_env, &
    1053              :                            para_env=para_env, blacs_env_all=blacs_env_all, &
    1054              :                            para_env_inter_kp=para_env_inter_kp, para_env_kp=para_env_kp, &
    1055              :                            blacs_env=blacs_env, wkp=wkp, cell_to_index=cell_to_index, &
    1056            8 :                            sab_nl=sab_kp)
    1057            8 :       CPASSERT(ASSOCIATED(para_env))
    1058            8 :       CPASSERT(ASSOCIATED(para_env_inter_kp))
    1059            8 :       CPASSERT(ASSOCIATED(para_env_kp))
    1060            8 :       CPASSERT(ASSOCIATED(blacs_env_all))
    1061            8 :       CPASSERT(ASSOCIATED(blacs_env))
    1062            8 :       CPASSERT(ASSOCIATED(kp_env))
    1063            8 :       CPASSERT(ASSOCIATED(ks_env))
    1064            8 :       CPASSERT(ASSOCIATED(sab_orb))
    1065            8 :       CPASSERT(ASSOCIATED(sab_kp))
    1066            8 :       CPASSERT(ASSOCIATED(cell_to_index))
    1067              : 
    1068            8 :       nspins = dft_control%nspins
    1069            8 :       nmo_spin = 0
    1070            8 :       homo_spin = 0
    1071            8 :       nao_spin = 0
    1072            8 :       nkp_local = MAX(0, kp_range(2) - kp_range(1) + 1)
    1073            8 :       IF (nkp_local > 0) THEN
    1074            8 :          kp => kp_env(1)%kpoint_env
    1075            8 :          mos_kp => kp%mos
    1076            8 :          CPASSERT(ASSOCIATED(mos_kp))
    1077            8 :          CPASSERT(SIZE(mos_kp, 2) == nspins)
    1078           16 :          DO ispin = 1, nspins
    1079              :             CALL get_mo_set(mos_kp(1, ispin), nmo=nmo_spin(ispin), homo=homo_spin(ispin), &
    1080           16 :                             nao=nao_spin(ispin))
    1081              :          END DO
    1082              :       END IF
    1083            8 :       CALL para_env%max(nmo_spin)
    1084            8 :       CALL para_env%max(homo_spin)
    1085            8 :       CALL para_env%max(nao_spin)
    1086              : 
    1087            8 :       ntrans_kpoint = 0
    1088           16 :       DO ispin = 1, nspins
    1089            8 :          nvirt_spin(ispin) = nmo_spin(ispin) - homo_spin(ispin)
    1090            8 :          IF (homo_spin(ispin) <= 0 .OR. nvirt_spin(ispin) <= 0) THEN
    1091            0 :             CPABORT("At least one occupied and one unoccupied MO are required for k-point TDDFPT")
    1092              :          END IF
    1093           16 :          ntrans_kpoint = ntrans_kpoint + homo_spin(ispin)*nvirt_spin(ispin)
    1094              :       END DO
    1095            8 :       ntrans_total = nkp*ntrans_kpoint
    1096            8 :       IF (ntrans_total <= 0) THEN
    1097            0 :          CPABORT("No independent-particle k-point transitions available")
    1098              :       END IF
    1099              : 
    1100              :       ALLOCATE (transition_energy(ntrans_total), transition_dipole_re(ntrans_total, nderivs), &
    1101              :                 transition_dipole_im(ntrans_total, nderivs), oscillator_strength(ntrans_total), &
    1102           72 :                 inds(ntrans_total))
    1103            8 :       transition_energy = 0.0_dp
    1104            8 :       transition_dipole_re = 0.0_dp
    1105            8 :       transition_dipole_im = 0.0_dp
    1106            8 :       oscillator_strength = 0.0_dp
    1107            8 :       use_scf_moment_dipoles = (tddfpt_control%dipole_form == tddfpt_dipole_scf_moment)
    1108            8 :       IF (use_scf_moment_dipoles) THEN
    1109              :          CALL cp_warn(__LOCATION__, "SCF_MOMENT k-point dipoles use direct SCF MO matrix "// &
    1110            2 :                       "elements; compare folded energy blocks, not individual degenerate states.")
    1111            2 :          CALL qs_moment_kpoints_scf_mos(qs_env, kpoint_dipole)
    1112              :       END IF
    1113              : 
    1114              :       IF (.NOT. use_scf_moment_dipoles) THEN
    1115              :          CALL build_overlap_matrix(ks_env, matrixkp_s=overlap_deriv, nderivative=1, &
    1116              :                                    basis_type_a="ORB", basis_type_b="ORB", sab_nl=sab_orb, &
    1117            6 :                                    ext_kpoints=kpoints)
    1118              : 
    1119            6 :          ALLOCATE (rmatrix, cmatrix)
    1120              :          CALL dbcsr_create(rmatrix, template=overlap_deriv(1, 1)%matrix, &
    1121            6 :                            matrix_type=dbcsr_type_symmetric)
    1122              :          CALL dbcsr_create(cmatrix, template=overlap_deriv(1, 1)%matrix, &
    1123            6 :                            matrix_type=dbcsr_type_antisymmetric)
    1124            6 :          CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_kp)
    1125            6 :          CALL cp_dbcsr_alloc_block_from_nbl(cmatrix, sab_kp)
    1126              :       END IF
    1127              : 
    1128           22 :       DO ikp = 1, nkp
    1129           14 :          my_kpgrp = (ikp >= kp_range(1) .AND. ikp <= kp_range(2))
    1130              :          IF (my_kpgrp) THEN
    1131            8 :             ikp_local = ikp - kp_range(1) + 1
    1132            8 :             kp => kp_env(ikp_local)%kpoint_env
    1133            8 :             mos_kp => kp%mos
    1134              :          ELSE
    1135           14 :             NULLIFY (kp, mos_kp)
    1136              :          END IF
    1137           14 :          spin_offset = 0
    1138           36 :          DO ispin = 1, nspins
    1139           14 :             nao = nao_spin(ispin)
    1140           42 :             ALLOCATE (eigenvalues_kp(nmo_spin(ispin)))
    1141           14 :             eigenvalues_kp = 0.0_dp
    1142              : 
    1143           14 :             IF (.NOT. use_scf_moment_dipoles) THEN
    1144              :                CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nmo_spin(ispin), &
    1145           10 :                                         para_env=para_env, context=blacs_env_all)
    1146           10 :                CALL cp_fm_create(mo_coeff_re_global, fm_struct)
    1147           10 :                CALL cp_fm_create(mo_coeff_im_global, fm_struct)
    1148           10 :                CALL cp_fm_create(fm_tmp, fm_struct)
    1149           10 :                CALL cp_fm_struct_release(fm_struct)
    1150              :                CALL cp_fm_struct_create(moment_struct, nrow_global=nmo_spin(ispin), &
    1151              :                                         ncol_global=nmo_spin(ispin), para_env=para_env, &
    1152           10 :                                         context=blacs_env_all)
    1153           10 :                CALL cp_fm_create(moment_re, moment_struct)
    1154           10 :                CALL cp_fm_create(moment_im, moment_struct)
    1155           10 :                CALL cp_fm_struct_release(moment_struct)
    1156              :             END IF
    1157              : 
    1158           14 :             IF (my_kpgrp) THEN
    1159            8 :                CALL get_mo_set(mos_kp(1, ispin), eigenvalues=eigenvalues)
    1160            8 :                CPASSERT(ASSOCIATED(eigenvalues))
    1161            8 :                IF (para_env_kp%is_source()) THEN
    1162           42 :                   eigenvalues_kp(1:nmo_spin(ispin)) = eigenvalues(1:nmo_spin(ispin))
    1163              :                END IF
    1164            8 :                IF (.NOT. use_scf_moment_dipoles) THEN
    1165            6 :                   CALL get_mo_set(mos_kp(1, ispin), mo_coeff=mo_coeff_re)
    1166            6 :                   CALL get_mo_set(mos_kp(2, ispin), mo_coeff=mo_coeff_im)
    1167            6 :                   CPASSERT(ASSOCIATED(mo_coeff_re))
    1168            6 :                   CPASSERT(ASSOCIATED(mo_coeff_im))
    1169            6 :                   CALL cp_fm_copy_general(mo_coeff_re, mo_coeff_re_global, para_env)
    1170            6 :                   CALL cp_fm_copy_general(mo_coeff_im, mo_coeff_im_global, para_env)
    1171              :                END IF
    1172            6 :             ELSE IF (.NOT. use_scf_moment_dipoles) THEN
    1173            4 :                CALL cp_fm_copy_general(fm_dummy, mo_coeff_re_global, para_env)
    1174            4 :                CALL cp_fm_copy_general(fm_dummy, mo_coeff_im_global, para_env)
    1175              :             END IF
    1176           14 :             CALL para_env%sum(eigenvalues_kp)
    1177              : 
    1178           14 :             spin_factor = 1.0_dp
    1179           14 :             IF (nspins == 1) THEN
    1180           14 :                IF (tddfpt_control%rks_triplets) THEN
    1181              :                   spin_factor = 0.0_dp
    1182              :                ELSE
    1183           14 :                   spin_factor = 2.0_dp
    1184              :                END IF
    1185              :             END IF
    1186              : 
    1187           56 :             DO ideriv = 1, nderivs
    1188           42 :                IF (.NOT. use_scf_moment_dipoles) THEN
    1189           30 :                   CALL dbcsr_set(rmatrix, 0.0_dp)
    1190           30 :                   CALL dbcsr_set(cmatrix, 0.0_dp)
    1191              :                   CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=overlap_deriv, &
    1192              :                                       ispin=ideriv + 1, xkp=kpoints%xkp(:, ikp), &
    1193           30 :                                       cell_to_index=cell_to_index, sab_nl=sab_kp)
    1194              : 
    1195           30 :                   CALL cp_dbcsr_sm_fm_multiply(rmatrix, mo_coeff_re_global, fm_tmp, nmo_spin(ispin))
    1196              :                   CALL parallel_gemm("T", "N", nmo_spin(ispin), nmo_spin(ispin), nao, &
    1197           30 :                                      1.0_dp, mo_coeff_re_global, fm_tmp, 0.0_dp, moment_re)
    1198              :                   CALL parallel_gemm("T", "N", nmo_spin(ispin), nmo_spin(ispin), nao, &
    1199           30 :                                      1.0_dp, mo_coeff_im_global, fm_tmp, 0.0_dp, moment_im)
    1200              : 
    1201           30 :                   CALL cp_dbcsr_sm_fm_multiply(rmatrix, mo_coeff_im_global, fm_tmp, nmo_spin(ispin))
    1202              :                   CALL parallel_gemm("T", "N", nmo_spin(ispin), nmo_spin(ispin), nao, &
    1203           30 :                                      1.0_dp, mo_coeff_re_global, fm_tmp, 1.0_dp, moment_im)
    1204              :                   CALL parallel_gemm("T", "N", nmo_spin(ispin), nmo_spin(ispin), nao, &
    1205           30 :                                      -1.0_dp, mo_coeff_im_global, fm_tmp, 1.0_dp, moment_re)
    1206              : 
    1207           30 :                   CALL cp_dbcsr_sm_fm_multiply(cmatrix, mo_coeff_re_global, fm_tmp, nmo_spin(ispin))
    1208              :                   CALL parallel_gemm("T", "N", nmo_spin(ispin), nmo_spin(ispin), nao, &
    1209           30 :                                      1.0_dp, mo_coeff_re_global, fm_tmp, 1.0_dp, moment_im)
    1210              :                   CALL parallel_gemm("T", "N", nmo_spin(ispin), nmo_spin(ispin), nao, &
    1211           30 :                                      -1.0_dp, mo_coeff_im_global, fm_tmp, 1.0_dp, moment_re)
    1212              : 
    1213           30 :                   CALL cp_dbcsr_sm_fm_multiply(cmatrix, mo_coeff_im_global, fm_tmp, nmo_spin(ispin))
    1214              :                   CALL parallel_gemm("T", "N", nmo_spin(ispin), nmo_spin(ispin), nao, &
    1215           30 :                                      -1.0_dp, mo_coeff_re_global, fm_tmp, 1.0_dp, moment_re)
    1216              :                   CALL parallel_gemm("T", "N", nmo_spin(ispin), nmo_spin(ispin), nao, &
    1217           30 :                                      -1.0_dp, mo_coeff_im_global, fm_tmp, 1.0_dp, moment_im)
    1218              :                END IF
    1219              : 
    1220           98 :                DO iocc = 1, homo_spin(ispin)
    1221          252 :                   DO ivirt = homo_spin(ispin) + 1, nmo_spin(ispin)
    1222              :                      trans_index = (ikp - 1)*ntrans_kpoint + spin_offset + &
    1223          168 :                                    (iocc - 1)*nvirt_spin(ispin) + ivirt - homo_spin(ispin)
    1224          168 :                      gap = eigenvalues_kp(ivirt) - eigenvalues_kp(iocc)
    1225          168 :                      IF (gap <= 0.0_dp) THEN
    1226            0 :                         CPABORT("K-point TDDFPT requires positive occupied-virtual energy gaps")
    1227              :                      END IF
    1228          168 :                      IF (use_scf_moment_dipoles) THEN
    1229           48 :                         oscillator_factor = SQRT(spin_factor*wkp(ikp))
    1230           48 :                         dipole_re = REAL(kpoint_dipole(ispin, ikp, ideriv, iocc, ivirt), KIND=dp)
    1231           48 :                         dipole_im = AIMAG(kpoint_dipole(ispin, ikp, ideriv, iocc, ivirt))
    1232              :                      ELSE
    1233          120 :                         oscillator_factor = SQRT(spin_factor*wkp(ikp))/gap
    1234          120 :                         CALL cp_fm_get_element(moment_re, ivirt, iocc, dipole_re)
    1235          120 :                         CALL cp_fm_get_element(moment_im, ivirt, iocc, dipole_im)
    1236              :                      END IF
    1237          168 :                      transition_dipole_re(trans_index, ideriv) = oscillator_factor*dipole_re
    1238          210 :                      transition_dipole_im(trans_index, ideriv) = oscillator_factor*dipole_im
    1239              :                   END DO
    1240              :                END DO
    1241              :             END DO
    1242              : 
    1243           28 :             DO iocc = 1, homo_spin(ispin)
    1244           84 :                DO ivirt = homo_spin(ispin) + 1, nmo_spin(ispin)
    1245              :                   trans_index = (ikp - 1)*ntrans_kpoint + spin_offset + &
    1246           56 :                                 (iocc - 1)*nvirt_spin(ispin) + ivirt - homo_spin(ispin)
    1247           56 :                   transition_energy(trans_index) = eigenvalues_kp(ivirt) - eigenvalues_kp(iocc)
    1248              :                   oscillator_strength(trans_index) = 2.0_dp/3.0_dp*transition_energy(trans_index)* &
    1249              :                                                      SUM(transition_dipole_re(trans_index, :)**2 + &
    1250          238 :                                                          transition_dipole_im(trans_index, :)**2)
    1251              :                END DO
    1252              :             END DO
    1253           14 :             IF (.NOT. use_scf_moment_dipoles) THEN
    1254           10 :                CALL cp_fm_release(moment_im)
    1255           10 :                CALL cp_fm_release(moment_re)
    1256           10 :                CALL cp_fm_release(fm_tmp)
    1257           10 :                CALL cp_fm_release(mo_coeff_im_global)
    1258           10 :                CALL cp_fm_release(mo_coeff_re_global)
    1259              :             END IF
    1260           14 :             DEALLOCATE (eigenvalues_kp)
    1261           28 :             spin_offset = spin_offset + homo_spin(ispin)*nvirt_spin(ispin)
    1262              :          END DO
    1263              :       END DO
    1264              : 
    1265           64 :       IF (ANY(transition_energy <= 0.0_dp)) THEN
    1266            0 :          CPABORT("K-point TDDFPT KERNEL NONE requires positive occupied-virtual energy gaps")
    1267              :       END IF
    1268              : 
    1269            8 :       CALL sort(transition_energy, ntrans_total, inds)
    1270            8 :       nstates = MIN(tddfpt_control%nstates, ntrans_total)
    1271            8 :       IF (tddfpt_control%nstates > ntrans_total) THEN
    1272            0 :          CPWARN("Requested more TDDFPT states than independent-particle k-point transitions")
    1273              :       END IF
    1274              : 
    1275           24 :       ALLOCATE (evals(nstates))
    1276           22 :       evals(1:nstates) = transition_energy(1:nstates)
    1277           22 :       checksum = SQRT(SUM(evals**2))
    1278              : 
    1279            8 :       log_unit = cp_logger_get_default_io_unit(logger)
    1280            8 :       IF (log_unit > 0) THEN
    1281            4 :          WRITE (log_unit, "(1X,A)") "", &
    1282            4 :             "-------------------------------------------------------------------------------", &
    1283            4 :             "-             TDDFPT K-point Independent-particle Transitions                 -", &
    1284            8 :             "-------------------------------------------------------------------------------"
    1285              :          WRITE (log_unit, "(1X,A)") &
    1286            4 :             "Only KERNEL NONE is active for k-point TDDFPT; transition dipole magnitudes are shown."
    1287            4 :          WRITE (log_unit, '(/,T10,A,T19,A,T37,A,T69,A)') "State", "Excitation", &
    1288            8 :             "Transition dipole (a.u.)", "Oscillator"
    1289            4 :          WRITE (log_unit, '(T10,A,T19,A,T37,A,T49,A,T61,A,T67,A)') "number", "energy (eV)", &
    1290            8 :             "x", "y", "z", "strength (a.u.)"
    1291            4 :          WRITE (log_unit, '(T10,72("-"))')
    1292              :       END IF
    1293              : 
    1294            8 :       fsum = 0.0_dp
    1295           22 :       DO istate = 1, nstates
    1296           14 :          itrans = inds(istate) - 1
    1297           14 :          ikp = itrans/ntrans_kpoint + 1
    1298           14 :          itrans = MOD(itrans, ntrans_kpoint)
    1299           14 :          spin_offset = 0
    1300           14 :          DO ispin = 1, nspins
    1301           14 :             ntrans_spin = homo_spin(ispin)*nvirt_spin(ispin)
    1302           14 :             IF (itrans < spin_offset + ntrans_spin) THEN
    1303           14 :                itrans = itrans - spin_offset
    1304           14 :                iocc = itrans/nvirt_spin(ispin) + 1
    1305           14 :                ivirt = MOD(itrans, nvirt_spin(ispin)) + homo_spin(ispin) + 1
    1306           14 :                EXIT
    1307              :             END IF
    1308            0 :             spin_offset = spin_offset + ntrans_spin
    1309              :          END DO
    1310              : 
    1311           22 :          IF (log_unit > 0) THEN
    1312              :             transition_dipole_abs(1:nderivs) = &
    1313              :                SQRT(transition_dipole_re(inds(istate), 1:nderivs)**2 + &
    1314           28 :                     transition_dipole_im(inds(istate), 1:nderivs)**2)
    1315              :             WRITE (log_unit, '(1X,A,T9,I7,T19,F11.5,T31,3(1X,ES11.4E2),T69,ES12.5E2)') &
    1316            7 :                "TDDFPT|", istate, evals(istate)*evolt, transition_dipole_abs, &
    1317           14 :                oscillator_strength(inds(istate))
    1318            7 :             fsum = fsum + oscillator_strength(inds(istate))**2
    1319              :             WRITE (log_unit, '(1X,A,T18,I7,T28,I7,T38,I7,T50,I7,T62,I7,T74,F10.5)') &
    1320            7 :                "TDDFPT_KPOINT|", istate, ikp, ispin, iocc, ivirt, wkp(ikp)
    1321              :          END IF
    1322              :       END DO
    1323              : 
    1324            8 :       IF (log_unit > 0) THEN
    1325            4 :          WRITE (log_unit, '(/,T2,A,E16.8)') 'TDDFPT : CheckSum E = ', checksum
    1326            4 :          WRITE (log_unit, '(T2,A,E16.8)') 'TDDFPT : CheckSum F = ', SQRT(fsum)
    1327              :          WRITE (log_unit, "(1X,A)") &
    1328            4 :             "-------------------------------------------------------------------------------"
    1329              :       END IF
    1330              : 
    1331            8 :       IF (use_scf_moment_dipoles) THEN
    1332            2 :          DEALLOCATE (kpoint_dipole)
    1333              :       ELSE
    1334            6 :          CALL dbcsr_deallocate_matrix(rmatrix)
    1335            6 :          CALL dbcsr_deallocate_matrix(cmatrix)
    1336            6 :          CALL dbcsr_deallocate_matrix_set(overlap_deriv)
    1337              :       END IF
    1338              : 
    1339            0 :       DEALLOCATE (evals, inds, oscillator_strength, transition_dipole_im, transition_dipole_re, &
    1340            8 :                   transition_energy)
    1341              : 
    1342            8 :       CALL timestop(handle)
    1343              : 
    1344           16 :    END SUBROUTINE tddfpt_kpoint_independent_particle
    1345              : 
    1346              : ! **************************************************************************************************
    1347              : !> \brief The energy calculation has been moved to its own subroutine
    1348              : !> \param qs_env ...
    1349              : !> \param nstates ...
    1350              : !> \param nspins ...
    1351              : !> \param work_matrices ...
    1352              : !> \param tddfpt_control ...
    1353              : !> \param logger ...
    1354              : !> \param tddfpt_print_section ...
    1355              : !> \param evects ...
    1356              : !> \param evals ...
    1357              : !> \param gs_mos ...
    1358              : !> \param tddfpt_section ...
    1359              : !> \param S_evects ...
    1360              : !> \param matrix_s ...
    1361              : !> \param kernel_env ...
    1362              : !> \param matrix_ks ...
    1363              : !> \param sub_env ...
    1364              : !> \param ostrength ...
    1365              : !> \param dipole_op_mos_occ ...
    1366              : !> \param mult ...
    1367              : !> \param xc_section ...
    1368              : !> \param full_kernel_env ...
    1369              : !> \param kernel_env_admm_aux ...
    1370              : ! **************************************************************************************************
    1371         1426 :    SUBROUTINE tddfpt_energies(qs_env, nstates, nspins, work_matrices, &
    1372              :                               tddfpt_control, logger, tddfpt_print_section, evects, evals, &
    1373              :                               gs_mos, tddfpt_section, S_evects, matrix_s, kernel_env, matrix_ks, &
    1374              :                               sub_env, ostrength, dipole_op_mos_occ, mult, xc_section, full_kernel_env, &
    1375              :                               kernel_env_admm_aux)
    1376              : 
    1377              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1378              :       INTEGER                                            :: nstates, nspins
    1379              :       TYPE(tddfpt_work_matrices)                         :: work_matrices
    1380              :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
    1381              :       TYPE(cp_logger_type), POINTER                      :: logger
    1382              :       TYPE(section_vals_type), POINTER                   :: tddfpt_print_section
    1383              :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: evects
    1384              :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: evals
    1385              :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
    1386              :          POINTER                                         :: gs_mos
    1387              :       TYPE(section_vals_type), POINTER                   :: tddfpt_section
    1388              :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: S_evects
    1389              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
    1390              :       TYPE(kernel_env_type)                              :: kernel_env
    1391              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks
    1392              :       TYPE(tddfpt_subgroup_env_type)                     :: sub_env
    1393              :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: ostrength
    1394              :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: dipole_op_mos_occ
    1395              :       INTEGER                                            :: mult
    1396              :       TYPE(section_vals_type), POINTER                   :: xc_section
    1397              :       TYPE(full_kernel_env_type), TARGET                 :: full_kernel_env, kernel_env_admm_aux
    1398              : 
    1399              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'tddfpt_energies'
    1400              : 
    1401              :       CHARACTER(len=20)                                  :: nstates_str
    1402              :       INTEGER                                            :: energy_unit, handle, iter, log_unit, &
    1403              :                                                             niters, nocc, nstate_max, &
    1404              :                                                             nstates_read, nvirt
    1405              :       LOGICAL                                            :: do_admm, do_exck, do_soc, explicit
    1406              :       REAL(kind=dp)                                      :: conv
    1407              :       TYPE(admm_type), POINTER                           :: admm_env
    1408              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
    1409         1426 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks_oep
    1410              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1411              :       TYPE(qs_rho_type), POINTER                         :: rho0_struct
    1412              :       TYPE(section_vals_type), POINTER                   :: lri_section, namd_print_section, &
    1413              :                                                             soc_section
    1414              : 
    1415         1426 :       CALL timeset(routineN, handle)
    1416              : 
    1417         1426 :       CALL get_qs_env(qs_env, dft_control=dft_control)
    1418              : 
    1419         1426 :       NULLIFY (admm_env, matrix_ks_oep)
    1420         1426 :       do_admm = tddfpt_control%do_admm
    1421         1426 :       IF (do_admm) CALL get_qs_env(qs_env, admm_env=admm_env)
    1422              : 
    1423              :       ! setup for full_kernel and admm_kernel within tddfpt_energies due to dependence on multiplicity
    1424         1426 :       IF (tddfpt_control%kernel == tddfpt_kernel_full) THEN
    1425              : 
    1426              :          CALL tddfpt_construct_ground_state_orb_density( &
    1427              :             rho_orb_struct=work_matrices%rho_orb_struct_sub, &
    1428              :             rho_xc_struct=work_matrices%rho_xc_struct_sub, &
    1429              :             is_rks_triplets=tddfpt_control%rks_triplets, &
    1430              :             qs_env=qs_env, sub_env=sub_env, &
    1431          862 :             wfm_rho_orb=work_matrices%rho_ao_orb_fm_sub)
    1432          862 :          IF (dft_control%qs_control%gapw_xc) THEN
    1433           72 :             rho0_struct => work_matrices%rho_xc_struct_sub
    1434              :          ELSE
    1435          790 :             rho0_struct => work_matrices%rho_orb_struct_sub
    1436              :          END IF
    1437              : 
    1438          862 :          IF (do_admm) THEN
    1439              :             ! Full kernel with ADMM
    1440          174 :             IF (tddfpt_control%admm_xc_correction) THEN
    1441              :                CALL create_kernel_env(kernel_env=full_kernel_env, &
    1442              :                                       rho_struct_sub=rho0_struct, &
    1443              :                                       xc_section=admm_env%xc_section_primary, &
    1444              :                                       is_rks_triplets=tddfpt_control%rks_triplets, &
    1445          134 :                                       sub_env=sub_env, qs_env=qs_env)
    1446              :             ELSE
    1447              :                CALL create_kernel_env(kernel_env=full_kernel_env, &
    1448              :                                       rho_struct_sub=rho0_struct, &
    1449              :                                       xc_section=xc_section, &
    1450              :                                       is_rks_triplets=tddfpt_control%rks_triplets, &
    1451           40 :                                       sub_env=sub_env, qs_env=qs_env)
    1452              :             END IF
    1453              : 
    1454              :             CALL tddfpt_construct_aux_fit_density( &
    1455              :                rho_orb_struct=work_matrices%rho_orb_struct_sub, &
    1456              :                rho_aux_fit_struct=work_matrices%rho_aux_fit_struct_sub, &
    1457              :                local_rho_set=sub_env%local_rho_set_admm, &
    1458              :                qs_env=qs_env, sub_env=sub_env, &
    1459              :                wfm_rho_orb=work_matrices%rho_ao_orb_fm_sub, &
    1460              :                wfm_rho_aux_fit=work_matrices%rho_ao_aux_fit_fm_sub, &
    1461          174 :                wfm_aux_orb=work_matrices%wfm_aux_orb_sub)
    1462              : 
    1463              :             CALL create_kernel_env(kernel_env=kernel_env_admm_aux, &
    1464              :                                    rho_struct_sub=work_matrices%rho_aux_fit_struct_sub, &
    1465              :                                    xc_section=admm_env%xc_section_aux, &
    1466              :                                    is_rks_triplets=tddfpt_control%rks_triplets, &
    1467          174 :                                    sub_env=sub_env, qs_env=qs_env)
    1468          174 :             kernel_env%full_kernel => full_kernel_env
    1469          174 :             kernel_env%admm_kernel => kernel_env_admm_aux
    1470              :          ELSE
    1471              :             ! Full kernel
    1472              :             CALL create_kernel_env(kernel_env=full_kernel_env, &
    1473              :                                    rho_struct_sub=rho0_struct, &
    1474              :                                    xc_section=xc_section, &
    1475              :                                    is_rks_triplets=tddfpt_control%rks_triplets, &
    1476          688 :                                    sub_env=sub_env, qs_env=qs_env)
    1477          688 :             kernel_env%full_kernel => full_kernel_env
    1478          688 :             NULLIFY (kernel_env%admm_kernel)
    1479              :          END IF
    1480              :          ! Fxc from kernel definition
    1481          862 :          do_exck = tddfpt_control%do_exck
    1482          862 :          kernel_env%full_kernel%do_exck = do_exck
    1483              :          ! initilize xc kernel
    1484          862 :          IF (do_exck) THEN
    1485              :             CALL create_fxc_kernel(work_matrices%rho_orb_struct_sub, work_matrices%fxc_rspace_sub, &
    1486           12 :                                    xc_section, tddfpt_control%rks_triplets, sub_env, qs_env)
    1487              :          END IF
    1488              :       END IF
    1489              : 
    1490              :       ! lri input
    1491         1426 :       IF (tddfpt_control%do_lrigpw) THEN
    1492           10 :          lri_section => section_vals_get_subs_vals(tddfpt_section, "LRIGPW")
    1493              :          CALL tddfpt2_lri_init(qs_env, kernel_env, lri_section, &
    1494           10 :                                tddfpt_print_section)
    1495              :       END IF
    1496              : 
    1497              :       !! Too many states can lead to Problems
    1498              :       !! You should be warned if there are more states
    1499              :       !! than occ-virt Combinations!!
    1500         1426 :       CALL cp_fm_get_info(gs_mos(1)%mos_occ, ncol_global=nocc)
    1501         1426 :       IF (tddfpt_control%spinflip == no_sf_tddfpt) THEN
    1502         1404 :          CALL cp_fm_get_info(gs_mos(1)%mos_virt, ncol_global=nvirt)
    1503              :       ELSE
    1504           22 :          CALL cp_fm_get_info(gs_mos(2)%mos_virt, ncol_global=nvirt)
    1505              :       END IF
    1506         1426 :       nstate_max = nocc*nvirt
    1507         1426 :       IF ((SIZE(gs_mos, 1) == 2) .AND. (tddfpt_control%spinflip == no_sf_tddfpt)) THEN
    1508          172 :          CALL cp_fm_get_info(gs_mos(2)%mos_occ, ncol_global=nocc)
    1509          172 :          CALL cp_fm_get_info(gs_mos(2)%mos_virt, ncol_global=nvirt)
    1510          172 :          nstate_max = nocc*nvirt + nstate_max
    1511              :       END IF
    1512         1426 :       IF (nstates > nstate_max) THEN
    1513            0 :          CPWARN("NUMBER OF EXCITED STATES COULD LEAD TO PROBLEMS!")
    1514            0 :          CPWARN("Experimental: CHANGED NSTATES TO ITS MAXIMUM VALUE!")
    1515            0 :          nstates = nstate_max
    1516              :       END IF
    1517              : 
    1518         1426 :       soc_section => section_vals_get_subs_vals(tddfpt_section, "SOC")
    1519         1426 :       CALL section_vals_get(soc_section, explicit=do_soc)
    1520              : 
    1521              :       ! reuse Ritz vectors from the previous calculation if available
    1522         1426 :       IF (tddfpt_control%is_restart .AND. .NOT. do_soc) THEN
    1523            6 :          CALL get_qs_env(qs_env, blacs_env=blacs_env)
    1524              : 
    1525              :          nstates_read = tddfpt_read_restart( &
    1526              :                         evects=evects, &
    1527              :                         evals=evals, &
    1528              :                         gs_mos=gs_mos, &
    1529              :                         logger=logger, &
    1530              :                         tddfpt_section=tddfpt_section, &
    1531              :                         tddfpt_print_section=tddfpt_print_section, &
    1532              :                         fm_pool_ao_mo_active=work_matrices%fm_pool_ao_mo_active, &
    1533            6 :                         blacs_env_global=blacs_env)
    1534              :       ELSE
    1535              :          nstates_read = 0
    1536              :       END IF
    1537              : 
    1538              :       ! build the list of missed singly excited states and sort them in ascending order
    1539              :       ! according to their excitation energies
    1540              :       log_unit = cp_print_key_unit_nr(logger, tddfpt_print_section, &
    1541         1426 :                                       "GUESS_VECTORS", extension=".tddfptLog")
    1542              :       CALL tddfpt_guess_vectors(evects=evects, evals=evals, &
    1543              :                                 gs_mos=gs_mos, log_unit=log_unit, tddfpt_control=tddfpt_control, &
    1544              :                                 fm_pool_ao_mo_active=work_matrices%fm_pool_ao_mo_active, &
    1545         1426 :                                 qs_env=qs_env, nspins=nspins)
    1546              :       CALL cp_print_key_finished_output(log_unit, logger, &
    1547         1426 :                                         tddfpt_print_section, "GUESS_VECTORS")
    1548              : 
    1549              :       CALL tddfpt_orthogonalize_psi1_psi0(evects, work_matrices%S_C0_C0T, qs_env, &
    1550         1426 :                                           gs_mos, evals, tddfpt_control, work_matrices%S_C0)
    1551         1426 :       CALL tddfpt_orthonormalize_psi1_psi1(evects, nstates, S_evects, matrix_s(1)%matrix)
    1552              : 
    1553         1426 :       niters = tddfpt_control%niters
    1554         1426 :       IF (niters > 0) THEN
    1555              :          log_unit = cp_print_key_unit_nr(logger, tddfpt_print_section, &
    1556         1426 :                                          "ITERATION_INFO", extension=".tddfptLog")
    1557              :          energy_unit = cp_print_key_unit_nr(logger, &
    1558              :                                             tddfpt_print_section, &
    1559              :                                             "DETAILED_ENERGY", &
    1560         1426 :                                             extension=".tddfptLog")
    1561              : 
    1562         1426 :          IF (log_unit > 0) THEN
    1563          713 :             WRITE (log_unit, "(1X,A)") "", &
    1564          713 :                "-------------------------------------------------------------------------------", &
    1565          713 :                "-                      TDDFPT WAVEFUNCTION OPTIMIZATION                       -", &
    1566         1426 :                "-------------------------------------------------------------------------------"
    1567              : 
    1568          713 :             WRITE (log_unit, '(/,T11,A,T27,A,T40,A,T62,A)') "Step", "Time", "Convergence", "Conv. states"
    1569          713 :             WRITE (log_unit, '(1X,79("-"))')
    1570              :          END IF
    1571              : 
    1572         1426 :          CALL cp_add_iter_level(logger%iter_info, "TDDFT_SCF")
    1573              : 
    1574              :          DO
    1575              :             ! *** perform Davidson iterations ***
    1576              :             conv = tddfpt_davidson_solver( &
    1577              :                    evects=evects, &
    1578              :                    evals=evals, &
    1579              :                    S_evects=S_evects, &
    1580              :                    gs_mos=gs_mos, &
    1581              :                    tddfpt_control=tddfpt_control, &
    1582              :                    matrix_ks=matrix_ks, &
    1583              :                    qs_env=qs_env, &
    1584              :                    kernel_env=kernel_env, &
    1585              :                    sub_env=sub_env, &
    1586              :                    logger=logger, &
    1587              :                    iter_unit=log_unit, &
    1588              :                    energy_unit=energy_unit, &
    1589              :                    tddfpt_print_section=tddfpt_print_section, &
    1590         1528 :                    work_matrices=work_matrices)
    1591              : 
    1592              :             ! at this point at least one of the following conditions are met:
    1593              :             ! a) convergence criteria has been achieved;
    1594              :             ! b) maximum number of iterations has been reached;
    1595              :             ! c) Davidson iterations must be restarted due to lack of Krylov vectors
    1596              : 
    1597         1528 :             CALL cp_iterate(logger%iter_info, increment=0, iter_nr_out=iter)
    1598              :             ! terminate the loop if either (a) or (b) is true ...
    1599         1528 :             IF ((conv <= tddfpt_control%conv) .OR. iter >= niters) EXIT
    1600              : 
    1601              :             ! ... otherwise restart Davidson iterations
    1602          102 :             evals = 0.0_dp
    1603         1528 :             IF (log_unit > 0) THEN
    1604           51 :                WRITE (log_unit, '(1X,25("-"),1X,A,1X,25("-"))') "Restart Davidson iterations"
    1605           51 :                CALL m_flush(log_unit)
    1606              :             END IF
    1607              :          END DO
    1608              : 
    1609              :          ! write TDDFPT restart file at the last iteration if requested to do so
    1610         1426 :          CALL cp_iterate(logger%iter_info, increment=0, last=.TRUE.)
    1611              :          CALL tddfpt_write_restart(evects=evects, &
    1612              :                                    evals=evals, &
    1613              :                                    gs_mos=gs_mos, &
    1614              :                                    logger=logger, &
    1615         1426 :                                    tddfpt_print_section=tddfpt_print_section)
    1616              : 
    1617         1426 :          CALL cp_rm_iter_level(logger%iter_info, "TDDFT_SCF")
    1618              : 
    1619              :          ! print convergence summary
    1620         1426 :          IF (log_unit > 0) THEN
    1621          713 :             CALL integer_to_string(iter, nstates_str)
    1622          713 :             IF (conv <= tddfpt_control%conv) THEN
    1623          713 :                WRITE (log_unit, "(1X,A)") "", &
    1624          713 :                   "-------------------------------------------------------------------------------", &
    1625          713 :                   "-  TDDFPT run converged in "//TRIM(nstates_str)//" iteration(s) ", &
    1626         1426 :                   "-------------------------------------------------------------------------------"
    1627              :             ELSE
    1628            0 :                WRITE (log_unit, "(1X,A)") "", &
    1629            0 :                   "-------------------------------------------------------------------------------", &
    1630            0 :                   "-  TDDFPT run did NOT converge after "//TRIM(nstates_str)//" iteration(s) ", &
    1631            0 :                   "-------------------------------------------------------------------------------"
    1632              :             END IF
    1633              :          END IF
    1634              : 
    1635              :          CALL cp_print_key_finished_output(energy_unit, logger, &
    1636         1426 :                                            tddfpt_print_section, "DETAILED_ENERGY")
    1637              :          CALL cp_print_key_finished_output(log_unit, logger, &
    1638         1426 :                                            tddfpt_print_section, "ITERATION_INFO")
    1639              :       ELSE
    1640              :          CALL cp_warn(__LOCATION__, &
    1641            0 :                       "Skipping TDDFPT wavefunction optimization")
    1642              :       END IF
    1643              : 
    1644              :       IF (ASSOCIATED(matrix_ks_oep)) THEN
    1645              :          IF (tddfpt_control%dipole_form == tddfpt_dipole_velocity) THEN
    1646              :             CALL cp_warn(__LOCATION__, &
    1647              :                          "Transition dipole moments and oscillator strengths are likely to be incorrect "// &
    1648              :                          "when computed using an orbital energy correction XC-potential together with "// &
    1649              :                          "the velocity form of dipole transition integrals")
    1650              :          END IF
    1651              :       END IF
    1652              : 
    1653              :       ! *** print summary information ***
    1654         1426 :       log_unit = cp_logger_get_default_io_unit(logger)
    1655              : 
    1656              :       namd_print_section => section_vals_get_subs_vals( &
    1657              :                             tddfpt_print_section, &
    1658         1426 :                             "NAMD_PRINT")
    1659         1426 :       CALL section_vals_get(namd_print_section, explicit=explicit)
    1660         1426 :       IF (explicit) THEN
    1661              :          CALL tddfpt_write_newtonx_output(evects, &
    1662              :                                           evals, &
    1663              :                                           gs_mos, &
    1664              :                                           logger, &
    1665              :                                           tddfpt_print_section, &
    1666              :                                           matrix_s(1)%matrix, &
    1667              :                                           S_evects, &
    1668            2 :                                           sub_env)
    1669              :       END IF
    1670         4278 :       ALLOCATE (ostrength(nstates))
    1671         1426 :       ostrength = 0.0_dp
    1672              :       CALL tddfpt_print_summary(log_unit, &
    1673              :                                 evects, &
    1674              :                                 evals, &
    1675              :                                 gs_mos, &
    1676              :                                 ostrength, &
    1677              :                                 mult, &
    1678              :                                 dipole_op_mos_occ, &
    1679         1426 :                                 tddfpt_control%dipole_form)
    1680              :       CALL tddfpt_print_excitation_analysis( &
    1681              :          log_unit, &
    1682              :          evects, &
    1683              :          evals, &
    1684              :          gs_mos, &
    1685              :          matrix_s(1)%matrix, &
    1686              :          tddfpt_control%spinflip, &
    1687         1426 :          min_amplitude=tddfpt_control%min_excitation_amplitude)
    1688              :       CALL tddfpt_print_nto_analysis(qs_env, &
    1689              :                                      evects, evals, &
    1690              :                                      ostrength, &
    1691              :                                      gs_mos, &
    1692              :                                      matrix_s(1)%matrix, &
    1693         1426 :                                      tddfpt_print_section)
    1694         1426 :       IF (tddfpt_control%do_exciton_descriptors) THEN
    1695              :          CALL tddfpt_print_exciton_descriptors( &
    1696              :             log_unit, &
    1697              :             evects, &
    1698              :             gs_mos, &
    1699              :             matrix_s(1)%matrix, &
    1700              :             tddfpt_control%do_directional_exciton_descriptors, &
    1701            2 :             qs_env)
    1702              :       END IF
    1703              : 
    1704         1426 :       IF (tddfpt_control%do_lrigpw) THEN
    1705              :          CALL lri_print_stat(qs_env, &
    1706              :                              ltddfpt=.TRUE., &
    1707           10 :                              tddfpt_lri_env=kernel_env%full_kernel%lri_env)
    1708              :       END IF
    1709              : 
    1710         1426 :       CALL timestop(handle)
    1711         5704 :    END SUBROUTINE tddfpt_energies
    1712              : 
    1713              : ! **************************************************************************************************
    1714              : !> \brief Perform singlet and triplet computations for subsequent TDDFPT-SOC calculation.
    1715              : !> \param qs_env  Quickstep environment
    1716              : !> \param nstates number of requested  exited states
    1717              : !> \param work_matrices ...
    1718              : !> \param tddfpt_control ...
    1719              : !> \param logger ...
    1720              : !> \param tddfpt_print_section ...
    1721              : !> \param evects Eigenvector of the requested multiplicity
    1722              : !> \param evals Eigenvalue of the requested multiplicity
    1723              : !> \param ostrength Oscillatorstrength
    1724              : !> \param gs_mos ...
    1725              : !> \param tddfpt_section ...
    1726              : !> \param S_evects ...
    1727              : !> \param matrix_s ...
    1728              : !> \param kernel_env ...
    1729              : !> \param matrix_ks ...
    1730              : !> \param sub_env ...
    1731              : !> \param dipole_op_mos_occ ...
    1732              : !> \param lmult_tmp ...
    1733              : !> \param xc_section ...
    1734              : !> \param full_kernel_env ...
    1735              : !> \param kernel_env_admm_aux ...
    1736              : !> \par History
    1737              : !>    * 02.2023 created [Jan-Robert Vogt]
    1738              : !> \note Based on tddfpt2_methods and xas_tdp_utils.
    1739              : !> \note only the values of one multiplicity will be passed back for force calculations!
    1740              : ! **************************************************************************************************
    1741              : 
    1742           10 :    SUBROUTINE tddfpt_soc_energies(qs_env, nstates, work_matrices, &
    1743              :                                   tddfpt_control, logger, tddfpt_print_section, &
    1744              :                                   evects, evals, ostrength, &
    1745              :                                   gs_mos, tddfpt_section, S_evects, matrix_s, kernel_env, matrix_ks, &
    1746              :                                   sub_env, dipole_op_mos_occ, lmult_tmp, xc_section, full_kernel_env, &
    1747              :                                   kernel_env_admm_aux)
    1748              : 
    1749              :       TYPE(qs_environment_type), INTENT(IN), POINTER     :: qs_env
    1750              :       INTEGER, INTENT(in)                                :: nstates
    1751              :       TYPE(tddfpt_work_matrices)                         :: work_matrices
    1752              :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
    1753              :       TYPE(cp_logger_type), POINTER                      :: logger
    1754              :       TYPE(section_vals_type), POINTER                   :: tddfpt_print_section
    1755              :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: evects
    1756              :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: evals, ostrength
    1757              :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
    1758              :          POINTER                                         :: gs_mos
    1759              :       TYPE(section_vals_type), POINTER                   :: tddfpt_section
    1760              :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: S_evects
    1761              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
    1762              :       TYPE(kernel_env_type)                              :: kernel_env
    1763              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks
    1764              :       TYPE(tddfpt_subgroup_env_type)                     :: sub_env
    1765              :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: dipole_op_mos_occ
    1766              :       LOGICAL, INTENT(in)                                :: lmult_tmp
    1767              :       TYPE(section_vals_type), POINTER                   :: xc_section
    1768              :       TYPE(full_kernel_env_type), TARGET                 :: full_kernel_env, kernel_env_admm_aux
    1769              : 
    1770              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_soc_energies'
    1771              : 
    1772              :       INTEGER                                            :: handle, ispin, istate, log_unit, mult, &
    1773              :                                                             nspins
    1774              :       LOGICAL                                            :: do_sf
    1775           10 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: evals_mult, ostrength_mult
    1776           10 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: evects_mult
    1777              : 
    1778           10 :       CALL timeset(routineN, handle)
    1779              : 
    1780              :       log_unit = cp_print_key_unit_nr(logger, tddfpt_print_section, &
    1781              :                                       "PROGRAM_BANNER", &
    1782           10 :                                       extension=".tddfptLog")
    1783           10 :       CALL tddfpt_soc_header(log_unit)
    1784              : 
    1785           10 :       nspins = SIZE(gs_mos)
    1786           96 :       ALLOCATE (evects_mult(nspins, nstates))
    1787           30 :       ALLOCATE (evals_mult(nstates))
    1788           10 :       do_sf = tddfpt_control%spinflip /= no_sf_tddfpt
    1789              : 
    1790              :       ! First multiplicity
    1791           10 :       IF (lmult_tmp) THEN
    1792            2 :          IF (log_unit > 0) THEN
    1793            1 :             WRITE (log_unit, "(1X,A)") "", &
    1794            1 :                "-------------------------------------------------------------------------------", &
    1795            1 :                "-                      TDDFPT SINGLET ENERGIES                                 -", &
    1796            2 :                "-------------------------------------------------------------------------------"
    1797              :          END IF
    1798            2 :          mult = 1
    1799              :       ELSE
    1800            8 :          IF (log_unit > 0) THEN
    1801            4 :             WRITE (log_unit, "(1X,A)") "", &
    1802            4 :                "-------------------------------------------------------------------------------", &
    1803            4 :                "-                      TDDFPT TRIPLET ENERGIES                                 -", &
    1804            8 :                "-------------------------------------------------------------------------------"
    1805              :          END IF
    1806            8 :          mult = 3
    1807              :       END IF
    1808              : 
    1809              :       CALL tddfpt_energies(qs_env, nstates, nspins, work_matrices, tddfpt_control, logger, &
    1810              :                            tddfpt_print_section, evects_mult, evals_mult, &
    1811              :                            gs_mos, tddfpt_section, S_evects, matrix_s, &
    1812              :                            kernel_env, matrix_ks, sub_env, ostrength_mult, &
    1813              :                            dipole_op_mos_occ, mult, xc_section, full_kernel_env, &
    1814           10 :                            kernel_env_admm_aux)
    1815              : 
    1816              :       ! Clean up in between for full kernel
    1817           10 :       IF (tddfpt_control%kernel == tddfpt_kernel_full) THEN
    1818           10 :          IF (tddfpt_control%do_admm) CALL release_kernel_env(kernel_env%admm_kernel)
    1819           10 :          CALL release_kernel_env(kernel_env%full_kernel)
    1820           10 :          CALL tddfpt_release_work_matrices(work_matrices, sub_env)
    1821              :          CALL tddfpt_create_work_matrices(work_matrices, gs_mos, nstates, &
    1822              :                                           tddfpt_control%do_hfx, &
    1823              :                                           tddfpt_control%do_admm, tddfpt_control%do_hfxlr, &
    1824           10 :                                           tddfpt_control%do_exck, do_sf, qs_env, sub_env)
    1825              :       END IF
    1826              : 
    1827           38 :       DO istate = 1, nstates
    1828           66 :          DO ispin = 1, nspins
    1829           56 :             CALL cp_fm_release(S_evects(ispin, istate))
    1830              :          END DO
    1831              :       END DO
    1832              : 
    1833           38 :       DO istate = 1, nstates
    1834           66 :          DO ispin = 1, nspins
    1835              :             CALL fm_pool_create_fm( &
    1836              :                work_matrices%fm_pool_ao_mo_active(ispin)%pool, &
    1837           56 :                S_evects(ispin, istate))
    1838              :          END DO
    1839              :       END DO
    1840              : 
    1841           10 :       tddfpt_control%rks_triplets = lmult_tmp
    1842              : 
    1843              :       ! Second multiplicity
    1844           10 :       IF (lmult_tmp) THEN
    1845            2 :          IF (log_unit > 0) THEN
    1846            1 :             WRITE (log_unit, "(1X,A)") "", &
    1847            1 :                "                      singlet excitations finished                             ", &
    1848            1 :                "                                                                               ", &
    1849            1 :                "-------------------------------------------------------------------------------", &
    1850            1 :                "-                      TDDFPT TRIPLET ENERGIES                                -", &
    1851            2 :                "-------------------------------------------------------------------------------"
    1852              :          END IF !log_unit
    1853            2 :          mult = 3
    1854              :       ELSE
    1855            8 :          IF (log_unit > 0) THEN
    1856            4 :             WRITE (log_unit, "(1X,A)") "", &
    1857            4 :                "                      triplet excitations finished                             ", &
    1858            4 :                "                                                                               ", &
    1859            4 :                "-------------------------------------------------------------------------------", &
    1860            4 :                "-                      TDDFPT SINGLET ENERGIES                                -", &
    1861            8 :                "-------------------------------------------------------------------------------"
    1862              :          END IF !log_unit
    1863            8 :          mult = 1
    1864              :       END IF
    1865              : 
    1866              :       CALL tddfpt_energies(qs_env, nstates, nspins, work_matrices, tddfpt_control, logger, &
    1867              :                            tddfpt_print_section, evects, evals, &
    1868              :                            gs_mos, tddfpt_section, S_evects, matrix_s, &
    1869              :                            kernel_env, matrix_ks, sub_env, ostrength, &
    1870              :                            dipole_op_mos_occ, mult, xc_section, full_kernel_env, &
    1871           10 :                            kernel_env_admm_aux)
    1872              : 
    1873              :       ! Compute perturbative SOC correction
    1874              :       ! Order should always be singlet triplet in tddfpt_soc
    1875           10 :       IF (lmult_tmp) THEN
    1876            2 :          CALL tddfpt_soc(qs_env, evals_mult, evals, evects_mult, evects, gs_mos) !mult=singlet
    1877              :       ELSE
    1878            8 :          CALL tddfpt_soc(qs_env, evals, evals_mult, evects, evects_mult, gs_mos) !mult=triplet
    1879              :       END IF
    1880              : 
    1881              :       ! deallocate the additional multiplicity
    1882           20 :       DO ispin = 1, SIZE(evects_mult, 1)
    1883           48 :          DO istate = 1, SIZE(evects_mult, 2)
    1884           38 :             CALL cp_fm_release(evects_mult(ispin, istate))
    1885              :          END DO
    1886              :       END DO
    1887           10 :       DEALLOCATE (evects_mult, evals_mult, ostrength_mult)
    1888              : 
    1889           10 :       CALL timestop(handle)
    1890              : 
    1891           20 :    END SUBROUTINE tddfpt_soc_energies
    1892              : 
    1893              : ! **************************************************************************************************
    1894              : !> \brief ...
    1895              : !> \param qs_env ...
    1896              : !> \param gs_mos ...
    1897              : !> \param tddfpt_control ...
    1898              : !> \param tddfpt_section ...
    1899              : !> \param iounit ...
    1900              : ! **************************************************************************************************
    1901         1416 :    SUBROUTINE init_res_method(qs_env, gs_mos, tddfpt_control, tddfpt_section, iounit)
    1902              : 
    1903              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1904              :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
    1905              :          POINTER                                         :: gs_mos
    1906              :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
    1907              :       TYPE(section_vals_type), POINTER                   :: tddfpt_section
    1908              :       INTEGER, INTENT(IN)                                :: iounit
    1909              : 
    1910              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'init_res_method'
    1911              : 
    1912              :       INTEGER                                            :: handle, i, io, ispin, nao, nmo, nmol, &
    1913              :                                                             nspins
    1914         1416 :       INTEGER, ALLOCATABLE, DIMENSION(:, :)              :: orblist
    1915         1416 :       INTEGER, DIMENSION(:), POINTER                     :: mollist
    1916              :       LOGICAL                                            :: do_res, do_sf, ew1, ew2, ew3, ewcut, lms
    1917              :       REAL(KIND=dp)                                      :: eclow, ecup, eint, emo
    1918         1416 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rvint
    1919              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
    1920              :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct
    1921              :       TYPE(section_vals_type), POINTER                   :: res_section
    1922              : 
    1923         1416 :       CALL timeset(routineN, handle)
    1924              : 
    1925         1416 :       res_section => section_vals_get_subs_vals(tddfpt_section, "REDUCED_EXCITATION_SPACE")
    1926         1416 :       CALL section_vals_val_get(res_section, "_SECTION_PARAMETERS_", l_val=do_res)
    1927              : 
    1928              :       ! spin flip TDA
    1929         1416 :       IF (tddfpt_control%spinflip == no_sf_tddfpt) THEN
    1930              :          do_sf = .FALSE.
    1931              :       ELSE
    1932           22 :          do_sf = .TRUE.
    1933              :       END IF
    1934              : 
    1935         1416 :       nspins = SIZE(gs_mos)
    1936         1416 :       IF (.NOT. do_res) THEN
    1937         2994 :          DO ispin = 1, nspins
    1938         1594 :             nmo = gs_mos(ispin)%nmo_occ
    1939         1594 :             tddfpt_control%nactive(ispin) = nmo
    1940         1594 :             gs_mos(ispin)%nmo_active = nmo
    1941         4782 :             ALLOCATE (gs_mos(ispin)%index_active(nmo))
    1942        11106 :             DO i = 1, nmo
    1943         9706 :                gs_mos(ispin)%index_active(i) = i
    1944              :             END DO
    1945              :          END DO
    1946              :       ELSE
    1947           16 :          IF (iounit > 0) THEN
    1948            8 :             WRITE (iounit, "(/,1X,27('='),A,26('='))") ' REDUCED EXCITATION SPACE '
    1949              :          END IF
    1950           16 :          CALL section_vals_val_get(res_section, "ENERGY_WINDOW", explicit=ew1)
    1951           16 :          CALL section_vals_val_get(res_section, "UPPER_ENERGY_CUTOFF", explicit=ew2)
    1952           16 :          CALL section_vals_val_get(res_section, "LOWER_ENERGY_CUTOFF", explicit=ew3)
    1953           16 :          ewcut = (ew1 .OR. ew2 .OR. ew3)
    1954           16 :          CALL section_vals_val_get(res_section, "MOLECULE_LIST", explicit=lms)
    1955              : 
    1956           16 :          CALL section_vals_val_get(res_section, "ENERGY_WINDOW", r_vals=rvint)
    1957           16 :          CPASSERT(SIZE(rvint) == 2)
    1958           16 :          eclow = rvint(1)
    1959           16 :          ecup = rvint(2)
    1960           16 :          CALL section_vals_val_get(res_section, "UPPER_ENERGY_CUTOFF", r_val=eint)
    1961           16 :          ecup = MIN(ecup, eint)
    1962           16 :          CALL section_vals_val_get(res_section, "LOWER_ENERGY_CUTOFF", r_val=eint)
    1963           16 :          eclow = MAX(eclow, eint)
    1964           16 :          IF (ewcut .AND. (iounit > 0)) THEN
    1965            8 :             IF (eclow < -1.E8_dp .AND. ecup > 1.E8_dp) THEN
    1966              :                WRITE (iounit, "(1X,A,T51,A10,T71,A10)") &
    1967            0 :                   'Orbital Energy Window [eV]', "      -Inf", "       Inf"
    1968              :             ELSE IF (eclow < -1.E8_dp) THEN
    1969              :                WRITE (iounit, "(1X,A,T51,A10,T71,F10.4)") &
    1970            3 :                   'Orbital Energy Window [eV]', "      -Inf", evolt*ecup
    1971            5 :             ELSE IF (ecup > 1.E8_dp) THEN
    1972              :                WRITE (iounit, "(1X,A,T51,F10.4,T71,A10)") &
    1973            1 :                   'Orbital Energy Window [eV]', evolt*eclow, "       Inf"
    1974              :             ELSE
    1975              :                WRITE (iounit, "(1X,A,T51,F10.4,T71,F10.4)") &
    1976            4 :                   'Orbital Energy Window [eV]', evolt*eclow, evolt*ecup
    1977              :             END IF
    1978              :          END IF
    1979              : 
    1980           16 :          nmol = 0
    1981           16 :          IF (lms) THEN
    1982            0 :             CALL section_vals_val_get(res_section, "MOLECULE_LIST", i_vals=mollist)
    1983            0 :             nmol = SIZE(mollist)
    1984            0 :             WRITE (iounit, "(1X,A)") 'List of Selected Molecules'
    1985            0 :             WRITE (iounit, "(1X,15(I5))") mollist(1:nmol)
    1986              :          END IF
    1987              : 
    1988           32 :          DO ispin = 1, nspins
    1989           32 :             tddfpt_control%nactive(ispin) = gs_mos(ispin)%nmo_occ
    1990              :          END DO
    1991           48 :          nmo = MAXVAL(tddfpt_control%nactive)
    1992           64 :          ALLOCATE (orblist(nmo, nspins))
    1993           16 :          orblist = 0
    1994              : 
    1995           16 :          IF (lms) THEN
    1996              :             ! ignore for now
    1997            0 :             orblist = 1
    1998            0 :             DO ispin = 1, nspins
    1999            0 :                CPASSERT(.NOT. ASSOCIATED(gs_mos(ispin)%evals_occ_matrix))
    2000              :             END DO
    2001           16 :          ELSE IF (ewcut) THEN
    2002              :             ! Filter orbitals wrt energy window
    2003           32 :             DO ispin = 1, nspins
    2004          122 :                DO i = 1, gs_mos(ispin)%nmo_occ
    2005           90 :                   emo = gs_mos(ispin)%evals_occ(i)
    2006          106 :                   IF (emo > eclow .AND. emo < ecup) orblist(i, ispin) = 1
    2007              :                END DO
    2008              :             END DO
    2009              :          ELSE
    2010            0 :             orblist = 1
    2011              :          END IF
    2012              : 
    2013              :          ! count active orbitals
    2014          122 :          nmo = SUM(orblist)
    2015           16 :          IF (nmo == 0) THEN
    2016            0 :             CPABORT("RSE TDA: no active orbitals selected.")
    2017              :          END IF
    2018           32 :          DO ispin = 1, nspins
    2019          106 :             nmo = SUM(orblist(:, ispin))
    2020           16 :             tddfpt_control%nactive(ispin) = nmo
    2021           16 :             gs_mos(ispin)%nmo_active = nmo
    2022           48 :             ALLOCATE (gs_mos(ispin)%index_active(nmo))
    2023           16 :             io = 0
    2024          122 :             DO i = 1, SIZE(ORBLIST, 1)
    2025          106 :                IF (orblist(i, ispin) == 1) THEN
    2026           32 :                   io = io + 1
    2027           32 :                   gs_mos(ispin)%index_active(io) = i
    2028              :                END IF
    2029              :             END DO
    2030              :          END DO
    2031           16 :          DEALLOCATE (orblist)
    2032              : 
    2033           16 :          IF (lms) THEN
    2034              :             ! output information
    2035              :          ELSE
    2036           16 :             IF (iounit > 0) THEN
    2037            8 :                WRITE (iounit, "(1X,A)") 'List of Selected States'
    2038            8 :                IF (nspins == 1) THEN
    2039            8 :                   WRITE (iounit, "(A,T67,A)") ' Active State      Orbital', 'Orbital Energy'
    2040           24 :                   DO i = 1, gs_mos(1)%nmo_active
    2041           16 :                      io = gs_mos(1)%index_active(i)
    2042           24 :                      WRITE (iounit, "(T8,I6,T21,I6,T61,F20.4)") i, io, gs_mos(1)%evals_occ(io)*evolt
    2043              :                   END DO
    2044              :                ELSE
    2045            0 :                   DO ispin = 1, nspins
    2046            0 :                      WRITE (iounit, "(1X,A,I2)") 'Spin ', ispin
    2047            0 :                      WRITE (iounit, "(A,T67,A)") ' Active State      Orbital', 'Orbital Energy'
    2048            0 :                      DO i = 1, gs_mos(ispin)%nmo_active
    2049            0 :                         io = gs_mos(ispin)%index_active(i)
    2050            0 :                         WRITE (iounit, "(T8,I6,T21,I6,T61,F20.4)") i, io, gs_mos(ispin)%evals_occ(io)*evolt
    2051              :                      END DO
    2052              :                   END DO
    2053              :                END IF
    2054              :             END IF
    2055              :          END IF
    2056              : 
    2057           16 :          IF (do_sf) THEN
    2058            0 :             CPABORT("Restricted Active Space with spin flip TDA NYA")
    2059              :          END IF
    2060              : 
    2061           64 :          IF (iounit > 0) THEN
    2062            8 :             WRITE (iounit, "(1X,79('='))")
    2063              :          END IF
    2064              :       END IF
    2065              : 
    2066              :       ! Allocate mos_active
    2067         3026 :       DO ispin = 1, nspins
    2068         1610 :          CALL get_qs_env(qs_env, blacs_env=blacs_env)
    2069         1610 :          CALL cp_fm_get_info(gs_mos(ispin)%mos_occ, nrow_global=nao)
    2070         1610 :          nmo = gs_mos(ispin)%nmo_active
    2071              :          CALL cp_fm_struct_create(fm_struct, template_fmstruct=gs_mos(ispin)%mos_occ%matrix_struct, &
    2072         1610 :                                   ncol_global=nmo, context=blacs_env)
    2073         1610 :          NULLIFY (gs_mos(ispin)%mos_active)
    2074         1610 :          ALLOCATE (gs_mos(ispin)%mos_active)
    2075         1610 :          CALL cp_fm_create(gs_mos(ispin)%mos_active, fm_struct)
    2076         1610 :          CALL cp_fm_struct_release(fm_struct)
    2077              :          ! copy the active orbitals
    2078         4636 :          IF (gs_mos(ispin)%nmo_active == gs_mos(ispin)%nmo_occ) THEN
    2079         9706 :             DO i = 1, gs_mos(ispin)%nmo_active
    2080         9706 :                CPASSERT(i == gs_mos(ispin)%index_active(i))
    2081              :             END DO
    2082              :             CALL cp_fm_to_fm_submat(gs_mos(ispin)%mos_occ, gs_mos(ispin)%mos_active, &
    2083         1594 :                                     nao, nmo, 1, 1, 1, 1)
    2084              :          ELSE
    2085           48 :             DO i = 1, gs_mos(ispin)%nmo_active
    2086           32 :                io = gs_mos(ispin)%index_active(i)
    2087              :                CALL cp_fm_to_fm_submat(gs_mos(ispin)%mos_occ, gs_mos(ispin)%mos_active, &
    2088           48 :                                        nao, 1, 1, io, 1, i)
    2089              :             END DO
    2090              :          END IF
    2091              :       END DO
    2092              : 
    2093         1416 :       CALL timestop(handle)
    2094              : 
    2095         1416 :    END SUBROUTINE init_res_method
    2096              : 
    2097              : END MODULE qs_tddfpt2_methods
        

Generated by: LCOV version 2.0-1