LCOV - code coverage report
Current view: top level - src - energy_corrections.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:e5b1968) Lines: 1244 1576 78.9 %
Date: 2025-06-05 07:00:53 Functions: 22 23 95.7 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Routines for an energy correction on top of a Kohn-Sham calculation
      10             : !> \par History
      11             : !>       03.2014 created
      12             : !>       09.2019 Moved from KG to Kohn-Sham
      13             : !>       08.2022 Add Density-Corrected DFT methods
      14             : !>       04.2023 Add hybrid functionals for DC-DFT
      15             : !>       10.2024 Add external energy method
      16             : !> \author JGH
      17             : ! **************************************************************************************************
      18             : MODULE energy_corrections
      19             :    USE admm_dm_methods,                 ONLY: admm_dm_calc_rho_aux
      20             :    USE admm_methods,                    ONLY: admm_mo_calc_rho_aux
      21             :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      22             :                                               get_atomic_kind
      23             :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      24             :                                               gto_basis_set_type
      25             :    USE bibliography,                    ONLY: Belleflamme2023,&
      26             :                                               cite_reference
      27             :    USE cell_types,                      ONLY: cell_type,&
      28             :                                               pbc
      29             :    USE core_ae,                         ONLY: build_core_ae
      30             :    USE core_ppl,                        ONLY: build_core_ppl
      31             :    USE core_ppnl,                       ONLY: build_core_ppnl
      32             :    USE cp_blacs_env,                    ONLY: cp_blacs_env_type
      33             :    USE cp_control_types,                ONLY: dft_control_type
      34             :    USE cp_dbcsr_api,                    ONLY: &
      35             :         dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_desymmetrize, dbcsr_distribution_type, &
      36             :         dbcsr_filter, dbcsr_get_info, dbcsr_init_p, dbcsr_multiply, dbcsr_p_type, dbcsr_release, &
      37             :         dbcsr_scale, dbcsr_set, dbcsr_type, dbcsr_type_no_symmetry, dbcsr_type_symmetric
      38             :    USE cp_dbcsr_contrib,                ONLY: dbcsr_dot
      39             :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      40             :    USE cp_dbcsr_operations,             ONLY: copy_dbcsr_to_fm,&
      41             :                                               copy_fm_to_dbcsr,&
      42             :                                               cp_dbcsr_sm_fm_multiply,&
      43             :                                               dbcsr_allocate_matrix_set,&
      44             :                                               dbcsr_deallocate_matrix_set
      45             :    USE cp_files,                        ONLY: close_file,&
      46             :                                               open_file
      47             :    USE cp_fm_basic_linalg,              ONLY: cp_fm_column_scale,&
      48             :                                               cp_fm_triangular_invert
      49             :    USE cp_fm_cholesky,                  ONLY: cp_fm_cholesky_decompose
      50             :    USE cp_fm_diag,                      ONLY: choose_eigv_solver
      51             :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      52             :                                               cp_fm_struct_release,&
      53             :                                               cp_fm_struct_type
      54             :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      55             :                                               cp_fm_init_random,&
      56             :                                               cp_fm_release,&
      57             :                                               cp_fm_set_all,&
      58             :                                               cp_fm_to_fm_triangular,&
      59             :                                               cp_fm_type
      60             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      61             :                                               cp_logger_get_default_unit_nr,&
      62             :                                               cp_logger_type
      63             :    USE cp_output_handling,              ONLY: cp_p_file,&
      64             :                                               cp_print_key_finished_output,&
      65             :                                               cp_print_key_should_output,&
      66             :                                               cp_print_key_unit_nr
      67             :    USE cp_result_methods,               ONLY: cp_results_erase,&
      68             :                                               put_results
      69             :    USE cp_result_types,                 ONLY: cp_result_type
      70             :    USE cp_units,                        ONLY: cp_unit_from_cp2k
      71             :    USE distribution_1d_types,           ONLY: distribution_1d_type
      72             :    USE distribution_2d_types,           ONLY: distribution_2d_type
      73             :    USE dm_ls_scf,                       ONLY: calculate_w_matrix_ls,&
      74             :                                               post_scf_sparsities
      75             :    USE dm_ls_scf_methods,               ONLY: apply_matrix_preconditioner,&
      76             :                                               density_matrix_sign,&
      77             :                                               density_matrix_tc2,&
      78             :                                               density_matrix_trs4,&
      79             :                                               ls_scf_init_matrix_s
      80             :    USE dm_ls_scf_qs,                    ONLY: matrix_ls_create,&
      81             :                                               matrix_ls_to_qs,&
      82             :                                               matrix_qs_to_ls
      83             :    USE dm_ls_scf_types,                 ONLY: ls_scf_env_type
      84             :    USE ec_efield_local,                 ONLY: ec_efield_integrals,&
      85             :                                               ec_efield_local_operator
      86             :    USE ec_env_types,                    ONLY: energy_correction_type
      87             :    USE ec_external,                     ONLY: ec_ext_energy
      88             :    USE ec_methods,                      ONLY: create_kernel,&
      89             :                                               ec_mos_init
      90             :    USE external_potential_types,        ONLY: get_potential,&
      91             :                                               gth_potential_type,&
      92             :                                               sgp_potential_type
      93             :    USE hfx_exx,                         ONLY: add_exx_to_rhs,&
      94             :                                               calculate_exx
      95             :    USE input_constants,                 ONLY: &
      96             :         ec_diagonalization, ec_functional_dc, ec_functional_ext, ec_functional_harris, &
      97             :         ec_matrix_sign, ec_matrix_tc2, ec_matrix_trs4, ec_ot_atomic, ec_ot_diag, ec_ot_gs, &
      98             :         ot_precond_full_single_inverse, ot_precond_solver_default, vdw_pairpot_dftd3, &
      99             :         vdw_pairpot_dftd3bj, xc_vdw_fun_pairpot
     100             :    USE input_section_types,             ONLY: section_get_ival,&
     101             :                                               section_get_lval,&
     102             :                                               section_vals_duplicate,&
     103             :                                               section_vals_get,&
     104             :                                               section_vals_get_subs_vals,&
     105             :                                               section_vals_type,&
     106             :                                               section_vals_val_get,&
     107             :                                               section_vals_val_set
     108             :    USE kinds,                           ONLY: default_path_length,&
     109             :                                               default_string_length,&
     110             :                                               dp
     111             :    USE mao_basis,                       ONLY: mao_generate_basis
     112             :    USE mathlib,                         ONLY: det_3x3
     113             :    USE message_passing,                 ONLY: mp_para_env_type
     114             :    USE molecule_types,                  ONLY: molecule_type
     115             :    USE moments_utils,                   ONLY: get_reference_point
     116             :    USE particle_types,                  ONLY: particle_type
     117             :    USE periodic_table,                  ONLY: ptable
     118             :    USE physcon,                         ONLY: bohr,&
     119             :                                               debye,&
     120             :                                               pascal
     121             :    USE preconditioner,                  ONLY: make_preconditioner
     122             :    USE preconditioner_types,            ONLY: destroy_preconditioner,&
     123             :                                               init_preconditioner,&
     124             :                                               preconditioner_type
     125             :    USE pw_env_types,                    ONLY: pw_env_get,&
     126             :                                               pw_env_type
     127             :    USE pw_grid_types,                   ONLY: pw_grid_type
     128             :    USE pw_methods,                      ONLY: pw_axpy,&
     129             :                                               pw_copy,&
     130             :                                               pw_integral_ab,&
     131             :                                               pw_scale,&
     132             :                                               pw_transfer,&
     133             :                                               pw_zero
     134             :    USE pw_poisson_methods,              ONLY: pw_poisson_solve
     135             :    USE pw_poisson_types,                ONLY: pw_poisson_type
     136             :    USE pw_pool_types,                   ONLY: pw_pool_p_type,&
     137             :                                               pw_pool_type
     138             :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
     139             :                                               pw_r3d_rs_type
     140             :    USE qs_atomic_block,                 ONLY: calculate_atomic_block_dm
     141             :    USE qs_collocate_density,            ONLY: calculate_rho_elec
     142             :    USE qs_core_energies,                ONLY: calculate_ecore_overlap,&
     143             :                                               calculate_ptrace
     144             :    USE qs_density_matrices,             ONLY: calculate_density_matrix,&
     145             :                                               calculate_w_matrix
     146             :    USE qs_dispersion_pairpot,           ONLY: calculate_dispersion_pairpot
     147             :    USE qs_dispersion_types,             ONLY: qs_dispersion_type
     148             :    USE qs_energy_types,                 ONLY: qs_energy_type
     149             :    USE qs_environment_types,            ONLY: get_qs_env,&
     150             :                                               qs_environment_type
     151             :    USE qs_force_types,                  ONLY: qs_force_type,&
     152             :                                               total_qs_force,&
     153             :                                               zero_qs_force
     154             :    USE qs_integrate_potential,          ONLY: integrate_v_core_rspace,&
     155             :                                               integrate_v_rspace
     156             :    USE qs_kind_types,                   ONLY: get_qs_kind,&
     157             :                                               get_qs_kind_set,&
     158             :                                               qs_kind_type
     159             :    USE qs_kinetic,                      ONLY: build_kinetic_matrix
     160             :    USE qs_ks_methods,                   ONLY: calc_rho_tot_gspace
     161             :    USE qs_ks_reference,                 ONLY: ks_ref_potential
     162             :    USE qs_ks_types,                     ONLY: qs_ks_env_type
     163             :    USE qs_mo_methods,                   ONLY: calculate_subspace_eigenvalues,&
     164             :                                               make_basis_sm
     165             :    USE qs_mo_types,                     ONLY: deallocate_mo_set,&
     166             :                                               get_mo_set,&
     167             :                                               mo_set_type
     168             :    USE qs_moments,                      ONLY: build_local_moment_matrix
     169             :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
     170             :    USE qs_neighbor_lists,               ONLY: atom2d_build,&
     171             :                                               atom2d_cleanup,&
     172             :                                               build_neighbor_lists,&
     173             :                                               local_atoms_type,&
     174             :                                               pair_radius_setup
     175             :    USE qs_ot_eigensolver,               ONLY: ot_eigensolver
     176             :    USE qs_overlap,                      ONLY: build_overlap_matrix
     177             :    USE qs_rho_types,                    ONLY: qs_rho_get,&
     178             :                                               qs_rho_type
     179             :    USE qs_vxc,                          ONLY: qs_vxc_create
     180             :    USE response_solver,                 ONLY: response_calculation,&
     181             :                                               response_force
     182             :    USE rtp_admm_methods,                ONLY: rtp_admm_calc_rho_aux
     183             :    USE string_utilities,                ONLY: uppercase
     184             :    USE task_list_methods,               ONLY: generate_qs_task_list
     185             :    USE task_list_types,                 ONLY: allocate_task_list,&
     186             :                                               deallocate_task_list
     187             :    USE trexio_utils,                    ONLY: write_trexio
     188             :    USE virial_methods,                  ONLY: one_third_sum_diag,&
     189             :                                               write_stress_tensor,&
     190             :                                               write_stress_tensor_components
     191             :    USE virial_types,                    ONLY: symmetrize_virial,&
     192             :                                               virial_type,&
     193             :                                               zero_virial
     194             :    USE voronoi_interface,               ONLY: entry_voronoi_or_bqb
     195             : #include "./base/base_uses.f90"
     196             : 
     197             :    IMPLICIT NONE
     198             : 
     199             :    PRIVATE
     200             : 
     201             :    ! Global parameters
     202             : 
     203             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'energy_corrections'
     204             : 
     205             :    PUBLIC :: energy_correction
     206             : 
     207             : CONTAINS
     208             : 
     209             : ! **************************************************************************************************
     210             : !> \brief Energy Correction to a Kohn-Sham simulation
     211             : !>        Available energy corrections: (1) Harris energy functional
     212             : !>                                      (2) Density-corrected DFT
     213             : !>                                      (3) Energy from external source
     214             : !>
     215             : !> \param qs_env ...
     216             : !> \param ec_init ...
     217             : !> \param calculate_forces ...
     218             : !> \par History
     219             : !>       03.2014 created
     220             : !> \author JGH
     221             : ! **************************************************************************************************
     222         966 :    SUBROUTINE energy_correction(qs_env, ec_init, calculate_forces)
     223             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     224             :       LOGICAL, INTENT(IN), OPTIONAL                      :: ec_init, calculate_forces
     225             : 
     226             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'energy_correction'
     227             : 
     228             :       INTEGER                                            :: handle, unit_nr
     229             :       LOGICAL                                            :: my_calc_forces
     230             :       TYPE(cp_logger_type), POINTER                      :: logger
     231             :       TYPE(energy_correction_type), POINTER              :: ec_env
     232             :       TYPE(qs_energy_type), POINTER                      :: energy
     233         966 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: ks_force
     234             :       TYPE(virial_type), POINTER                         :: virial
     235             : 
     236         966 :       CALL timeset(routineN, handle)
     237             : 
     238         966 :       logger => cp_get_default_logger()
     239         966 :       IF (logger%para_env%is_source()) THEN
     240         483 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     241             :       ELSE
     242         483 :          unit_nr = -1
     243             :       END IF
     244             : 
     245         966 :       CALL cite_reference(Belleflamme2023)
     246             : 
     247         966 :       NULLIFY (ec_env)
     248         966 :       CALL get_qs_env(qs_env, ec_env=ec_env)
     249             : 
     250             :       ! Skip energy correction if ground-state is NOT converged
     251         966 :       IF (.NOT. ec_env%do_skip) THEN
     252             : 
     253         966 :          ec_env%should_update = .TRUE.
     254         966 :          IF (PRESENT(ec_init)) ec_env%should_update = ec_init
     255             : 
     256         966 :          my_calc_forces = .FALSE.
     257         966 :          IF (PRESENT(calculate_forces)) my_calc_forces = calculate_forces
     258             : 
     259         966 :          IF (ec_env%should_update) THEN
     260         530 :             ec_env%old_etotal = 0.0_dp
     261         530 :             ec_env%etotal = 0.0_dp
     262         530 :             ec_env%eband = 0.0_dp
     263         530 :             ec_env%ehartree = 0.0_dp
     264         530 :             ec_env%ex = 0.0_dp
     265         530 :             ec_env%exc = 0.0_dp
     266         530 :             ec_env%vhxc = 0.0_dp
     267         530 :             ec_env%edispersion = 0.0_dp
     268         530 :             ec_env%exc_aux_fit = 0.0_dp
     269             : 
     270             :             ! Save total energy of reference calculation
     271         530 :             CALL get_qs_env(qs_env, energy=energy)
     272         530 :             ec_env%old_etotal = energy%total
     273             : 
     274             :          END IF
     275             : 
     276         966 :          IF (my_calc_forces) THEN
     277         436 :             IF (unit_nr > 0) THEN
     278         218 :                WRITE (unit_nr, '(T2,A,A,A,A,A)') "!", REPEAT("-", 25), &
     279         436 :                   " Energy Correction Forces ", REPEAT("-", 26), "!"
     280             :             END IF
     281         436 :             CALL get_qs_env(qs_env, force=ks_force, virial=virial)
     282         436 :             CALL zero_qs_force(ks_force)
     283         436 :             CALL zero_virial(virial, reset=.FALSE.)
     284             :          ELSE
     285         530 :             IF (unit_nr > 0) THEN
     286         265 :                WRITE (unit_nr, '(T2,A,A,A,A,A)') "!", REPEAT("-", 29), &
     287         530 :                   " Energy Correction ", REPEAT("-", 29), "!"
     288             :             END IF
     289             :          END IF
     290             : 
     291             :          ! Perform the energy correction
     292         966 :          CALL energy_correction_low(qs_env, ec_env, my_calc_forces, unit_nr)
     293             : 
     294             :          ! Update total energy in qs environment and amount fo correction
     295         966 :          IF (ec_env%should_update) THEN
     296         530 :             energy%nonscf_correction = ec_env%etotal - ec_env%old_etotal
     297         530 :             energy%total = ec_env%etotal
     298             :          END IF
     299             : 
     300         966 :          IF (.NOT. my_calc_forces .AND. unit_nr > 0) THEN
     301         265 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Energy Correction ", energy%nonscf_correction
     302             :          END IF
     303         966 :          IF (unit_nr > 0) THEN
     304         483 :             WRITE (unit_nr, '(T2,A,A,A)') "!", REPEAT("-", 77), "!"
     305             :          END IF
     306             : 
     307             :       ELSE
     308             : 
     309             :          ! Ground-state energy calculation did not converge,
     310             :          ! do not calculate energy correction
     311           0 :          IF (unit_nr > 0) THEN
     312           0 :             WRITE (unit_nr, '(T2,A,A,A)') "!", REPEAT("-", 77), "!"
     313           0 :             WRITE (unit_nr, '(T2,A,A,A,A,A)') "!", REPEAT("-", 26), &
     314           0 :                " Skip Energy Correction ", REPEAT("-", 27), "!"
     315           0 :             WRITE (unit_nr, '(T2,A,A,A)') "!", REPEAT("-", 77), "!"
     316             :          END IF
     317             : 
     318             :       END IF
     319             : 
     320         966 :       CALL timestop(handle)
     321             : 
     322         966 :    END SUBROUTINE energy_correction
     323             : 
     324             : ! **************************************************************************************************
     325             : !> \brief Energy Correction to a Kohn-Sham simulation
     326             : !>
     327             : !> \param qs_env ...
     328             : !> \param ec_env ...
     329             : !> \param calculate_forces ...
     330             : !> \param unit_nr ...
     331             : !> \par History
     332             : !>       03.2014 created
     333             : !> \author JGH
     334             : ! **************************************************************************************************
     335         966 :    SUBROUTINE energy_correction_low(qs_env, ec_env, calculate_forces, unit_nr)
     336             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     337             :       TYPE(energy_correction_type), POINTER              :: ec_env
     338             :       LOGICAL, INTENT(IN)                                :: calculate_forces
     339             :       INTEGER, INTENT(IN)                                :: unit_nr
     340             : 
     341             :       INTEGER                                            :: ispin, nspins
     342             :       LOGICAL                                            :: debug_f
     343             :       REAL(KIND=dp)                                      :: exc
     344             :       TYPE(dft_control_type), POINTER                    :: dft_control
     345             :       TYPE(pw_env_type), POINTER                         :: pw_env
     346             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     347             : 
     348         966 :       IF (ec_env%should_update) THEN
     349         530 :          CALL ec_build_neighborlist(qs_env, ec_env)
     350             :          CALL ks_ref_potential(qs_env, &
     351             :                                ec_env%vh_rspace, &
     352             :                                ec_env%vxc_rspace, &
     353             :                                ec_env%vtau_rspace, &
     354             :                                ec_env%vadmm_rspace, &
     355         530 :                                ec_env%ehartree, exc)
     356             : 
     357         876 :          SELECT CASE (ec_env%energy_functional)
     358             :          CASE (ec_functional_harris)
     359             : 
     360         346 :             CALL ec_build_core_hamiltonian(qs_env, ec_env)
     361         346 :             CALL ec_build_ks_matrix(qs_env, ec_env)
     362             : 
     363         346 :             IF (ec_env%mao) THEN
     364             :                ! MAO basis
     365           4 :                IF (ASSOCIATED(ec_env%mao_coef)) CALL dbcsr_deallocate_matrix_set(ec_env%mao_coef)
     366           4 :                NULLIFY (ec_env%mao_coef)
     367             :                CALL mao_generate_basis(qs_env, ec_env%mao_coef, ref_basis_set="HARRIS", molecular=.TRUE., &
     368             :                                        max_iter=ec_env%mao_max_iter, eps_grad=ec_env%mao_eps_grad, &
     369           4 :                                        eps1_mao=ec_env%mao_eps1, iolevel=ec_env%mao_iolevel, unit_nr=unit_nr)
     370             :             END IF
     371             : 
     372         346 :             CALL ec_ks_solver(qs_env, ec_env)
     373             : 
     374         346 :             CALL evaluate_ec_core_matrix_traces(qs_env, ec_env)
     375             : 
     376             :          CASE (ec_functional_dc)
     377             : 
     378             :             ! Prepare Density-corrected DFT (DC-DFT) calculation
     379         176 :             CALL ec_dc_energy(qs_env, ec_env, calculate_forces=.FALSE.)
     380             : 
     381             :             ! Rebuild KS matrix with DC-DFT XC functional evaluated in ground-state density.
     382             :             ! KS matrix might contain unwanted contributions
     383             :             ! Calculate Hartree and XC related energies here
     384         176 :             CALL ec_build_ks_matrix(qs_env, ec_env)
     385             : 
     386             :          CASE (ec_functional_ext)
     387             : 
     388           8 :             CALL ec_ext_energy(qs_env, ec_env, calculate_forces=.FALSE.)
     389             : 
     390             :          CASE DEFAULT
     391         530 :             CPABORT("unknown energy correction")
     392             :          END SELECT
     393             : 
     394             :          ! dispersion through pairpotentials
     395         530 :          CALL ec_disp(qs_env, ec_env, calculate_forces=.FALSE.)
     396             : 
     397             :          ! Calculate total energy
     398         530 :          CALL ec_energy(ec_env, unit_nr)
     399             : 
     400             :       END IF
     401             : 
     402         966 :       IF (calculate_forces) THEN
     403             : 
     404         436 :          debug_f = ec_env%debug_forces .OR. ec_env%debug_stress
     405             : 
     406         436 :          CALL ec_disp(qs_env, ec_env, calculate_forces=.TRUE.)
     407             : 
     408         696 :          SELECT CASE (ec_env%energy_functional)
     409             :          CASE (ec_functional_harris)
     410             : 
     411             :             CALL ec_build_core_hamiltonian_force(qs_env, ec_env, &
     412             :                                                  ec_env%matrix_p, &
     413             :                                                  ec_env%matrix_s, &
     414         260 :                                                  ec_env%matrix_w)
     415         260 :             CALL ec_build_ks_matrix_force(qs_env, ec_env)
     416         260 :             IF (ec_env%debug_external) THEN
     417           0 :                CALL write_response_interface(qs_env, ec_env)
     418           0 :                CALL init_response_deriv(qs_env, ec_env)
     419             :             END IF
     420             : 
     421             :          CASE (ec_functional_dc)
     422             : 
     423             :             ! Prepare Density-corrected DFT (DC-DFT) calculation
     424             :             ! by getting ground-state matrices
     425         172 :             CALL ec_dc_energy(qs_env, ec_env, calculate_forces=.TRUE.)
     426             : 
     427             :             CALL ec_build_core_hamiltonian_force(qs_env, ec_env, &
     428             :                                                  ec_env%matrix_p, &
     429             :                                                  ec_env%matrix_s, &
     430         172 :                                                  ec_env%matrix_w)
     431         172 :             CALL ec_dc_build_ks_matrix_force(qs_env, ec_env)
     432         172 :             IF (ec_env%debug_external) THEN
     433           0 :                CALL write_response_interface(qs_env, ec_env)
     434           0 :                CALL init_response_deriv(qs_env, ec_env)
     435             :             END IF
     436             : 
     437             :          CASE (ec_functional_ext)
     438             : 
     439           4 :             CALL init_response_deriv(qs_env, ec_env)
     440           4 :             CALL ec_ext_energy(qs_env, ec_env, calculate_forces=.TRUE.)
     441             : 
     442             :          CASE DEFAULT
     443         436 :             CPABORT("unknown energy correction")
     444             :          END SELECT
     445             : 
     446         436 :          CALL response_calculation(qs_env, ec_env)
     447             : 
     448             :          ! Allocate response density on real space grid for use in properties
     449             :          ! Calculated in response_force
     450         436 :          CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, pw_env=pw_env)
     451         436 :          nspins = dft_control%nspins
     452             : 
     453         436 :          CPASSERT(ASSOCIATED(pw_env))
     454         436 :          CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     455        1744 :          ALLOCATE (ec_env%rhoz_r(nspins))
     456         872 :          DO ispin = 1, nspins
     457         872 :             CALL auxbas_pw_pool%create_pw(ec_env%rhoz_r(ispin))
     458             :          END DO
     459             : 
     460             :          CALL response_force(qs_env, &
     461             :                              vh_rspace=ec_env%vh_rspace, &
     462             :                              vxc_rspace=ec_env%vxc_rspace, &
     463             :                              vtau_rspace=ec_env%vtau_rspace, &
     464             :                              vadmm_rspace=ec_env%vadmm_rspace, &
     465             :                              matrix_hz=ec_env%matrix_hz, &
     466             :                              matrix_pz=ec_env%matrix_z, &
     467             :                              matrix_pz_admm=ec_env%z_admm, &
     468             :                              matrix_wz=ec_env%matrix_wz, &
     469             :                              rhopz_r=ec_env%rhoz_r, &
     470             :                              zehartree=ec_env%ehartree, &
     471             :                              zexc=ec_env%exc, &
     472             :                              zexc_aux_fit=ec_env%exc_aux_fit, &
     473             :                              p_env=ec_env%p_env, &
     474         436 :                              debug=debug_f)
     475             : 
     476         436 :          CALL output_response_deriv(qs_env, ec_env, unit_nr)
     477             : 
     478         436 :          CALL ec_properties(qs_env, ec_env)
     479             : 
     480             :          ! Deallocate Harris density and response density on grid
     481         436 :          IF (ASSOCIATED(ec_env%rhoout_r)) THEN
     482         864 :             DO ispin = 1, nspins
     483         864 :                CALL auxbas_pw_pool%give_back_pw(ec_env%rhoout_r(ispin))
     484             :             END DO
     485         432 :             DEALLOCATE (ec_env%rhoout_r)
     486             :          END IF
     487         436 :          IF (ASSOCIATED(ec_env%rhoz_r)) THEN
     488         872 :             DO ispin = 1, nspins
     489         872 :                CALL auxbas_pw_pool%give_back_pw(ec_env%rhoz_r(ispin))
     490             :             END DO
     491         436 :             DEALLOCATE (ec_env%rhoz_r)
     492             :          END IF
     493             : 
     494             :          ! Deallocate matrices
     495         436 :          IF (ASSOCIATED(ec_env%matrix_ks)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_ks)
     496         436 :          IF (ASSOCIATED(ec_env%matrix_h)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_h)
     497         436 :          IF (ASSOCIATED(ec_env%matrix_s)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_s)
     498         436 :          IF (ASSOCIATED(ec_env%matrix_t)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_t)
     499         436 :          IF (ASSOCIATED(ec_env%matrix_p)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_p)
     500         436 :          IF (ASSOCIATED(ec_env%matrix_w)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_w)
     501         436 :          IF (ASSOCIATED(ec_env%matrix_hz)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_hz)
     502         436 :          IF (ASSOCIATED(ec_env%matrix_wz)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_wz)
     503         436 :          IF (ASSOCIATED(ec_env%matrix_z)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_z)
     504             : 
     505             :       END IF
     506             : 
     507         966 :    END SUBROUTINE energy_correction_low
     508             : 
     509             : ! **************************************************************************************************
     510             : !> \brief Output response information to TREXIO file (for testing external method read in)
     511             : !> \param qs_env ...
     512             : !> \param ec_env ...
     513             : !> \author JHU
     514             : ! **************************************************************************************************
     515           0 :    SUBROUTINE write_response_interface(qs_env, ec_env)
     516             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     517             :       TYPE(energy_correction_type), POINTER              :: ec_env
     518             : 
     519             :       TYPE(section_vals_type), POINTER                   :: section, trexio_section
     520             : 
     521           0 :       section => section_vals_get_subs_vals(qs_env%input, "DFT%PRINT%TREXIO")
     522           0 :       NULLIFY (trexio_section)
     523           0 :       CALL section_vals_duplicate(section, trexio_section)
     524           0 :       CALL section_vals_val_set(trexio_section, "FILENAME", c_val=ec_env%exresp_fn)
     525           0 :       CALL section_vals_val_set(trexio_section, "CARTESIAN", l_val=.FALSE.)
     526           0 :       CALL write_trexio(qs_env, trexio_section, ec_env%matrix_hz)
     527             : 
     528           0 :    END SUBROUTINE write_response_interface
     529             : 
     530             : ! **************************************************************************************************
     531             : !> \brief Initialize arrays for response derivatives
     532             : !> \param qs_env ...
     533             : !> \param ec_env ...
     534             : !> \author JHU
     535             : ! **************************************************************************************************
     536           4 :    SUBROUTINE init_response_deriv(qs_env, ec_env)
     537             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     538             :       TYPE(energy_correction_type), POINTER              :: ec_env
     539             : 
     540             :       INTEGER                                            :: natom
     541           4 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     542           4 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     543             :       TYPE(virial_type), POINTER                         :: virial
     544             : 
     545           4 :       CALL get_qs_env(qs_env, natom=natom)
     546          16 :       ALLOCATE (ec_env%rf(3, natom), ec_env%rferror(3, natom))
     547          44 :       ec_env%rf = 0.0_dp
     548          44 :       ec_env%rferror = 0.0_dp
     549          52 :       ec_env%rpv = 0.0_dp
     550          52 :       ec_env%rpverror = 0.0_dp
     551           4 :       CALL get_qs_env(qs_env, force=force, virial=virial)
     552             : 
     553           4 :       CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
     554           4 :       CALL total_qs_force(ec_env%rf, force, atomic_kind_set)
     555             : 
     556           4 :       IF (virial%pv_availability .AND. (.NOT. virial%pv_numer)) THEN
     557           0 :          ec_env%rpv = virial%pv_virial
     558             :       END IF
     559             : 
     560           4 :    END SUBROUTINE init_response_deriv
     561             : 
     562             : ! **************************************************************************************************
     563             : !> \brief Write the reponse forces to file
     564             : !> \param qs_env ...
     565             : !> \param ec_env ...
     566             : !> \param unit_nr ...
     567             : !> \author JHU
     568             : ! **************************************************************************************************
     569         436 :    SUBROUTINE output_response_deriv(qs_env, ec_env, unit_nr)
     570             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     571             :       TYPE(energy_correction_type), POINTER              :: ec_env
     572             :       INTEGER, INTENT(IN)                                :: unit_nr
     573             : 
     574             :       CHARACTER(LEN=default_string_length)               :: unit_string
     575             :       INTEGER                                            :: funit, ia, natom
     576             :       REAL(KIND=dp)                                      :: fconv
     577         436 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: ftot
     578         436 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     579             :       TYPE(cell_type), POINTER                           :: cell
     580             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     581         436 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     582         436 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     583             :       TYPE(virial_type), POINTER                         :: virial
     584             : 
     585         436 :       IF (ASSOCIATED(ec_env%rf)) THEN
     586           4 :          CALL get_qs_env(qs_env, natom=natom)
     587          12 :          ALLOCATE (ftot(3, natom))
     588          44 :          ftot = 0.0_dp
     589           4 :          CALL get_qs_env(qs_env, force=force, virial=virial, para_env=para_env)
     590             : 
     591           4 :          CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
     592           4 :          CALL total_qs_force(ftot, force, atomic_kind_set)
     593          44 :          ec_env%rf(1:3, 1:natom) = ftot(1:3, 1:natom) - ec_env%rf(1:3, 1:natom)
     594          84 :          CALL para_env%sum(ec_env%rf)
     595           4 :          DEALLOCATE (ftot)
     596             : 
     597           4 :          IF (virial%pv_availability .AND. (.NOT. virial%pv_numer)) THEN
     598           0 :             ec_env%rpv = virial%pv_virial - ec_env%rpv
     599           0 :             CALL para_env%sum(ec_env%rpv)
     600             :          END IF
     601             : 
     602           4 :          CALL get_qs_env(qs_env, particle_set=particle_set, cell=cell)
     603             :          ! Conversion factor a.u. -> GPa
     604           4 :          unit_string = "GPa"
     605           4 :          fconv = cp_unit_from_cp2k(1.0_dp/cell%deth, TRIM(unit_string))
     606           4 :          IF (unit_nr > 0) THEN
     607           2 :             WRITE (unit_nr, '(T2,A)') "Write EXTERNAL Response Derivative: "//TRIM(ec_env%exresult_fn)
     608             : 
     609             :             CALL open_file(ec_env%exresult_fn, file_status="REPLACE", file_form="FORMATTED", &
     610           2 :                            file_action="WRITE", unit_number=funit)
     611           2 :             WRITE (funit, *) "   COORDINATES // RESPONSE FORCES // ERRORS  "
     612           2 :             WRITE (funit, *) "        [Bohr] //  [Hartree/Bohr] //         "
     613           7 :             DO ia = 1, natom
     614          20 :                WRITE (funit, "(3(3F15.8,5x))") particle_set(ia)%r(1:3), &
     615          12 :                   ec_env%rf(1:3, ia), ec_env%rferror(1:3, ia)
     616             :             END DO
     617           2 :             WRITE (funit, *)
     618           2 :             WRITE (funit, *) "   CELL // RESPONSE PRESSURE // ERRORS  "
     619           2 :             WRITE (funit, *) " [Bohr] //             [GPa] //         "
     620           8 :             DO ia = 1, 3
     621           6 :                WRITE (funit, "(3F15.8,5x,3F15.8,5x,3F15.8)") cell%hmat(ia, 1:3), &
     622          32 :                   fconv*ec_env%rpv(ia, 1:3), ec_env%rpverror(ia, 1:3)
     623             :             END DO
     624             : 
     625           2 :             CALL close_file(funit)
     626             :          END IF
     627             :       END IF
     628             : 
     629         440 :    END SUBROUTINE output_response_deriv
     630             : 
     631             : ! **************************************************************************************************
     632             : !> \brief Calculates the traces of the core matrices and the density matrix.
     633             : !> \param qs_env ...
     634             : !> \param ec_env ...
     635             : !> \author Ole Schuett
     636             : !>         adapted for energy correction fbelle
     637             : ! **************************************************************************************************
     638         346 :    SUBROUTINE evaluate_ec_core_matrix_traces(qs_env, ec_env)
     639             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     640             :       TYPE(energy_correction_type), POINTER              :: ec_env
     641             : 
     642             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'evaluate_ec_core_matrix_traces'
     643             : 
     644             :       INTEGER                                            :: handle
     645             :       TYPE(dft_control_type), POINTER                    :: dft_control
     646             :       TYPE(qs_energy_type), POINTER                      :: energy
     647             : 
     648         346 :       CALL timeset(routineN, handle)
     649         346 :       NULLIFY (energy)
     650             : 
     651         346 :       CALL get_qs_env(qs_env, dft_control=dft_control, energy=energy)
     652             : 
     653             :       ! Core hamiltonian energy
     654         346 :       CALL calculate_ptrace(ec_env%matrix_h, ec_env%matrix_p, energy%core, dft_control%nspins)
     655             : 
     656             :       ! kinetic energy
     657         346 :       CALL calculate_ptrace(ec_env%matrix_t, ec_env%matrix_p, energy%kinetic, dft_control%nspins)
     658             : 
     659         346 :       CALL timestop(handle)
     660             : 
     661         346 :    END SUBROUTINE evaluate_ec_core_matrix_traces
     662             : 
     663             : ! **************************************************************************************************
     664             : !> \brief Prepare DC-DFT calculation by copying unaffected ground-state matrices (core Hamiltonian,
     665             : !>        density matrix) into energy correction environment and rebuild the overlap matrix
     666             : !>
     667             : !> \param qs_env ...
     668             : !> \param ec_env ...
     669             : !> \param calculate_forces ...
     670             : !> \par History
     671             : !>      07.2022 created
     672             : !> \author fbelle
     673             : ! **************************************************************************************************
     674         348 :    SUBROUTINE ec_dc_energy(qs_env, ec_env, calculate_forces)
     675             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     676             :       TYPE(energy_correction_type), POINTER              :: ec_env
     677             :       LOGICAL, INTENT(IN)                                :: calculate_forces
     678             : 
     679             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ec_dc_energy'
     680             : 
     681             :       CHARACTER(LEN=default_string_length)               :: headline
     682             :       INTEGER                                            :: handle, ispin, nspins
     683         348 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_h, matrix_p, matrix_s, matrix_w
     684             :       TYPE(dft_control_type), POINTER                    :: dft_control
     685             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     686             :       TYPE(qs_rho_type), POINTER                         :: rho
     687             : 
     688         348 :       CALL timeset(routineN, handle)
     689             : 
     690         348 :       NULLIFY (dft_control, ks_env, matrix_h, matrix_p, matrix_s, matrix_w, rho)
     691             :       CALL get_qs_env(qs_env=qs_env, &
     692             :                       dft_control=dft_control, &
     693             :                       ks_env=ks_env, &
     694             :                       matrix_h_kp=matrix_h, &
     695             :                       matrix_s_kp=matrix_s, &
     696             :                       matrix_w_kp=matrix_w, &
     697         348 :                       rho=rho)
     698         348 :       CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     699         348 :       nspins = dft_control%nspins
     700             : 
     701             :       ! For density-corrected DFT only the ground-state matrices are required
     702             :       ! Comply with ec_env environment for property calculations later
     703             :       CALL build_overlap_matrix(ks_env, matrixkp_s=ec_env%matrix_s, &
     704             :                                 matrix_name="OVERLAP MATRIX", &
     705             :                                 basis_type_a="HARRIS", &
     706             :                                 basis_type_b="HARRIS", &
     707         348 :                                 sab_nl=ec_env%sab_orb)
     708             : 
     709             :       ! Core Hamiltonian matrix
     710         348 :       IF (ASSOCIATED(ec_env%matrix_h)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_h)
     711         348 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_h, 1, 1)
     712         348 :       headline = "CORE HAMILTONIAN MATRIX"
     713         348 :       ALLOCATE (ec_env%matrix_h(1, 1)%matrix)
     714             :       CALL dbcsr_create(ec_env%matrix_h(1, 1)%matrix, name=TRIM(headline), &
     715         348 :                         template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
     716         348 :       CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_h(1, 1)%matrix, ec_env%sab_orb)
     717         348 :       CALL dbcsr_copy(ec_env%matrix_h(1, 1)%matrix, matrix_h(1, 1)%matrix)
     718             : 
     719             :       ! Density matrix
     720         348 :       IF (ASSOCIATED(ec_env%matrix_p)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_p)
     721         348 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_p, nspins, 1)
     722         348 :       headline = "DENSITY MATRIX"
     723         696 :       DO ispin = 1, nspins
     724         348 :          ALLOCATE (ec_env%matrix_p(ispin, 1)%matrix)
     725             :          CALL dbcsr_create(ec_env%matrix_p(ispin, 1)%matrix, name=TRIM(headline), &
     726         348 :                            template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
     727         348 :          CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_p(ispin, 1)%matrix, ec_env%sab_orb)
     728         696 :          CALL dbcsr_copy(ec_env%matrix_p(ispin, 1)%matrix, matrix_p(ispin, 1)%matrix)
     729             :       END DO
     730             : 
     731         348 :       IF (calculate_forces) THEN
     732             : 
     733             :          ! Energy-weighted density matrix
     734         172 :          IF (ASSOCIATED(ec_env%matrix_w)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_w)
     735         172 :          CALL dbcsr_allocate_matrix_set(ec_env%matrix_w, nspins, 1)
     736         172 :          headline = "ENERGY-WEIGHTED DENSITY MATRIX"
     737         344 :          DO ispin = 1, nspins
     738         172 :             ALLOCATE (ec_env%matrix_w(ispin, 1)%matrix)
     739             :             CALL dbcsr_create(ec_env%matrix_w(ispin, 1)%matrix, name=TRIM(headline), &
     740         172 :                               template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
     741         172 :             CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_w(ispin, 1)%matrix, ec_env%sab_orb)
     742         344 :             CALL dbcsr_copy(ec_env%matrix_w(ispin, 1)%matrix, matrix_w(ispin, 1)%matrix)
     743             :          END DO
     744             : 
     745             :       END IF
     746             : 
     747             :       ! External field (nonperiodic case)
     748         348 :       ec_env%efield_nuclear = 0.0_dp
     749         348 :       ec_env%efield_elec = 0.0_dp
     750         348 :       CALL ec_efield_local_operator(qs_env, ec_env, calculate_forces=.FALSE.)
     751             : 
     752         348 :       CALL timestop(handle)
     753             : 
     754         348 :    END SUBROUTINE ec_dc_energy
     755             : 
     756             : ! **************************************************************************************************
     757             : !> \brief Kohn-Sham matrix contributions to force in DC-DFT
     758             : !>        also calculate right-hand-side matrix B for response equations AX=B
     759             : !> \param qs_env ...
     760             : !> \param ec_env ...
     761             : !> \par History
     762             : !>      08.2022 adapted from qs_ks_build_kohn_sham_matrix
     763             : !> \author fbelle
     764             : ! **************************************************************************************************
     765         172 :    SUBROUTINE ec_dc_build_ks_matrix_force(qs_env, ec_env)
     766             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     767             :       TYPE(energy_correction_type), POINTER              :: ec_env
     768             : 
     769             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_dc_build_ks_matrix_force'
     770             : 
     771             :       CHARACTER(LEN=default_string_length)               :: unit_string
     772             :       INTEGER                                            :: handle, i, iounit, ispin, natom, nspins
     773             :       LOGICAL                                            :: debug_forces, debug_stress, do_ec_hfx, &
     774             :                                                             use_virial
     775             :       REAL(dp)                                           :: dummy_real, dummy_real2(2), ehartree, &
     776             :                                                             eovrl, exc, fconv
     777         172 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: ftot
     778             :       REAL(dp), DIMENSION(3)                             :: fodeb, fodeb2
     779             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: h_stress, pv_loc, stdeb, sttot
     780         172 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     781             :       TYPE(cell_type), POINTER                           :: cell
     782             :       TYPE(cp_logger_type), POINTER                      :: logger
     783         172 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks, matrix_s, scrm
     784         172 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p
     785             :       TYPE(dft_control_type), POINTER                    :: dft_control
     786             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     787             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     788         172 :          POINTER                                         :: sab_orb
     789             :       TYPE(pw_c1d_gs_type)                               :: rho_tot_gspace, v_hartree_gspace
     790             :       TYPE(pw_env_type), POINTER                         :: pw_env
     791             :       TYPE(pw_grid_type), POINTER                        :: pw_grid
     792             :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
     793             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     794             :       TYPE(pw_r3d_rs_type)                               :: v_hartree_rspace
     795         172 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, v_rspace, v_rspace_in, &
     796         172 :                                                             v_tau_rspace
     797         172 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     798             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     799             :       TYPE(qs_rho_type), POINTER                         :: rho
     800             :       TYPE(section_vals_type), POINTER                   :: ec_hfx_sections
     801             :       TYPE(virial_type), POINTER                         :: virial
     802             : 
     803         172 :       CALL timeset(routineN, handle)
     804             : 
     805         172 :       debug_forces = ec_env%debug_forces
     806         172 :       debug_stress = ec_env%debug_stress
     807             : 
     808         172 :       logger => cp_get_default_logger()
     809         172 :       IF (logger%para_env%is_source()) THEN
     810          86 :          iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     811             :       ELSE
     812          86 :          iounit = -1
     813             :       END IF
     814             : 
     815         172 :       NULLIFY (atomic_kind_set, cell, dft_control, force, ks_env, matrix_ks, &
     816         172 :                matrix_p, matrix_s, para_env, pw_env, rho, sab_orb, virial)
     817             :       CALL get_qs_env(qs_env=qs_env, &
     818             :                       cell=cell, &
     819             :                       dft_control=dft_control, &
     820             :                       force=force, &
     821             :                       ks_env=ks_env, &
     822             :                       matrix_ks=matrix_ks, &
     823             :                       matrix_s=matrix_s, &
     824             :                       para_env=para_env, &
     825             :                       pw_env=pw_env, &
     826             :                       rho=rho, &
     827             :                       sab_orb=sab_orb, &
     828         172 :                       virial=virial)
     829         172 :       CPASSERT(ASSOCIATED(pw_env))
     830             : 
     831         172 :       nspins = dft_control%nspins
     832         172 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     833             : 
     834         172 :       fconv = 1.0E-9_dp*pascal/cell%deth
     835         172 :       IF (debug_stress .AND. use_virial) THEN
     836           0 :          sttot = virial%pv_virial
     837             :       END IF
     838             : 
     839             :       ! Get density matrix of reference calculation
     840         172 :       CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     841             : 
     842         172 :       NULLIFY (auxbas_pw_pool, poisson_env)
     843             :       ! gets the tmp grids
     844             :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
     845         172 :                       poisson_env=poisson_env)
     846             : 
     847             :       ! Calculate the Hartree potential
     848         172 :       CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
     849         172 :       CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
     850         172 :       CALL auxbas_pw_pool%create_pw(v_hartree_rspace)
     851             : 
     852             :       ! Get the total input density in g-space [ions + electrons]
     853         172 :       CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho)
     854             : 
     855             :       ! v_H[n_in]
     856         172 :       IF (use_virial) THEN
     857             : 
     858             :          ! Stress tensor - Volume and Green function contribution
     859          60 :          h_stress(:, :) = 0.0_dp
     860             :          CALL pw_poisson_solve(poisson_env, &
     861             :                                density=rho_tot_gspace, &
     862             :                                ehartree=ehartree, &
     863             :                                vhartree=v_hartree_gspace, &
     864          60 :                                h_stress=h_stress)
     865             : 
     866         780 :          virial%pv_ehartree = virial%pv_ehartree + h_stress/REAL(para_env%num_pe, dp)
     867         780 :          virial%pv_virial = virial%pv_virial + h_stress/REAL(para_env%num_pe, dp)
     868             : 
     869          60 :          IF (debug_stress) THEN
     870           0 :             stdeb = fconv*(h_stress/REAL(para_env%num_pe, dp))
     871           0 :             CALL para_env%sum(stdeb)
     872           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
     873           0 :                'STRESS| GREEN 1st V_H[n_in]*n_in  ', one_third_sum_diag(stdeb), det_3x3(stdeb)
     874             :          END IF
     875             : 
     876             :       ELSE
     877             :          CALL pw_poisson_solve(poisson_env, rho_tot_gspace, ehartree, &
     878         112 :                                v_hartree_gspace)
     879             :       END IF
     880             : 
     881         172 :       CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
     882         172 :       CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
     883             : 
     884             :       ! Save density on real space grid for use in properties
     885         172 :       CALL qs_rho_get(rho, rho_r=rho_r)
     886         688 :       ALLOCATE (ec_env%rhoout_r(nspins))
     887         344 :       DO ispin = 1, nspins
     888         172 :          CALL auxbas_pw_pool%create_pw(ec_env%rhoout_r(ispin))
     889         344 :          CALL pw_copy(rho_r(ispin), ec_env%rhoout_r(ispin))
     890             :       END DO
     891             : 
     892             :       ! Getting nuclear force contribution from the core charge density
     893             :       ! Vh(rho_c + rho_in)
     894         172 :       IF (debug_forces) fodeb(1:3) = force(1)%rho_core(1:3, 1)
     895         172 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_ehartree
     896         172 :       CALL integrate_v_core_rspace(v_hartree_rspace, qs_env)
     897         172 :       IF (debug_forces) THEN
     898           0 :          fodeb(1:3) = force(1)%rho_core(1:3, 1) - fodeb(1:3)
     899           0 :          CALL para_env%sum(fodeb)
     900           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Vtot*dncore", fodeb
     901             :       END IF
     902         172 :       IF (debug_stress .AND. use_virial) THEN
     903           0 :          stdeb = fconv*(virial%pv_ehartree - stdeb)
     904           0 :          CALL para_env%sum(stdeb)
     905           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
     906           0 :             'STRESS| Vtot*dncore', one_third_sum_diag(stdeb), det_3x3(stdeb)
     907             :       END IF
     908             : 
     909             :       ! v_XC[n_in]_DC
     910             :       ! v_rspace and v_tau_rspace are generated from the auxbas pool
     911         172 :       NULLIFY (v_rspace, v_tau_rspace)
     912             : 
     913             :       ! only activate stress calculation if
     914         172 :       IF (use_virial) virial%pv_calculate = .TRUE.
     915             : 
     916             :       ! Exchange-correlation potential
     917             :       CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho, xc_section=ec_env%xc_section, &
     918         172 :                          vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE.)
     919             : 
     920         172 :       IF (.NOT. ASSOCIATED(v_rspace)) THEN
     921           0 :          ALLOCATE (v_rspace(nspins))
     922           0 :          DO ispin = 1, nspins
     923           0 :             CALL auxbas_pw_pool%create_pw(v_rspace(ispin))
     924           0 :             CALL pw_zero(v_rspace(ispin))
     925             :          END DO
     926             :       END IF
     927             : 
     928         172 :       IF (use_virial) THEN
     929         780 :          virial%pv_exc = virial%pv_exc - virial%pv_xc
     930         780 :          virial%pv_virial = virial%pv_virial - virial%pv_xc
     931             :          ! virial%pv_xc will be zeroed in the xc routines
     932             :       END IF
     933             : 
     934             :       ! initialize srcm matrix
     935         172 :       NULLIFY (scrm)
     936         172 :       CALL dbcsr_allocate_matrix_set(scrm, nspins)
     937         344 :       DO ispin = 1, nspins
     938         172 :          ALLOCATE (scrm(ispin)%matrix)
     939         172 :          CALL dbcsr_create(scrm(ispin)%matrix, template=ec_env%matrix_ks(ispin, 1)%matrix)
     940         172 :          CALL dbcsr_copy(scrm(ispin)%matrix, ec_env%matrix_ks(ispin, 1)%matrix)
     941         344 :          CALL dbcsr_set(scrm(ispin)%matrix, 0.0_dp)
     942             :       END DO
     943             : 
     944         172 :       pw_grid => v_hartree_rspace%pw_grid
     945         516 :       ALLOCATE (v_rspace_in(nspins))
     946         344 :       DO ispin = 1, nspins
     947         344 :          CALL v_rspace_in(ispin)%create(pw_grid)
     948             :       END DO
     949             : 
     950             :       ! v_rspace_in = v_H[n_in] + v_xc[n_in] calculated in ks_ref_potential
     951         344 :       DO ispin = 1, nspins
     952             :          ! v_xc[n_in]_GS
     953         172 :          CALL pw_transfer(ec_env%vxc_rspace(ispin), v_rspace_in(ispin))
     954             :          ! add v_H[n_in]
     955         344 :          CALL pw_axpy(ec_env%vh_rspace, v_rspace_in(ispin))
     956             :       END DO
     957             : 
     958             : !------------------------------------------------
     959             : 
     960             :       ! If hybrid functional in DC-DFT
     961         172 :       ec_hfx_sections => section_vals_get_subs_vals(qs_env%input, "DFT%ENERGY_CORRECTION%XC%HF")
     962         172 :       CALL section_vals_get(ec_hfx_sections, explicit=do_ec_hfx)
     963             : 
     964         172 :       IF (do_ec_hfx) THEN
     965             : 
     966          32 :          IF (debug_forces) fodeb(1:3) = force(1)%fock_4c(1:3, 1)
     967           0 :          IF (debug_forces) fodeb2(1:3) = force(1)%overlap_admm(1:3, 1)
     968             : 
     969             :          ! Calculate direct HFX forces here
     970             :          ! Virial contribution (fock_4c) done inside calculate_exx
     971          32 :          dummy_real = 0.0_dp
     972             :          CALL calculate_exx(qs_env=qs_env, &
     973             :                             unit_nr=iounit, &
     974             :                             hfx_sections=ec_hfx_sections, &
     975             :                             x_data=ec_env%x_data, &
     976             :                             do_gw=.FALSE., &
     977             :                             do_admm=ec_env%do_ec_admm, &
     978             :                             calc_forces=.TRUE., &
     979             :                             reuse_hfx=ec_env%reuse_hfx, &
     980             :                             do_im_time=.FALSE., &
     981             :                             E_ex_from_GW=dummy_real, &
     982             :                             E_admm_from_GW=dummy_real2, &
     983          32 :                             t3=dummy_real)
     984             : 
     985          32 :          IF (debug_forces) THEN
     986           0 :             fodeb(1:3) = force(1)%fock_4c(1:3, 1) - fodeb(1:3)
     987           0 :             CALL para_env%sum(fodeb)
     988           0 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*hfx_DC ", fodeb
     989             : 
     990           0 :             fodeb2(1:3) = force(1)%overlap_admm(1:3, 1) - fodeb2(1:3)
     991           0 :             CALL para_env%sum(fodeb2)
     992           0 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*hfx_DC*S ", fodeb2
     993             :          END IF
     994          32 :          IF (debug_stress .AND. use_virial) THEN
     995           0 :             stdeb = -1.0_dp*fconv*virial%pv_fock_4c
     996           0 :             CALL para_env%sum(stdeb)
     997           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
     998           0 :                'STRESS| P*hfx_DC ', one_third_sum_diag(stdeb), det_3x3(stdeb)
     999             :          END IF
    1000             : 
    1001             :       END IF
    1002             : 
    1003             : !------------------------------------------------
    1004             : 
    1005             :       ! Stress-tensor contribution derivative of integrand
    1006             :       ! int v_Hxc[n^în]*n^out
    1007         172 :       IF (use_virial) THEN
    1008         780 :          pv_loc = virial%pv_virial
    1009             :       END IF
    1010             : 
    1011         172 :       IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
    1012         172 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
    1013             : 
    1014         344 :       DO ispin = 1, nspins
    1015             :          ! Add v_H[n_in] + v_xc[n_in] = v_rspace
    1016         172 :          CALL pw_scale(v_rspace(ispin), v_rspace(ispin)%pw_grid%dvol)
    1017         172 :          CALL pw_axpy(v_hartree_rspace, v_rspace(ispin))
    1018             :          ! integrate over potential <a|V|b>
    1019             :          CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
    1020             :                                  hmat=scrm(ispin), &
    1021             :                                  pmat=matrix_p(ispin, 1), &
    1022             :                                  qs_env=qs_env, &
    1023             :                                  calculate_forces=.TRUE., &
    1024             :                                  basis_type="HARRIS", &
    1025         344 :                                  task_list_external=ec_env%task_list)
    1026             :       END DO
    1027             : 
    1028         172 :       IF (debug_forces) THEN
    1029           0 :          fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
    1030           0 :          CALL para_env%sum(fodeb)
    1031           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dVhxc ", fodeb
    1032             :       END IF
    1033         172 :       IF (debug_stress .AND. use_virial) THEN
    1034           0 :          stdeb = fconv*(virial%pv_virial - stdeb)
    1035           0 :          CALL para_env%sum(stdeb)
    1036           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1037           0 :             'STRESS| INT Pout*dVhxc   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1038             :       END IF
    1039             : 
    1040         172 :       IF (ASSOCIATED(v_tau_rspace)) THEN
    1041          16 :          IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
    1042          16 :          IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
    1043          32 :          DO ispin = 1, nspins
    1044          16 :             CALL pw_scale(v_tau_rspace(ispin), v_tau_rspace(ispin)%pw_grid%dvol)
    1045             :             ! integrate over Tau-potential <nabla.a|V|nabla.b>
    1046             :             CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
    1047             :                                     hmat=scrm(ispin), &
    1048             :                                     pmat=matrix_p(ispin, 1), &
    1049             :                                     qs_env=qs_env, &
    1050             :                                     calculate_forces=.TRUE., &
    1051             :                                     compute_tau=.TRUE., &
    1052             :                                     basis_type="HARRIS", &
    1053          32 :                                     task_list_external=ec_env%task_list)
    1054             :          END DO
    1055             : 
    1056          16 :          IF (debug_forces) THEN
    1057           0 :             fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
    1058           0 :             CALL para_env%sum(fodeb)
    1059           0 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dVhxc_tau ", fodeb
    1060             :          END IF
    1061          16 :          IF (debug_stress .AND. use_virial) THEN
    1062           0 :             stdeb = fconv*(virial%pv_virial - stdeb)
    1063           0 :             CALL para_env%sum(stdeb)
    1064           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1065           0 :                'STRESS| INT Pout*dVhxc_tau   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1066             :          END IF
    1067             :       END IF
    1068             : 
    1069             :       ! Stress-tensor
    1070         172 :       IF (use_virial) THEN
    1071         780 :          virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - pv_loc)
    1072             :       END IF
    1073             : 
    1074             :       ! delete scrm matrix
    1075         172 :       CALL dbcsr_deallocate_matrix_set(scrm)
    1076             : 
    1077             :       !----------------------------------------------------
    1078             :       ! Right-hand-side matrix B for linear response equations AX = B
    1079             :       !----------------------------------------------------
    1080             : 
    1081             :       ! RHS = int v_Hxc[n]_DC - v_Hxc[n]_GS dr + alpha_DC * E_X[n] - alpha_gs * E_X[n]
    1082             :       !     = int v_Hxc[n]_DC - v_Hxc[n]_GS dr + alpha_DC / alpha_GS * E_X[n]_GS - E_X[n]_GS
    1083             :       !
    1084             :       ! with v_Hxc[n] = v_H[n] + v_xc[n]
    1085             :       !
    1086             :       ! Actually v_H[n_in] same for DC and GS, just there for convenience
    1087             :       !          v_xc[n_in]_GS = 0 if GS is HF BUT =/0 if hybrid
    1088             :       !          so, we keep this general form
    1089             : 
    1090         172 :       NULLIFY (ec_env%matrix_hz)
    1091         172 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_hz, nspins)
    1092         344 :       DO ispin = 1, nspins
    1093         172 :          ALLOCATE (ec_env%matrix_hz(ispin)%matrix)
    1094         172 :          CALL dbcsr_create(ec_env%matrix_hz(ispin)%matrix, template=matrix_s(1)%matrix)
    1095         172 :          CALL dbcsr_copy(ec_env%matrix_hz(ispin)%matrix, matrix_s(1)%matrix)
    1096         344 :          CALL dbcsr_set(ec_env%matrix_hz(ispin)%matrix, 0.0_dp)
    1097             :       END DO
    1098             : 
    1099         344 :       DO ispin = 1, nspins
    1100             :          ! v_rspace = v_rspace - v_rspace_in
    1101             :          !          = v_Hxc[n_in]_DC - v_Hxc[n_in]_GS
    1102         344 :          CALL pw_axpy(v_rspace_in(ispin), v_rspace(ispin), -1.0_dp)
    1103             :       END DO
    1104             : 
    1105         344 :       DO ispin = 1, nspins
    1106             :          CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
    1107             :                                  hmat=ec_env%matrix_hz(ispin), &
    1108             :                                  pmat=matrix_p(ispin, 1), &
    1109             :                                  qs_env=qs_env, &
    1110             :                                  calculate_forces=.FALSE., &
    1111             :                                  basis_type="HARRIS", &
    1112         344 :                                  task_list_external=ec_env%task_list)
    1113             :       END DO
    1114             : 
    1115             :       ! Check if mGGA functionals are used
    1116         172 :       IF (dft_control%use_kinetic_energy_density) THEN
    1117             : 
    1118             :          ! If DC-DFT without mGGA functional, this needs to be allocated now.
    1119          32 :          IF (.NOT. ASSOCIATED(v_tau_rspace)) THEN
    1120          48 :             ALLOCATE (v_tau_rspace(nspins))
    1121          32 :             DO ispin = 1, nspins
    1122          16 :                CALL auxbas_pw_pool%create_pw(v_tau_rspace(ispin))
    1123          32 :                CALL pw_zero(v_tau_rspace(ispin))
    1124             :             END DO
    1125             :          END IF
    1126             : 
    1127          64 :          DO ispin = 1, nspins
    1128             :             ! v_tau_rspace = v_Hxc_tau[n_in]_DC - v_Hxc_tau[n_in]_GS
    1129          32 :             IF (ASSOCIATED(ec_env%vtau_rspace)) THEN
    1130          16 :                CALL pw_axpy(ec_env%vtau_rspace(ispin), v_tau_rspace(ispin), -1.0_dp)
    1131             :             END IF
    1132             :             ! integrate over Tau-potential <nabla.a|V|nabla.b>
    1133             :             CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
    1134             :                                     hmat=ec_env%matrix_hz(ispin), &
    1135             :                                     pmat=matrix_p(ispin, 1), &
    1136             :                                     qs_env=qs_env, &
    1137             :                                     calculate_forces=.FALSE., compute_tau=.TRUE., &
    1138             :                                     basis_type="HARRIS", &
    1139          64 :                                     task_list_external=ec_env%task_list)
    1140             :          END DO
    1141             :       END IF
    1142             : 
    1143             :       ! Need to also subtract HFX contribution of reference calculation from ec_env%matrix_hz
    1144             :       ! and/or add HFX contribution if DC-DFT ueses hybrid XC-functional
    1145             :       CALL add_exx_to_rhs(rhs=ec_env%matrix_hz, &
    1146             :                           qs_env=qs_env, &
    1147             :                           ext_hfx_section=ec_hfx_sections, &
    1148             :                           x_data=ec_env%x_data, &
    1149             :                           recalc_integrals=.FALSE., &
    1150             :                           do_admm=ec_env%do_ec_admm, &
    1151             :                           do_ec=.TRUE., &
    1152             :                           do_exx=.FALSE., &
    1153         172 :                           reuse_hfx=ec_env%reuse_hfx)
    1154             : 
    1155             :       ! Core overlap
    1156         172 :       IF (debug_forces) fodeb(1:3) = force(1)%core_overlap(1:3, 1)
    1157         172 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_ecore_overlap
    1158         172 :       CALL calculate_ecore_overlap(qs_env, para_env, .TRUE., E_overlap_core=eovrl)
    1159         172 :       IF (debug_forces) THEN
    1160           0 :          fodeb(1:3) = force(1)%core_overlap(1:3, 1) - fodeb(1:3)
    1161           0 :          CALL para_env%sum(fodeb)
    1162           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: CoreOverlap", fodeb
    1163             :       END IF
    1164         172 :       IF (debug_stress .AND. use_virial) THEN
    1165           0 :          stdeb = fconv*(stdeb - virial%pv_ecore_overlap)
    1166           0 :          CALL para_env%sum(stdeb)
    1167           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1168           0 :             'STRESS| CoreOverlap   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1169             :       END IF
    1170             : 
    1171         172 :       IF (debug_forces) THEN
    1172           0 :          CALL get_qs_env(qs_env, natom=natom, atomic_kind_set=atomic_kind_set)
    1173           0 :          ALLOCATE (ftot(3, natom))
    1174           0 :          CALL total_qs_force(ftot, force, atomic_kind_set)
    1175           0 :          fodeb(1:3) = ftot(1:3, 1)
    1176           0 :          DEALLOCATE (ftot)
    1177           0 :          CALL para_env%sum(fodeb)
    1178           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Force Explicit", fodeb
    1179             :       END IF
    1180             : 
    1181             :       ! return pw grids
    1182         344 :       DO ispin = 1, nspins
    1183         172 :          CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
    1184         172 :          CALL auxbas_pw_pool%give_back_pw(v_rspace_in(ispin))
    1185         344 :          IF (ASSOCIATED(v_tau_rspace)) THEN
    1186          32 :             CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
    1187             :          END IF
    1188             :       END DO
    1189             : 
    1190         172 :       DEALLOCATE (v_rspace, v_rspace_in)
    1191         172 :       IF (ASSOCIATED(v_tau_rspace)) DEALLOCATE (v_tau_rspace)
    1192             :       !
    1193         172 :       CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
    1194         172 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
    1195         172 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_rspace)
    1196             : 
    1197             :       ! Stress tensor - volume terms need to be stored,
    1198             :       ! for a sign correction in QS at the end of qs_force
    1199         172 :       IF (use_virial) THEN
    1200          60 :          IF (qs_env%energy_correction) THEN
    1201          60 :             ec_env%ehartree = ehartree
    1202          60 :             ec_env%exc = exc
    1203             :          END IF
    1204             :       END IF
    1205             : 
    1206          60 :       IF (debug_stress .AND. use_virial) THEN
    1207             :          ! In total: -1.0*E_H
    1208           0 :          stdeb = -1.0_dp*fconv*ehartree
    1209           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1210           0 :             'STRESS| VOL 1st v_H[n_in]*n_in', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1211             : 
    1212           0 :          stdeb = -1.0_dp*fconv*exc
    1213           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1214           0 :             'STRESS| VOL 1st E_XC_DC[n_in]', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1215             : 
    1216             :          ! For debugging, create a second virial environment,
    1217             :          ! apply volume terms immediately
    1218             :          BLOCK
    1219             :             TYPE(virial_type) :: virdeb
    1220           0 :             virdeb = virial
    1221             : 
    1222           0 :             CALL para_env%sum(virdeb%pv_overlap)
    1223           0 :             CALL para_env%sum(virdeb%pv_ekinetic)
    1224           0 :             CALL para_env%sum(virdeb%pv_ppl)
    1225           0 :             CALL para_env%sum(virdeb%pv_ppnl)
    1226           0 :             CALL para_env%sum(virdeb%pv_ecore_overlap)
    1227           0 :             CALL para_env%sum(virdeb%pv_ehartree)
    1228           0 :             CALL para_env%sum(virdeb%pv_exc)
    1229           0 :             CALL para_env%sum(virdeb%pv_exx)
    1230           0 :             CALL para_env%sum(virdeb%pv_vdw)
    1231           0 :             CALL para_env%sum(virdeb%pv_mp2)
    1232           0 :             CALL para_env%sum(virdeb%pv_nlcc)
    1233           0 :             CALL para_env%sum(virdeb%pv_gapw)
    1234           0 :             CALL para_env%sum(virdeb%pv_lrigpw)
    1235           0 :             CALL para_env%sum(virdeb%pv_virial)
    1236           0 :             CALL symmetrize_virial(virdeb)
    1237             : 
    1238             :             ! apply stress-tensor 1st terms
    1239           0 :             DO i = 1, 3
    1240           0 :                virdeb%pv_ehartree(i, i) = virdeb%pv_ehartree(i, i) - 2.0_dp*ehartree
    1241             :                virdeb%pv_virial(i, i) = virdeb%pv_virial(i, i) - exc &
    1242           0 :                                         - 2.0_dp*ehartree
    1243           0 :                virdeb%pv_exc(i, i) = virdeb%pv_exc(i, i) - exc
    1244             :                ! The factor 2 is a hack. It compensates the plus sign in h_stress/pw_poisson_solve.
    1245             :                ! The sign in pw_poisson_solve is correct for FIST, but not for QS.
    1246             :                ! There should be a more elegant solution to that ...
    1247             :             END DO
    1248             : 
    1249           0 :             CALL para_env%sum(sttot)
    1250           0 :             stdeb = fconv*(virdeb%pv_virial - sttot)
    1251           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1252           0 :                'STRESS| Explicit electronic stress   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1253             : 
    1254           0 :             stdeb = fconv*(virdeb%pv_virial)
    1255           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1256           0 :                'STRESS| Explicit total stress   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1257             : 
    1258           0 :             unit_string = "GPa" ! old default
    1259           0 :             CALL write_stress_tensor_components(virdeb, iounit, cell, unit_string)
    1260           0 :             CALL write_stress_tensor(virdeb%pv_virial, iounit, cell, unit_string, .FALSE.)
    1261             : 
    1262             :          END BLOCK
    1263             :       END IF
    1264             : 
    1265         172 :       CALL timestop(handle)
    1266             : 
    1267         516 :    END SUBROUTINE ec_dc_build_ks_matrix_force
    1268             : 
    1269             : ! **************************************************************************************************
    1270             : !> \brief ...
    1271             : !> \param qs_env ...
    1272             : !> \param ec_env ...
    1273             : !> \param calculate_forces ...
    1274             : ! **************************************************************************************************
    1275         966 :    SUBROUTINE ec_disp(qs_env, ec_env, calculate_forces)
    1276             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1277             :       TYPE(energy_correction_type), POINTER              :: ec_env
    1278             :       LOGICAL, INTENT(IN)                                :: calculate_forces
    1279             : 
    1280             :       REAL(KIND=dp)                                      :: edisp
    1281             : 
    1282         966 :       CALL calculate_dispersion_pairpot(qs_env, ec_env%dispersion_env, edisp, calculate_forces)
    1283         966 :       IF (.NOT. calculate_forces) ec_env%edispersion = ec_env%edispersion + edisp
    1284             : 
    1285         966 :    END SUBROUTINE ec_disp
    1286             : 
    1287             : ! **************************************************************************************************
    1288             : !> \brief Construction of the Core Hamiltonian Matrix
    1289             : !>        Short version of qs_core_hamiltonian
    1290             : !> \param qs_env ...
    1291             : !> \param ec_env ...
    1292             : !> \author Creation (03.2014,JGH)
    1293             : ! **************************************************************************************************
    1294         346 :    SUBROUTINE ec_build_core_hamiltonian(qs_env, ec_env)
    1295             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1296             :       TYPE(energy_correction_type), POINTER              :: ec_env
    1297             : 
    1298             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_core_hamiltonian'
    1299             : 
    1300             :       INTEGER                                            :: handle, nder, nimages
    1301         346 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
    1302             :       LOGICAL                                            :: calculate_forces, use_virial
    1303             :       REAL(KIND=dp)                                      :: eps_ppnl
    1304         346 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1305             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1306             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1307         346 :          POINTER                                         :: sab_orb, sac_ae, sac_ppl, sap_ppnl
    1308         346 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1309         346 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    1310         346 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1311             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1312             :       TYPE(virial_type), POINTER                         :: virial
    1313             : 
    1314         346 :       CALL timeset(routineN, handle)
    1315             : 
    1316         346 :       NULLIFY (atomic_kind_set, cell_to_index, dft_control, ks_env, particle_set, qs_kind_set, virial)
    1317             : 
    1318             :       CALL get_qs_env(qs_env=qs_env, &
    1319             :                       atomic_kind_set=atomic_kind_set, &
    1320             :                       dft_control=dft_control, &
    1321             :                       particle_set=particle_set, &
    1322             :                       qs_kind_set=qs_kind_set, &
    1323         346 :                       ks_env=ks_env)
    1324             : 
    1325             :       ! no k-points possible
    1326         346 :       nimages = dft_control%nimages
    1327         346 :       IF (nimages /= 1) THEN
    1328           0 :          CPABORT("K-points for Harris functional not implemented")
    1329             :       END IF
    1330             : 
    1331             :       ! check for GAPW/GAPW_XC
    1332         346 :       IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
    1333           0 :          CPABORT("Harris functional for GAPW not implemented")
    1334             :       END IF
    1335             : 
    1336             :       ! Do not calculate forces or stress tensor here
    1337         346 :       use_virial = .FALSE.
    1338         346 :       calculate_forces = .FALSE.
    1339             : 
    1340             :       ! get neighbor lists, we need the full sab_orb list from the ec_env
    1341         346 :       NULLIFY (sab_orb, sac_ae, sac_ppl, sap_ppnl)
    1342         346 :       sab_orb => ec_env%sab_orb
    1343         346 :       sac_ppl => ec_env%sac_ppl
    1344         346 :       sap_ppnl => ec_env%sap_ppnl
    1345             : 
    1346         346 :       nder = 0
    1347             :       ! Overlap and kinetic energy matrices
    1348             :       CALL build_overlap_matrix(ks_env, matrixkp_s=ec_env%matrix_s, &
    1349             :                                 matrix_name="OVERLAP MATRIX", &
    1350             :                                 basis_type_a="HARRIS", &
    1351             :                                 basis_type_b="HARRIS", &
    1352         346 :                                 sab_nl=sab_orb)
    1353             :       CALL build_kinetic_matrix(ks_env, matrixkp_t=ec_env%matrix_t, &
    1354             :                                 matrix_name="KINETIC ENERGY MATRIX", &
    1355             :                                 basis_type="HARRIS", &
    1356         346 :                                 sab_nl=sab_orb)
    1357             : 
    1358             :       ! initialize H matrix
    1359         346 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_h, 1, 1)
    1360         346 :       ALLOCATE (ec_env%matrix_h(1, 1)%matrix)
    1361         346 :       CALL dbcsr_create(ec_env%matrix_h(1, 1)%matrix, template=ec_env%matrix_s(1, 1)%matrix)
    1362         346 :       CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_h(1, 1)%matrix, sab_orb)
    1363             : 
    1364             :       ! add kinetic energy
    1365             :       CALL dbcsr_copy(ec_env%matrix_h(1, 1)%matrix, ec_env%matrix_t(1, 1)%matrix, &
    1366         346 :                       keep_sparsity=.TRUE., name="CORE HAMILTONIAN MATRIX")
    1367             : 
    1368             :       ! Possible AE contributions (also ECP)
    1369         346 :       IF (ASSOCIATED(sac_ae)) THEN
    1370           0 :          CPABORT("ECP/AE not available for energy corrections")
    1371             :          ! missig code: sac_ae has to bee calculated and stored in ec_env
    1372             :          ! build_core_ae: needs functionality to set the basis type at input
    1373             :          CALL build_core_ae(ec_env%matrix_h, ec_env%matrix_p, force, &
    1374             :                             virial, calculate_forces, use_virial, nder, &
    1375             :                             qs_kind_set, atomic_kind_set, particle_set, sab_orb, sac_ae, &
    1376           0 :                             nimages, cell_to_index)
    1377             :       END IF
    1378             :       ! compute the ppl contribution to the core hamiltonian
    1379         346 :       IF (ASSOCIATED(sac_ppl)) THEN
    1380             :          CALL build_core_ppl(ec_env%matrix_h, ec_env%matrix_p, force, &
    1381             :                              virial, calculate_forces, use_virial, nder, &
    1382             :                              qs_kind_set, atomic_kind_set, particle_set, sab_orb, sac_ppl, &
    1383         346 :                              nimages, cell_to_index, "HARRIS")
    1384             :       END IF
    1385             : 
    1386             :       ! compute the ppnl contribution to the core hamiltonian ***
    1387         346 :       eps_ppnl = dft_control%qs_control%eps_ppnl
    1388         346 :       IF (ASSOCIATED(sap_ppnl)) THEN
    1389             :          CALL build_core_ppnl(ec_env%matrix_h, ec_env%matrix_p, force, &
    1390             :                               virial, calculate_forces, use_virial, nder, &
    1391             :                               qs_kind_set, atomic_kind_set, particle_set, sab_orb, sap_ppnl, &
    1392         346 :                               eps_ppnl, nimages, cell_to_index, "HARRIS")
    1393             :       END IF
    1394             : 
    1395             :       ! External field (nonperiodic case)
    1396         346 :       ec_env%efield_nuclear = 0.0_dp
    1397         346 :       CALL ec_efield_local_operator(qs_env, ec_env, calculate_forces)
    1398             : 
    1399         346 :       CALL timestop(handle)
    1400             : 
    1401         346 :    END SUBROUTINE ec_build_core_hamiltonian
    1402             : 
    1403             : ! **************************************************************************************************
    1404             : !> \brief Solve KS equation for a given matrix
    1405             : !>        calculate the complete KS matrix
    1406             : !> \param qs_env ...
    1407             : !> \param ec_env ...
    1408             : !> \par History
    1409             : !>      03.2014 adapted from qs_ks_build_kohn_sham_matrix [JGH]
    1410             : !> \author JGH
    1411             : ! **************************************************************************************************
    1412        1044 :    SUBROUTINE ec_build_ks_matrix(qs_env, ec_env)
    1413             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1414             :       TYPE(energy_correction_type), POINTER              :: ec_env
    1415             : 
    1416             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_ks_matrix'
    1417             : 
    1418             :       CHARACTER(LEN=default_string_length)               :: headline
    1419             :       INTEGER                                            :: handle, iounit, ispin, nspins
    1420             :       LOGICAL                                            :: calculate_forces, &
    1421             :                                                             do_adiabatic_rescaling, do_ec_hfx, &
    1422             :                                                             hfx_treat_lsd_in_core, use_virial
    1423             :       REAL(dp)                                           :: dummy_real, dummy_real2(2), eexc, evhxc, &
    1424             :                                                             t3
    1425             :       TYPE(cp_logger_type), POINTER                      :: logger
    1426         522 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ks_mat
    1427             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1428             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1429             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1430         522 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, tau_r, v_rspace, v_tau_rspace
    1431             :       TYPE(qs_energy_type), POINTER                      :: energy
    1432             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1433             :       TYPE(qs_rho_type), POINTER                         :: rho
    1434             :       TYPE(section_vals_type), POINTER                   :: adiabatic_rescaling_section, &
    1435             :                                                             ec_hfx_sections, ec_section
    1436             : 
    1437         522 :       CALL timeset(routineN, handle)
    1438             : 
    1439         522 :       logger => cp_get_default_logger()
    1440         522 :       IF (logger%para_env%is_source()) THEN
    1441         261 :          iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1442             :       ELSE
    1443         261 :          iounit = -1
    1444             :       END IF
    1445             : 
    1446             :       ! get all information on the electronic density
    1447         522 :       NULLIFY (auxbas_pw_pool, dft_control, energy, ks_env, rho, rho_r, tau_r)
    1448             :       CALL get_qs_env(qs_env=qs_env, &
    1449             :                       dft_control=dft_control, &
    1450             :                       ks_env=ks_env, &
    1451         522 :                       rho=rho)
    1452         522 :       nspins = dft_control%nspins
    1453         522 :       calculate_forces = .FALSE.
    1454         522 :       use_virial = .FALSE.
    1455             : 
    1456             :       ! Kohn-Sham matrix
    1457         522 :       IF (ASSOCIATED(ec_env%matrix_ks)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_ks)
    1458         522 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_ks, nspins, 1)
    1459        1044 :       DO ispin = 1, nspins
    1460         522 :          headline = "KOHN-SHAM MATRIX"
    1461         522 :          ALLOCATE (ec_env%matrix_ks(ispin, 1)%matrix)
    1462             :          CALL dbcsr_create(ec_env%matrix_ks(ispin, 1)%matrix, name=TRIM(headline), &
    1463         522 :                            template=ec_env%matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
    1464         522 :          CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_ks(ispin, 1)%matrix, ec_env%sab_orb)
    1465        1044 :          CALL dbcsr_set(ec_env%matrix_ks(ispin, 1)%matrix, 0.0_dp)
    1466             :       END DO
    1467             : 
    1468         522 :       NULLIFY (pw_env)
    1469         522 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
    1470         522 :       CPASSERT(ASSOCIATED(pw_env))
    1471             : 
    1472             :       ! Exact exchange contribution (hybrid functionals)
    1473         522 :       ec_section => section_vals_get_subs_vals(qs_env%input, "DFT%ENERGY_CORRECTION")
    1474         522 :       ec_hfx_sections => section_vals_get_subs_vals(ec_section, "XC%HF")
    1475         522 :       CALL section_vals_get(ec_hfx_sections, explicit=do_ec_hfx)
    1476             : 
    1477         522 :       IF (do_ec_hfx) THEN
    1478             : 
    1479             :          ! Check what works
    1480          32 :          adiabatic_rescaling_section => section_vals_get_subs_vals(ec_section, "XC%ADIABATIC_RESCALING")
    1481          32 :          CALL section_vals_get(adiabatic_rescaling_section, explicit=do_adiabatic_rescaling)
    1482          32 :          IF (do_adiabatic_rescaling) THEN
    1483           0 :             CALL cp_abort(__LOCATION__, "Adiabatic rescaling NYI for energy correction")
    1484             :          END IF
    1485          32 :          CALL section_vals_val_get(ec_hfx_sections, "TREAT_LSD_IN_CORE", l_val=hfx_treat_lsd_in_core)
    1486          32 :          IF (hfx_treat_lsd_in_core) THEN
    1487           0 :             CALL cp_abort(__LOCATION__, "HFX_TREAT_LSD_IN_CORE NYI for energy correction")
    1488             :          END IF
    1489             : 
    1490             :          ! calculate the density matrix for the fitted mo_coeffs
    1491          32 :          IF (dft_control%do_admm) THEN
    1492             : 
    1493          20 :             IF (dft_control%do_admm_mo) THEN
    1494          20 :                IF (qs_env%run_rtp) THEN
    1495           0 :                   CALL rtp_admm_calc_rho_aux(qs_env)
    1496             :                ELSE
    1497          20 :                   CALL admm_mo_calc_rho_aux(qs_env)
    1498             :                END IF
    1499           0 :             ELSEIF (dft_control%do_admm_dm) THEN
    1500           0 :                CALL admm_dm_calc_rho_aux(qs_env)
    1501             :             END IF
    1502             :          END IF
    1503             : 
    1504             :          ! Get exact exchange energy
    1505          32 :          dummy_real = 0.0_dp
    1506          32 :          t3 = 0.0_dp
    1507          32 :          CALL get_qs_env(qs_env, energy=energy)
    1508             :          CALL calculate_exx(qs_env=qs_env, &
    1509             :                             unit_nr=iounit, &
    1510             :                             hfx_sections=ec_hfx_sections, &
    1511             :                             x_data=ec_env%x_data, &
    1512             :                             do_gw=.FALSE., &
    1513             :                             do_admm=ec_env%do_ec_admm, &
    1514             :                             calc_forces=.FALSE., &
    1515             :                             reuse_hfx=ec_env%reuse_hfx, &
    1516             :                             do_im_time=.FALSE., &
    1517             :                             E_ex_from_GW=dummy_real, &
    1518             :                             E_admm_from_GW=dummy_real2, &
    1519          32 :                             t3=dummy_real)
    1520             : 
    1521             :          ! Save exchange energy
    1522          32 :          ec_env%ex = energy%ex
    1523             :          ! Save EXX ADMM XC correction
    1524          32 :          IF (ec_env%do_ec_admm) THEN
    1525          12 :             ec_env%exc_aux_fit = energy%exc_aux_fit + energy%exc
    1526             :          END IF
    1527             : 
    1528             :          ! Add exact echange contribution of EC to EC Hamiltonian
    1529             :          ! do_ec = .FALSE prevents subtraction of HFX contribution of reference calculation
    1530             :          ! do_exx = .FALSE. prevents subtraction of reference XC contribution
    1531          32 :          ks_mat => ec_env%matrix_ks(:, 1)
    1532             :          CALL add_exx_to_rhs(rhs=ks_mat, &
    1533             :                              qs_env=qs_env, &
    1534             :                              ext_hfx_section=ec_hfx_sections, &
    1535             :                              x_data=ec_env%x_data, &
    1536             :                              recalc_integrals=.FALSE., &
    1537             :                              do_admm=ec_env%do_ec_admm, &
    1538             :                              do_ec=.FALSE., &
    1539             :                              do_exx=.FALSE., &
    1540          32 :                              reuse_hfx=ec_env%reuse_hfx)
    1541             : 
    1542             :       END IF
    1543             : 
    1544             :       ! v_rspace and v_tau_rspace are generated from the auxbas pool
    1545         522 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
    1546         522 :       NULLIFY (v_rspace, v_tau_rspace)
    1547             :       CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho, xc_section=ec_env%xc_section, &
    1548         522 :                          vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=eexc, just_energy=.FALSE.)
    1549             : 
    1550         522 :       IF (.NOT. ASSOCIATED(v_rspace)) THEN
    1551           0 :          ALLOCATE (v_rspace(nspins))
    1552           0 :          DO ispin = 1, nspins
    1553           0 :             CALL auxbas_pw_pool%create_pw(v_rspace(ispin))
    1554           0 :             CALL pw_zero(v_rspace(ispin))
    1555             :          END DO
    1556             :       END IF
    1557             : 
    1558         522 :       evhxc = 0.0_dp
    1559         522 :       CALL qs_rho_get(rho, rho_r=rho_r)
    1560         522 :       IF (ASSOCIATED(v_tau_rspace)) THEN
    1561          32 :          CALL qs_rho_get(rho, tau_r=tau_r)
    1562             :       END IF
    1563        1044 :       DO ispin = 1, nspins
    1564             :          ! Add v_hartree + v_xc = v_rspace
    1565         522 :          CALL pw_scale(v_rspace(ispin), v_rspace(ispin)%pw_grid%dvol)
    1566         522 :          CALL pw_axpy(ec_env%vh_rspace, v_rspace(ispin))
    1567             :          ! integrate over potential <a|V|b>
    1568             :          CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
    1569             :                                  hmat=ec_env%matrix_ks(ispin, 1), &
    1570             :                                  qs_env=qs_env, &
    1571             :                                  calculate_forces=.FALSE., &
    1572             :                                  basis_type="HARRIS", &
    1573         522 :                                  task_list_external=ec_env%task_list)
    1574             : 
    1575         522 :          IF (ASSOCIATED(v_tau_rspace)) THEN
    1576             :             ! integrate over Tau-potential <nabla.a|V|nabla.b>
    1577          32 :             CALL pw_scale(v_tau_rspace(ispin), v_tau_rspace(ispin)%pw_grid%dvol)
    1578             :             CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
    1579             :                                     hmat=ec_env%matrix_ks(ispin, 1), &
    1580             :                                     qs_env=qs_env, &
    1581             :                                     calculate_forces=.FALSE., &
    1582             :                                     compute_tau=.TRUE., &
    1583             :                                     basis_type="HARRIS", &
    1584          32 :                                     task_list_external=ec_env%task_list)
    1585             :          END IF
    1586             : 
    1587             :          ! calclulate Int(vhxc*rho)dr and Int(vtau*tau)dr
    1588             :          evhxc = evhxc + pw_integral_ab(rho_r(ispin), v_rspace(ispin))/ &
    1589         522 :                  v_rspace(1)%pw_grid%dvol
    1590        1044 :          IF (ASSOCIATED(v_tau_rspace)) THEN
    1591             :             evhxc = evhxc + pw_integral_ab(tau_r(ispin), v_tau_rspace(ispin))/ &
    1592          32 :                     v_tau_rspace(ispin)%pw_grid%dvol
    1593             :          END IF
    1594             : 
    1595             :       END DO
    1596             : 
    1597             :       ! return pw grids
    1598        1044 :       DO ispin = 1, nspins
    1599         522 :          CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
    1600        1044 :          IF (ASSOCIATED(v_tau_rspace)) THEN
    1601          32 :             CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
    1602             :          END IF
    1603             :       END DO
    1604         522 :       DEALLOCATE (v_rspace)
    1605         522 :       IF (ASSOCIATED(v_tau_rspace)) DEALLOCATE (v_tau_rspace)
    1606             : 
    1607             :       ! energies
    1608         522 :       ec_env%exc = eexc
    1609         522 :       ec_env%vhxc = evhxc
    1610             : 
    1611             :       ! add the core matrix
    1612        1044 :       DO ispin = 1, nspins
    1613             :          CALL dbcsr_add(ec_env%matrix_ks(ispin, 1)%matrix, ec_env%matrix_h(1, 1)%matrix, &
    1614         522 :                         alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
    1615             :          CALL dbcsr_filter(ec_env%matrix_ks(ispin, 1)%matrix, &
    1616        1044 :                            dft_control%qs_control%eps_filter_matrix)
    1617             :       END DO
    1618             : 
    1619         522 :       CALL timestop(handle)
    1620             : 
    1621         522 :    END SUBROUTINE ec_build_ks_matrix
    1622             : 
    1623             : ! **************************************************************************************************
    1624             : !> \brief Construction of the Core Hamiltonian Matrix
    1625             : !>        Short version of qs_core_hamiltonian
    1626             : !> \param qs_env ...
    1627             : !> \param ec_env ...
    1628             : !> \param matrix_p ...
    1629             : !> \param matrix_s ...
    1630             : !> \param matrix_w ...
    1631             : !> \author Creation (03.2014,JGH)
    1632             : ! **************************************************************************************************
    1633         432 :    SUBROUTINE ec_build_core_hamiltonian_force(qs_env, ec_env, matrix_p, matrix_s, matrix_w)
    1634             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1635             :       TYPE(energy_correction_type), POINTER              :: ec_env
    1636             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_s, matrix_w
    1637             : 
    1638             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_core_hamiltonian_force'
    1639             : 
    1640             :       INTEGER                                            :: handle, iounit, nder, nimages
    1641         432 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
    1642             :       LOGICAL                                            :: calculate_forces, debug_forces, &
    1643             :                                                             debug_stress, use_virial
    1644             :       REAL(KIND=dp)                                      :: eps_ppnl, fconv
    1645             :       REAL(KIND=dp), DIMENSION(3)                        :: fodeb
    1646             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: stdeb, sttot
    1647         432 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1648             :       TYPE(cell_type), POINTER                           :: cell
    1649             :       TYPE(cp_logger_type), POINTER                      :: logger
    1650         432 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: scrm
    1651             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1652             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1653             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1654         432 :          POINTER                                         :: sab_orb, sac_ppl, sap_ppnl
    1655         432 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1656         432 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    1657         432 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1658             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1659             :       TYPE(virial_type), POINTER                         :: virial
    1660             : 
    1661         432 :       CALL timeset(routineN, handle)
    1662             : 
    1663         432 :       debug_forces = ec_env%debug_forces
    1664         432 :       debug_stress = ec_env%debug_stress
    1665             : 
    1666         432 :       logger => cp_get_default_logger()
    1667         432 :       IF (logger%para_env%is_source()) THEN
    1668         216 :          iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1669             :       ELSE
    1670             :          iounit = -1
    1671             :       END IF
    1672             : 
    1673         432 :       calculate_forces = .TRUE.
    1674             : 
    1675             :       ! no k-points possible
    1676         432 :       NULLIFY (cell, dft_control, force, ks_env, para_env, virial)
    1677             :       CALL get_qs_env(qs_env=qs_env, &
    1678             :                       cell=cell, &
    1679             :                       dft_control=dft_control, &
    1680             :                       force=force, &
    1681             :                       ks_env=ks_env, &
    1682             :                       para_env=para_env, &
    1683         432 :                       virial=virial)
    1684         432 :       nimages = dft_control%nimages
    1685         432 :       IF (nimages /= 1) THEN
    1686           0 :          CPABORT("K-points for Harris functional not implemented")
    1687             :       END IF
    1688             : 
    1689             :       ! check for virial
    1690         432 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
    1691             : 
    1692         432 :       fconv = 1.0E-9_dp*pascal/cell%deth
    1693         432 :       IF (debug_stress .AND. use_virial) THEN
    1694           0 :          sttot = virial%pv_virial
    1695             :       END IF
    1696             : 
    1697             :       ! check for GAPW/GAPW_XC
    1698         432 :       IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
    1699           0 :          CPABORT("Harris functional for GAPW not implemented")
    1700             :       END IF
    1701             : 
    1702             :       ! get neighbor lists, we need the full sab_orb list from the ec_env
    1703             :       NULLIFY (sab_orb, sac_ppl, sap_ppnl)
    1704         432 :       sab_orb => ec_env%sab_orb
    1705         432 :       sac_ppl => ec_env%sac_ppl
    1706         432 :       sap_ppnl => ec_env%sap_ppnl
    1707             : 
    1708             :       ! initialize src matrix
    1709         432 :       NULLIFY (scrm)
    1710         432 :       CALL dbcsr_allocate_matrix_set(scrm, 1, 1)
    1711         432 :       ALLOCATE (scrm(1, 1)%matrix)
    1712         432 :       CALL dbcsr_create(scrm(1, 1)%matrix, template=matrix_s(1, 1)%matrix)
    1713         432 :       CALL cp_dbcsr_alloc_block_from_nbl(scrm(1, 1)%matrix, sab_orb)
    1714             : 
    1715         432 :       nder = 1
    1716         432 :       IF (SIZE(matrix_p, 1) == 2) THEN
    1717             :          CALL dbcsr_add(matrix_p(1, 1)%matrix, matrix_p(2, 1)%matrix, &
    1718           0 :                         alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
    1719             :          CALL dbcsr_add(matrix_w(1, 1)%matrix, matrix_w(2, 1)%matrix, &
    1720           0 :                         alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
    1721             :       END IF
    1722             : 
    1723             :       ! Overlap and kinetic energy matrices
    1724         432 :       IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
    1725         432 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_overlap
    1726             :       CALL build_overlap_matrix(ks_env, matrixkp_s=scrm, &
    1727             :                                 matrix_name="OVERLAP MATRIX", &
    1728             :                                 basis_type_a="HARRIS", &
    1729             :                                 basis_type_b="HARRIS", &
    1730             :                                 sab_nl=sab_orb, calculate_forces=.TRUE., &
    1731         432 :                                 matrixkp_p=matrix_w)
    1732             : 
    1733         432 :       IF (debug_forces) THEN
    1734           0 :          fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
    1735           0 :          CALL para_env%sum(fodeb)
    1736           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wout*dS    ", fodeb
    1737           0 :          fodeb(1:3) = force(1)%kinetic(1:3, 1)
    1738             :       END IF
    1739         432 :       IF (debug_stress .AND. use_virial) THEN
    1740           0 :          stdeb = fconv*(virial%pv_overlap - stdeb)
    1741           0 :          CALL para_env%sum(stdeb)
    1742           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1743           0 :             'STRESS| Wout*dS', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1744           0 :          stdeb = virial%pv_ekinetic
    1745             :       END IF
    1746             :       CALL build_kinetic_matrix(ks_env, matrixkp_t=scrm, &
    1747             :                                 matrix_name="KINETIC ENERGY MATRIX", &
    1748             :                                 basis_type="HARRIS", &
    1749             :                                 sab_nl=sab_orb, calculate_forces=.TRUE., &
    1750         432 :                                 matrixkp_p=matrix_p)
    1751         432 :       IF (debug_forces) THEN
    1752           0 :          fodeb(1:3) = force(1)%kinetic(1:3, 1) - fodeb(1:3)
    1753           0 :          CALL para_env%sum(fodeb)
    1754           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dT    ", fodeb
    1755             :       END IF
    1756         432 :       IF (debug_stress .AND. use_virial) THEN
    1757           0 :          stdeb = fconv*(virial%pv_ekinetic - stdeb)
    1758           0 :          CALL para_env%sum(stdeb)
    1759           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1760           0 :             'STRESS| Pout*dT', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1761             :       END IF
    1762         432 :       IF (SIZE(matrix_p, 1) == 2) THEN
    1763             :          CALL dbcsr_add(matrix_p(1, 1)%matrix, matrix_p(2, 1)%matrix, &
    1764           0 :                         alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
    1765             :       END IF
    1766             : 
    1767             :       ! compute the ppl contribution to the core hamiltonian
    1768         432 :       NULLIFY (atomic_kind_set, particle_set, qs_kind_set)
    1769             :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, particle_set=particle_set, &
    1770         432 :                       atomic_kind_set=atomic_kind_set)
    1771             : 
    1772         432 :       IF (ASSOCIATED(sac_ppl)) THEN
    1773         432 :          IF (calculate_forces .AND. debug_forces) fodeb(1:3) = force(1)%gth_ppl(1:3, 1)
    1774         432 :          IF (debug_stress .AND. use_virial) stdeb = virial%pv_ppl
    1775             :          CALL build_core_ppl(scrm, matrix_p, force, &
    1776             :                              virial, calculate_forces, use_virial, nder, &
    1777             :                              qs_kind_set, atomic_kind_set, particle_set, sab_orb, sac_ppl, &
    1778         432 :                              nimages, cell_to_index, "HARRIS")
    1779         432 :          IF (calculate_forces .AND. debug_forces) THEN
    1780           0 :             fodeb(1:3) = force(1)%gth_ppl(1:3, 1) - fodeb(1:3)
    1781           0 :             CALL para_env%sum(fodeb)
    1782           0 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dH_PPL ", fodeb
    1783             :          END IF
    1784         432 :          IF (debug_stress .AND. use_virial) THEN
    1785           0 :             stdeb = fconv*(virial%pv_ppl - stdeb)
    1786           0 :             CALL para_env%sum(stdeb)
    1787           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1788           0 :                'STRESS| Pout*dH_PPL', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1789             :          END IF
    1790             :       END IF
    1791             : 
    1792             :       ! compute the ppnl contribution to the core hamiltonian ***
    1793         432 :       eps_ppnl = dft_control%qs_control%eps_ppnl
    1794         432 :       IF (ASSOCIATED(sap_ppnl)) THEN
    1795         432 :          IF (calculate_forces .AND. debug_forces) fodeb(1:3) = force(1)%gth_ppnl(1:3, 1)
    1796         432 :          IF (debug_stress .AND. use_virial) stdeb = virial%pv_ppnl
    1797             :          CALL build_core_ppnl(scrm, matrix_p, force, &
    1798             :                               virial, calculate_forces, use_virial, nder, &
    1799             :                               qs_kind_set, atomic_kind_set, particle_set, &
    1800             :                               sab_orb, sap_ppnl, eps_ppnl, &
    1801         432 :                               nimages, cell_to_index, "HARRIS")
    1802         432 :          IF (calculate_forces .AND. debug_forces) THEN
    1803           0 :             fodeb(1:3) = force(1)%gth_ppnl(1:3, 1) - fodeb(1:3)
    1804           0 :             CALL para_env%sum(fodeb)
    1805           0 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dH_PPNL", fodeb
    1806             :          END IF
    1807         432 :          IF (debug_stress .AND. use_virial) THEN
    1808           0 :             stdeb = fconv*(virial%pv_ppnl - stdeb)
    1809           0 :             CALL para_env%sum(stdeb)
    1810           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1811           0 :                'STRESS| Pout*dH_PPNL', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1812             :          END IF
    1813             :       END IF
    1814             : 
    1815             :       ! External field (nonperiodic case)
    1816         432 :       ec_env%efield_nuclear = 0.0_dp
    1817         432 :       IF (calculate_forces .AND. debug_forces) fodeb(1:3) = force(1)%efield(1:3, 1)
    1818         432 :       CALL ec_efield_local_operator(qs_env, ec_env, calculate_forces)
    1819         432 :       IF (calculate_forces .AND. debug_forces) THEN
    1820           0 :          fodeb(1:3) = force(1)%efield(1:3, 1) - fodeb(1:3)
    1821           0 :          CALL para_env%sum(fodeb)
    1822           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dEfield", fodeb
    1823             :       END IF
    1824         432 :       IF (debug_stress .AND. use_virial) THEN
    1825           0 :          stdeb = fconv*(virial%pv_virial - sttot)
    1826           0 :          CALL para_env%sum(stdeb)
    1827           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    1828           0 :             'STRESS| Stress Pout*dHcore   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    1829           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") ' '
    1830             :       END IF
    1831             : 
    1832             :       ! delete scr matrix
    1833         432 :       CALL dbcsr_deallocate_matrix_set(scrm)
    1834             : 
    1835         432 :       CALL timestop(handle)
    1836             : 
    1837         432 :    END SUBROUTINE ec_build_core_hamiltonian_force
    1838             : 
    1839             : ! **************************************************************************************************
    1840             : !> \brief Solve KS equation for a given matrix
    1841             : !> \brief calculate the complete KS matrix
    1842             : !> \param qs_env ...
    1843             : !> \param ec_env ...
    1844             : !> \par History
    1845             : !>      03.2014 adapted from qs_ks_build_kohn_sham_matrix [JGH]
    1846             : !> \author JGH
    1847             : ! **************************************************************************************************
    1848         260 :    SUBROUTINE ec_build_ks_matrix_force(qs_env, ec_env)
    1849             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1850             :       TYPE(energy_correction_type), POINTER              :: ec_env
    1851             : 
    1852             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_ks_matrix_force'
    1853             : 
    1854             :       CHARACTER(LEN=default_string_length)               :: unit_string
    1855             :       INTEGER                                            :: handle, i, iounit, ispin, natom, nspins
    1856             :       LOGICAL                                            :: debug_forces, debug_stress, do_ec_hfx, &
    1857             :                                                             use_virial
    1858             :       REAL(dp)                                           :: dehartree, dummy_real, dummy_real2(2), &
    1859             :                                                             eexc, ehartree, eovrl, exc, fconv
    1860         260 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: ftot
    1861             :       REAL(dp), DIMENSION(3)                             :: fodeb
    1862             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: h_stress, pv_loc, stdeb, sttot
    1863         260 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1864             :       TYPE(cell_type), POINTER                           :: cell
    1865             :       TYPE(cp_logger_type), POINTER                      :: logger
    1866         260 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks, scrm
    1867         260 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_s
    1868             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1869             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1870             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1871         260 :          POINTER                                         :: sab_orb
    1872             :       TYPE(pw_c1d_gs_type)                               :: rho_tot_gspace, rhodn_tot_gspace, &
    1873             :                                                             v_hartree_gspace
    1874         260 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g, rhoout_g
    1875             :       TYPE(pw_c1d_gs_type), POINTER                      :: rho_core
    1876             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1877             :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
    1878             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1879             :       TYPE(pw_r3d_rs_type)                               :: dv_hartree_rspace, v_hartree_rspace, &
    1880             :                                                             vtot_rspace
    1881         260 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, rhoout_r, tau_r, tauout_r, &
    1882         260 :                                                             v_rspace, v_tau_rspace, v_xc, v_xc_tau
    1883         260 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    1884             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1885             :       TYPE(qs_rho_type), POINTER                         :: rho
    1886             :       TYPE(section_vals_type), POINTER                   :: ec_hfx_sections, xc_section
    1887             :       TYPE(virial_type), POINTER                         :: virial
    1888             : 
    1889         260 :       CALL timeset(routineN, handle)
    1890             : 
    1891         260 :       debug_forces = ec_env%debug_forces
    1892         260 :       debug_stress = ec_env%debug_stress
    1893             : 
    1894         260 :       logger => cp_get_default_logger()
    1895         260 :       IF (logger%para_env%is_source()) THEN
    1896         130 :          iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1897             :       ELSE
    1898         130 :          iounit = -1
    1899             :       END IF
    1900             : 
    1901             :       ! get all information on the electronic density
    1902         260 :       NULLIFY (atomic_kind_set, cell, dft_control, force, ks_env, &
    1903         260 :                matrix_ks, matrix_p, matrix_s, para_env, rho, rho_core, &
    1904         260 :                rho_g, rho_r, sab_orb, tau_r, virial)
    1905             :       CALL get_qs_env(qs_env=qs_env, &
    1906             :                       cell=cell, &
    1907             :                       dft_control=dft_control, &
    1908             :                       force=force, &
    1909             :                       ks_env=ks_env, &
    1910             :                       matrix_ks=matrix_ks, &
    1911             :                       para_env=para_env, &
    1912             :                       rho=rho, &
    1913             :                       sab_orb=sab_orb, &
    1914         260 :                       virial=virial)
    1915             : 
    1916         260 :       nspins = dft_control%nspins
    1917         260 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
    1918             : 
    1919             :       ! Conversion factor a.u. -> GPa
    1920         260 :       unit_string = "GPa"
    1921         260 :       fconv = cp_unit_from_cp2k(1.0_dp/cell%deth, TRIM(unit_string))
    1922             : 
    1923         260 :       IF (debug_stress .AND. use_virial) THEN
    1924           0 :          sttot = virial%pv_virial
    1925             :       END IF
    1926             : 
    1927         260 :       NULLIFY (pw_env)
    1928         260 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
    1929         260 :       CPASSERT(ASSOCIATED(pw_env))
    1930             : 
    1931         260 :       NULLIFY (auxbas_pw_pool, poisson_env)
    1932             :       ! gets the tmp grids
    1933             :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
    1934         260 :                       poisson_env=poisson_env)
    1935             : 
    1936             :       ! Calculate the Hartree potential
    1937         260 :       CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
    1938         260 :       CALL auxbas_pw_pool%create_pw(rhodn_tot_gspace)
    1939         260 :       CALL auxbas_pw_pool%create_pw(v_hartree_rspace)
    1940             : 
    1941         260 :       CALL pw_transfer(ec_env%vh_rspace, v_hartree_rspace)
    1942             : 
    1943             :       ! calculate output density on grid
    1944             :       ! rho_in(R):   CALL qs_rho_get(rho, rho_r=rho_r)
    1945             :       ! rho_in(G):   CALL qs_rho_get(rho, rho_g=rho_g)
    1946         260 :       CALL qs_rho_get(rho, rho_r=rho_r, rho_g=rho_g, tau_r=tau_r)
    1947         260 :       NULLIFY (rhoout_r, rhoout_g)
    1948        1820 :       ALLOCATE (rhoout_r(nspins), rhoout_g(nspins))
    1949         520 :       DO ispin = 1, nspins
    1950         260 :          CALL auxbas_pw_pool%create_pw(rhoout_r(ispin))
    1951         520 :          CALL auxbas_pw_pool%create_pw(rhoout_g(ispin))
    1952             :       END DO
    1953         260 :       CALL auxbas_pw_pool%create_pw(dv_hartree_rspace)
    1954         260 :       CALL auxbas_pw_pool%create_pw(vtot_rspace)
    1955             : 
    1956         260 :       CALL pw_zero(rhodn_tot_gspace)
    1957         520 :       DO ispin = 1, nspins
    1958             :          CALL calculate_rho_elec(ks_env=ks_env, matrix_p=ec_env%matrix_p(ispin, 1)%matrix, &
    1959             :                                  rho=rhoout_r(ispin), &
    1960             :                                  rho_gspace=rhoout_g(ispin), &
    1961             :                                  basis_type="HARRIS", &
    1962         520 :                                  task_list_external=ec_env%task_list)
    1963             :       END DO
    1964             : 
    1965             :       ! Save Harris on real space grid for use in properties
    1966         780 :       ALLOCATE (ec_env%rhoout_r(nspins))
    1967         520 :       DO ispin = 1, nspins
    1968         260 :          CALL auxbas_pw_pool%create_pw(ec_env%rhoout_r(ispin))
    1969         520 :          CALL pw_copy(rhoout_r(ispin), ec_env%rhoout_r(ispin))
    1970             :       END DO
    1971             : 
    1972         260 :       NULLIFY (tauout_r)
    1973         260 :       IF (dft_control%use_kinetic_energy_density) THEN
    1974             :          BLOCK
    1975             :             TYPE(pw_c1d_gs_type) :: tauout_g
    1976          96 :             ALLOCATE (tauout_r(nspins))
    1977          64 :             DO ispin = 1, nspins
    1978          64 :                CALL auxbas_pw_pool%create_pw(tauout_r(ispin))
    1979             :             END DO
    1980          32 :             CALL auxbas_pw_pool%create_pw(tauout_g)
    1981             : 
    1982          64 :             DO ispin = 1, nspins
    1983             :                CALL calculate_rho_elec(ks_env=ks_env, matrix_p=ec_env%matrix_p(ispin, 1)%matrix, &
    1984             :                                        rho=tauout_r(ispin), &
    1985             :                                        rho_gspace=tauout_g, &
    1986             :                                        compute_tau=.TRUE., &
    1987             :                                        basis_type="HARRIS", &
    1988          64 :                                        task_list_external=ec_env%task_list)
    1989             :             END DO
    1990             : 
    1991          64 :             CALL auxbas_pw_pool%give_back_pw(tauout_g)
    1992             :          END BLOCK
    1993             :       END IF
    1994             : 
    1995         260 :       IF (use_virial) THEN
    1996             : 
    1997             :          ! Calculate the Hartree potential
    1998         108 :          CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
    1999             : 
    2000             :          ! Get the total input density in g-space [ions + electrons]
    2001         108 :          CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho)
    2002             : 
    2003             :          ! make rho_tot_gspace with output density
    2004         108 :          CALL get_qs_env(qs_env=qs_env, rho_core=rho_core)
    2005         108 :          CALL pw_copy(rho_core, rhodn_tot_gspace)
    2006         216 :          DO ispin = 1, dft_control%nspins
    2007         216 :             CALL pw_axpy(rhoout_g(ispin), rhodn_tot_gspace)
    2008             :          END DO
    2009             : 
    2010             :          ! Volume and Green function terms
    2011         108 :          h_stress(:, :) = 0.0_dp
    2012             :          CALL pw_poisson_solve(poisson_env, &
    2013             :                                density=rho_tot_gspace, &  ! n_in
    2014             :                                ehartree=ehartree, &
    2015             :                                vhartree=v_hartree_gspace, & ! v_H[n_in]
    2016             :                                h_stress=h_stress, &
    2017         108 :                                aux_density=rhodn_tot_gspace) ! n_out
    2018             : 
    2019        1404 :          virial%pv_ehartree = virial%pv_ehartree + h_stress/REAL(para_env%num_pe, dp)
    2020        1404 :          virial%pv_virial = virial%pv_virial + h_stress/REAL(para_env%num_pe, dp)
    2021             : 
    2022         108 :          IF (debug_stress) THEN
    2023           0 :             stdeb = fconv*(h_stress/REAL(para_env%num_pe, dp))
    2024           0 :             CALL para_env%sum(stdeb)
    2025           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2026           0 :                'STRESS| GREEN 1st v_H[n_in]*n_out  ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2027             :          END IF
    2028             : 
    2029             :          ! activate stress calculation
    2030         108 :          virial%pv_calculate = .TRUE.
    2031             : 
    2032         108 :          NULLIFY (v_rspace, v_tau_rspace)
    2033             :          CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho, xc_section=ec_env%xc_section, &
    2034         108 :                             vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE.)
    2035             : 
    2036             :          ! Stress tensor XC-functional GGA contribution
    2037        1404 :          virial%pv_exc = virial%pv_exc - virial%pv_xc
    2038        1404 :          virial%pv_virial = virial%pv_virial - virial%pv_xc
    2039             : 
    2040         108 :          IF (debug_stress) THEN
    2041           0 :             stdeb = -1.0_dp*fconv*virial%pv_xc
    2042           0 :             CALL para_env%sum(stdeb)
    2043           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2044           0 :                'STRESS| GGA 1st E_xc[Pin]   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2045             :          END IF
    2046             : 
    2047         108 :          IF (ASSOCIATED(v_rspace)) THEN
    2048         216 :             DO ispin = 1, nspins
    2049         216 :                CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
    2050             :             END DO
    2051         108 :             DEALLOCATE (v_rspace)
    2052             :          END IF
    2053         108 :          IF (ASSOCIATED(v_tau_rspace)) THEN
    2054          16 :             DO ispin = 1, nspins
    2055          16 :                CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
    2056             :             END DO
    2057           8 :             DEALLOCATE (v_tau_rspace)
    2058             :          END IF
    2059         108 :          CALL pw_zero(rhodn_tot_gspace)
    2060             : 
    2061             :       END IF
    2062             : 
    2063             :       ! rho_out - rho_in
    2064         520 :       DO ispin = 1, nspins
    2065         260 :          CALL pw_axpy(rho_r(ispin), rhoout_r(ispin), -1.0_dp)
    2066         260 :          CALL pw_axpy(rho_g(ispin), rhoout_g(ispin), -1.0_dp)
    2067         260 :          CALL pw_axpy(rhoout_g(ispin), rhodn_tot_gspace)
    2068         520 :          IF (dft_control%use_kinetic_energy_density) CALL pw_axpy(tau_r(ispin), tauout_r(ispin), -1.0_dp)
    2069             :       END DO
    2070             : 
    2071             :       ! calculate associated hartree potential
    2072         260 :       IF (use_virial) THEN
    2073             : 
    2074             :          ! Stress tensor - 2nd derivative Volume and Green function contribution
    2075         108 :          h_stress(:, :) = 0.0_dp
    2076             :          CALL pw_poisson_solve(poisson_env, &
    2077             :                                density=rhodn_tot_gspace, &  ! delta_n
    2078             :                                ehartree=dehartree, &
    2079             :                                vhartree=v_hartree_gspace, & ! v_H[delta_n]
    2080             :                                h_stress=h_stress, &
    2081         108 :                                aux_density=rho_tot_gspace)  ! n_in
    2082             : 
    2083         108 :          CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
    2084             : 
    2085        1404 :          virial%pv_ehartree = virial%pv_ehartree + h_stress/REAL(para_env%num_pe, dp)
    2086        1404 :          virial%pv_virial = virial%pv_virial + h_stress/REAL(para_env%num_pe, dp)
    2087             : 
    2088         108 :          IF (debug_stress) THEN
    2089           0 :             stdeb = fconv*(h_stress/REAL(para_env%num_pe, dp))
    2090           0 :             CALL para_env%sum(stdeb)
    2091           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2092           0 :                'STRESS| GREEN 2nd V_H[dP]*n_in  ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2093             :          END IF
    2094             : 
    2095             :       ELSE
    2096             :          ! v_H[dn]
    2097             :          CALL pw_poisson_solve(poisson_env, rhodn_tot_gspace, dehartree, &
    2098         152 :                                v_hartree_gspace)
    2099             :       END IF
    2100             : 
    2101         260 :       CALL pw_transfer(v_hartree_gspace, dv_hartree_rspace)
    2102         260 :       CALL pw_scale(dv_hartree_rspace, dv_hartree_rspace%pw_grid%dvol)
    2103             :       ! Getting nuclear force contribution from the core charge density
    2104             :       ! Vh(rho_in + rho_c) + Vh(rho_out - rho_in)
    2105         260 :       CALL pw_transfer(v_hartree_rspace, vtot_rspace)
    2106         260 :       CALL pw_axpy(dv_hartree_rspace, vtot_rspace)
    2107         260 :       IF (debug_forces) fodeb(1:3) = force(1)%rho_core(1:3, 1)
    2108         260 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_ehartree
    2109         260 :       CALL integrate_v_core_rspace(vtot_rspace, qs_env)
    2110         260 :       IF (debug_forces) THEN
    2111           0 :          fodeb(1:3) = force(1)%rho_core(1:3, 1) - fodeb(1:3)
    2112           0 :          CALL para_env%sum(fodeb)
    2113           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Vtot*dncore", fodeb
    2114             :       END IF
    2115         260 :       IF (debug_stress .AND. use_virial) THEN
    2116           0 :          stdeb = fconv*(virial%pv_ehartree - stdeb)
    2117           0 :          CALL para_env%sum(stdeb)
    2118           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2119           0 :             'STRESS| Vtot*dncore', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2120             :       END IF
    2121             :       !
    2122             :       ! Pulay force from Tr P_in (V_H(drho)+ Fxc(rho_in)*drho)
    2123             :       ! RHS of CPKS equations: (V_H(drho)+ Fxc(rho_in)*drho)*C0
    2124             :       ! Fxc*drho term
    2125         260 :       xc_section => ec_env%xc_section
    2126             : 
    2127        1556 :       IF (use_virial) virial%pv_xc = 0.0_dp
    2128         260 :       NULLIFY (v_xc, v_xc_tau)
    2129             :       CALL create_kernel(qs_env, &
    2130             :                          vxc=v_xc, &
    2131             :                          vxc_tau=v_xc_tau, &
    2132             :                          rho=rho, &
    2133             :                          rho1_r=rhoout_r, &
    2134             :                          rho1_g=rhoout_g, &
    2135             :                          tau1_r=tauout_r, &
    2136             :                          xc_section=xc_section, &
    2137             :                          compute_virial=use_virial, &
    2138         260 :                          virial_xc=virial%pv_xc)
    2139             : 
    2140         260 :       IF (use_virial) THEN
    2141             :          ! Stress-tensor XC-functional 2nd GGA terms
    2142        1404 :          virial%pv_exc = virial%pv_exc + virial%pv_xc
    2143        1404 :          virial%pv_virial = virial%pv_virial + virial%pv_xc
    2144             :       END IF
    2145         260 :       IF (debug_stress .AND. use_virial) THEN
    2146           0 :          stdeb = 1.0_dp*fconv*virial%pv_xc
    2147           0 :          CALL para_env%sum(stdeb)
    2148           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2149           0 :             'STRESS| GGA 2nd f_Hxc[dP]*Pin   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2150             :       END IF
    2151             :       !
    2152         260 :       CALL get_qs_env(qs_env=qs_env, rho=rho, matrix_s_kp=matrix_s)
    2153         260 :       NULLIFY (ec_env%matrix_hz)
    2154         260 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_hz, nspins)
    2155         520 :       DO ispin = 1, nspins
    2156         260 :          ALLOCATE (ec_env%matrix_hz(ispin)%matrix)
    2157         260 :          CALL dbcsr_create(ec_env%matrix_hz(ispin)%matrix, template=matrix_s(1, 1)%matrix)
    2158         260 :          CALL dbcsr_copy(ec_env%matrix_hz(ispin)%matrix, matrix_s(1, 1)%matrix)
    2159         520 :          CALL dbcsr_set(ec_env%matrix_hz(ispin)%matrix, 0.0_dp)
    2160             :       END DO
    2161         260 :       CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
    2162             :       ! vtot = v_xc(ispin) + dv_hartree
    2163         260 :       IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
    2164         260 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
    2165             : 
    2166             :       ! Stress-tensor 2nd derivative integral contribution
    2167         260 :       IF (use_virial) THEN
    2168        1404 :          pv_loc = virial%pv_virial
    2169             :       END IF
    2170             : 
    2171         520 :       DO ispin = 1, nspins
    2172         260 :          CALL pw_scale(v_xc(ispin), v_xc(ispin)%pw_grid%dvol)
    2173         260 :          CALL pw_axpy(dv_hartree_rspace, v_xc(ispin))
    2174             :          CALL integrate_v_rspace(v_rspace=v_xc(ispin), &
    2175             :                                  hmat=ec_env%matrix_hz(ispin), &
    2176             :                                  pmat=matrix_p(ispin, 1), &
    2177             :                                  qs_env=qs_env, &
    2178         520 :                                  calculate_forces=.TRUE.)
    2179             :       END DO
    2180             : 
    2181         260 :       IF (debug_forces) THEN
    2182           0 :          fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
    2183           0 :          CALL para_env%sum(fodeb)
    2184           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pin*dKdrho", fodeb
    2185             :       END IF
    2186         260 :       IF (debug_stress .AND. use_virial) THEN
    2187           0 :          stdeb = fconv*(virial%pv_virial - stdeb)
    2188           0 :          CALL para_env%sum(stdeb)
    2189           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2190           0 :             'STRESS| INT 2nd f_Hxc[dP]*Pin    ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2191             :       END IF
    2192             : 
    2193         260 :       IF (ASSOCIATED(v_xc_tau)) THEN
    2194          16 :          IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
    2195          16 :          IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
    2196             : 
    2197          32 :          DO ispin = 1, nspins
    2198          16 :             CALL pw_scale(v_xc_tau(ispin), v_xc_tau(ispin)%pw_grid%dvol)
    2199             :             CALL integrate_v_rspace(v_rspace=v_xc_tau(ispin), &
    2200             :                                     hmat=ec_env%matrix_hz(ispin), &
    2201             :                                     pmat=matrix_p(ispin, 1), &
    2202             :                                     qs_env=qs_env, &
    2203             :                                     compute_tau=.TRUE., &
    2204          32 :                                     calculate_forces=.TRUE.)
    2205             :          END DO
    2206             : 
    2207          16 :          IF (debug_forces) THEN
    2208           0 :             fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
    2209           0 :             CALL para_env%sum(fodeb)
    2210           0 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pin*dKtaudtau", fodeb
    2211             :          END IF
    2212          16 :          IF (debug_stress .AND. use_virial) THEN
    2213           0 :             stdeb = fconv*(virial%pv_virial - stdeb)
    2214           0 :             CALL para_env%sum(stdeb)
    2215           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2216           0 :                'STRESS| INT 2nd f_xctau[dP]*Pin    ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2217             :          END IF
    2218             :       END IF
    2219             :       ! Stress-tensor 2nd derivative integral contribution
    2220         260 :       IF (use_virial) THEN
    2221        1404 :          virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - pv_loc)
    2222             :       END IF
    2223             : 
    2224             :       ! initialize srcm matrix
    2225         260 :       NULLIFY (scrm)
    2226         260 :       CALL dbcsr_allocate_matrix_set(scrm, nspins)
    2227         520 :       DO ispin = 1, nspins
    2228         260 :          ALLOCATE (scrm(ispin)%matrix)
    2229         260 :          CALL dbcsr_create(scrm(ispin)%matrix, template=ec_env%matrix_ks(ispin, 1)%matrix)
    2230         260 :          CALL dbcsr_copy(scrm(ispin)%matrix, ec_env%matrix_ks(ispin, 1)%matrix)
    2231         520 :          CALL dbcsr_set(scrm(ispin)%matrix, 0.0_dp)
    2232             :       END DO
    2233             : 
    2234             :       ! v_rspace and v_tau_rspace are generated from the auxbas pool
    2235         260 :       NULLIFY (v_rspace, v_tau_rspace)
    2236             : 
    2237             :       CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho, xc_section=ec_env%xc_section, &
    2238         260 :                          vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=eexc, just_energy=.FALSE.)
    2239             : 
    2240         260 :       IF (use_virial) THEN
    2241         108 :          eexc = 0.0_dp
    2242         108 :          IF (ASSOCIATED(v_rspace)) THEN
    2243         216 :             DO ispin = 1, nspins
    2244             :                ! 2nd deriv xc-volume term
    2245         216 :                eexc = eexc + pw_integral_ab(rhoout_r(ispin), v_rspace(ispin))
    2246             :             END DO
    2247             :          END IF
    2248         108 :          IF (ASSOCIATED(v_tau_rspace)) THEN
    2249          16 :             DO ispin = 1, nspins
    2250             :                ! 2nd deriv xc-volume term
    2251          16 :                eexc = eexc + pw_integral_ab(tauout_r(ispin), v_tau_rspace(ispin))
    2252             :             END DO
    2253             :          END IF
    2254             :       END IF
    2255             : 
    2256         260 :       IF (.NOT. ASSOCIATED(v_rspace)) THEN
    2257           0 :          ALLOCATE (v_rspace(nspins))
    2258           0 :          DO ispin = 1, nspins
    2259           0 :             CALL auxbas_pw_pool%create_pw(v_rspace(ispin))
    2260           0 :             CALL pw_zero(v_rspace(ispin))
    2261             :          END DO
    2262             :       END IF
    2263             : 
    2264             :       ! Stress-tensor contribution derivative of integrand
    2265             :       ! int v_Hxc[n^în]*n^out
    2266         260 :       IF (use_virial) THEN
    2267        1404 :          pv_loc = virial%pv_virial
    2268             :       END IF
    2269             : 
    2270         260 :       IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
    2271         260 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
    2272         520 :       DO ispin = 1, nspins
    2273             :          ! Add v_hartree + v_xc = v_rspace
    2274         260 :          CALL pw_scale(v_rspace(ispin), v_rspace(ispin)%pw_grid%dvol)
    2275         260 :          CALL pw_axpy(v_hartree_rspace, v_rspace(ispin))
    2276             :          ! integrate over potential <a|V|b>
    2277             :          CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
    2278             :                                  hmat=scrm(ispin), &
    2279             :                                  pmat=ec_env%matrix_p(ispin, 1), &
    2280             :                                  qs_env=qs_env, &
    2281             :                                  calculate_forces=.TRUE., &
    2282             :                                  basis_type="HARRIS", &
    2283         520 :                                  task_list_external=ec_env%task_list)
    2284             :       END DO
    2285             : 
    2286         260 :       IF (debug_forces) THEN
    2287           0 :          fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
    2288           0 :          CALL para_env%sum(fodeb)
    2289           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dVhxc ", fodeb
    2290             :       END IF
    2291         260 :       IF (debug_stress .AND. use_virial) THEN
    2292           0 :          stdeb = fconv*(virial%pv_virial - stdeb)
    2293           0 :          CALL para_env%sum(stdeb)
    2294           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2295           0 :             'STRESS| INT Pout*dVhxc   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2296             :       END IF
    2297             : 
    2298             :       ! Stress-tensor
    2299         260 :       IF (use_virial) THEN
    2300        1404 :          virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - pv_loc)
    2301             :       END IF
    2302             : 
    2303         260 :       IF (ASSOCIATED(v_tau_rspace)) THEN
    2304          16 :          IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
    2305          32 :          DO ispin = 1, nspins
    2306             :             ! integrate over Tau-potential <nabla.a|V|nabla.b>
    2307          16 :             CALL pw_scale(v_tau_rspace(ispin), v_tau_rspace(ispin)%pw_grid%dvol)
    2308             :             CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
    2309             :                                     hmat=scrm(ispin), &
    2310             :                                     pmat=ec_env%matrix_p(ispin, 1), &
    2311             :                                     qs_env=qs_env, &
    2312             :                                     calculate_forces=.TRUE., &
    2313             :                                     compute_tau=.TRUE., &
    2314             :                                     basis_type="HARRIS", &
    2315          32 :                                     task_list_external=ec_env%task_list)
    2316             :          END DO
    2317          16 :          IF (debug_forces) THEN
    2318           0 :             fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
    2319           0 :             CALL para_env%sum(fodeb)
    2320           0 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dVhxc_tau ", fodeb
    2321             :          END IF
    2322             :       END IF
    2323             : 
    2324             : !------------------------------------------------------------------------------
    2325             : ! HFX direct force
    2326             : !------------------------------------------------------------------------------
    2327             : 
    2328             :       ! If hybrid functional
    2329         260 :       ec_hfx_sections => section_vals_get_subs_vals(qs_env%input, "DFT%ENERGY_CORRECTION%XC%HF")
    2330         260 :       CALL section_vals_get(ec_hfx_sections, explicit=do_ec_hfx)
    2331             : 
    2332         260 :       IF (do_ec_hfx) THEN
    2333             : 
    2334           0 :          IF (debug_forces) fodeb(1:3) = force(1)%fock_4c(1:3, 1)
    2335           0 :          IF (use_virial) virial%pv_fock_4c = 0.0_dp
    2336             : 
    2337             :          CALL calculate_exx(qs_env=qs_env, &
    2338             :                             unit_nr=iounit, &
    2339             :                             hfx_sections=ec_hfx_sections, &
    2340             :                             x_data=ec_env%x_data, &
    2341             :                             do_gw=.FALSE., &
    2342             :                             do_admm=ec_env%do_ec_admm, &
    2343             :                             calc_forces=.TRUE., &
    2344             :                             reuse_hfx=ec_env%reuse_hfx, &
    2345             :                             do_im_time=.FALSE., &
    2346             :                             E_ex_from_GW=dummy_real, &
    2347             :                             E_admm_from_GW=dummy_real2, &
    2348           0 :                             t3=dummy_real)
    2349             : 
    2350           0 :          IF (use_virial) THEN
    2351           0 :             virial%pv_exx = virial%pv_exx - virial%pv_fock_4c
    2352           0 :             virial%pv_virial = virial%pv_virial - virial%pv_fock_4c
    2353           0 :             virial%pv_calculate = .FALSE.
    2354             :          END IF
    2355           0 :          IF (debug_forces) THEN
    2356           0 :             fodeb(1:3) = force(1)%fock_4c(1:3, 1) - fodeb(1:3)
    2357           0 :             CALL para_env%sum(fodeb)
    2358           0 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*hfx ", fodeb
    2359             :          END IF
    2360           0 :          IF (debug_stress .AND. use_virial) THEN
    2361           0 :             stdeb = -1.0_dp*fconv*virial%pv_fock_4c
    2362           0 :             CALL para_env%sum(stdeb)
    2363           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2364           0 :                'STRESS| Pout*hfx  ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2365             :          END IF
    2366             : 
    2367             :       END IF
    2368             : 
    2369             : !------------------------------------------------------------------------------
    2370             : 
    2371             :       ! delete scrm matrix
    2372         260 :       CALL dbcsr_deallocate_matrix_set(scrm)
    2373             : 
    2374             :       ! return pw grids
    2375         260 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_rspace)
    2376         520 :       DO ispin = 1, nspins
    2377         260 :          CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
    2378         520 :          IF (ASSOCIATED(v_tau_rspace)) THEN
    2379          16 :             CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
    2380             :          END IF
    2381             :       END DO
    2382         260 :       IF (ASSOCIATED(v_tau_rspace)) DEALLOCATE (v_tau_rspace)
    2383             : 
    2384             :       ! Core overlap
    2385         260 :       IF (debug_forces) fodeb(1:3) = force(1)%core_overlap(1:3, 1)
    2386         260 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_ecore_overlap
    2387         260 :       CALL calculate_ecore_overlap(qs_env, para_env, .TRUE., E_overlap_core=eovrl)
    2388         260 :       IF (debug_forces) THEN
    2389           0 :          fodeb(1:3) = force(1)%core_overlap(1:3, 1) - fodeb(1:3)
    2390           0 :          CALL para_env%sum(fodeb)
    2391           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: CoreOverlap", fodeb
    2392             :       END IF
    2393         260 :       IF (debug_stress .AND. use_virial) THEN
    2394           0 :          stdeb = fconv*(stdeb - virial%pv_ecore_overlap)
    2395           0 :          CALL para_env%sum(stdeb)
    2396           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2397           0 :             'STRESS| CoreOverlap   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2398             :       END IF
    2399             : 
    2400         260 :       IF (debug_forces) THEN
    2401           0 :          CALL get_qs_env(qs_env, natom=natom, atomic_kind_set=atomic_kind_set)
    2402           0 :          ALLOCATE (ftot(3, natom))
    2403           0 :          CALL total_qs_force(ftot, force, atomic_kind_set)
    2404           0 :          fodeb(1:3) = ftot(1:3, 1)
    2405           0 :          DEALLOCATE (ftot)
    2406           0 :          CALL para_env%sum(fodeb)
    2407           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Force Explicit", fodeb
    2408             :       END IF
    2409             : 
    2410         260 :       DEALLOCATE (v_rspace)
    2411             :       !
    2412         260 :       CALL auxbas_pw_pool%give_back_pw(dv_hartree_rspace)
    2413         260 :       CALL auxbas_pw_pool%give_back_pw(vtot_rspace)
    2414         520 :       DO ispin = 1, nspins
    2415         260 :          CALL auxbas_pw_pool%give_back_pw(rhoout_r(ispin))
    2416         260 :          CALL auxbas_pw_pool%give_back_pw(rhoout_g(ispin))
    2417         520 :          CALL auxbas_pw_pool%give_back_pw(v_xc(ispin))
    2418             :       END DO
    2419         260 :       DEALLOCATE (rhoout_r, rhoout_g, v_xc)
    2420         260 :       IF (ASSOCIATED(tauout_r)) THEN
    2421          64 :          DO ispin = 1, nspins
    2422          64 :             CALL auxbas_pw_pool%give_back_pw(tauout_r(ispin))
    2423             :          END DO
    2424          32 :          DEALLOCATE (tauout_r)
    2425             :       END IF
    2426         260 :       IF (ASSOCIATED(v_xc_tau)) THEN
    2427          32 :          DO ispin = 1, nspins
    2428          32 :             CALL auxbas_pw_pool%give_back_pw(v_xc_tau(ispin))
    2429             :          END DO
    2430          16 :          DEALLOCATE (v_xc_tau)
    2431             :       END IF
    2432         260 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
    2433         260 :       CALL auxbas_pw_pool%give_back_pw(rhodn_tot_gspace)
    2434             : 
    2435             :       ! Stress tensor - volume terms need to be stored,
    2436             :       ! for a sign correction in QS at the end of qs_force
    2437         260 :       IF (use_virial) THEN
    2438         108 :          IF (qs_env%energy_correction) THEN
    2439         108 :             ec_env%ehartree = ehartree + dehartree
    2440         108 :             ec_env%exc = exc + eexc
    2441             :          END IF
    2442             :       END IF
    2443             : 
    2444         260 :       IF (debug_stress .AND. use_virial) THEN
    2445             :          ! In total: -1.0*E_H
    2446           0 :          stdeb = -1.0_dp*fconv*ehartree
    2447           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2448           0 :             'STRESS| VOL 1st v_H[n_in]*n_out', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2449             : 
    2450           0 :          stdeb = -1.0_dp*fconv*exc
    2451           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2452           0 :             'STRESS| VOL 1st E_XC[n_in]', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2453             : 
    2454           0 :          stdeb = -1.0_dp*fconv*dehartree
    2455           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2456           0 :             'STRESS| VOL 2nd v_H[dP]*n_in', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2457             : 
    2458           0 :          stdeb = -1.0_dp*fconv*eexc
    2459           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2460           0 :             'STRESS| VOL 2nd v_XC[n_in]*dP', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2461             : 
    2462             :          ! For debugging, create a second virial environment,
    2463             :          ! apply volume terms immediately
    2464             :          BLOCK
    2465             :             TYPE(virial_type) :: virdeb
    2466           0 :             virdeb = virial
    2467             : 
    2468           0 :             CALL para_env%sum(virdeb%pv_overlap)
    2469           0 :             CALL para_env%sum(virdeb%pv_ekinetic)
    2470           0 :             CALL para_env%sum(virdeb%pv_ppl)
    2471           0 :             CALL para_env%sum(virdeb%pv_ppnl)
    2472           0 :             CALL para_env%sum(virdeb%pv_ecore_overlap)
    2473           0 :             CALL para_env%sum(virdeb%pv_ehartree)
    2474           0 :             CALL para_env%sum(virdeb%pv_exc)
    2475           0 :             CALL para_env%sum(virdeb%pv_exx)
    2476           0 :             CALL para_env%sum(virdeb%pv_vdw)
    2477           0 :             CALL para_env%sum(virdeb%pv_mp2)
    2478           0 :             CALL para_env%sum(virdeb%pv_nlcc)
    2479           0 :             CALL para_env%sum(virdeb%pv_gapw)
    2480           0 :             CALL para_env%sum(virdeb%pv_lrigpw)
    2481           0 :             CALL para_env%sum(virdeb%pv_virial)
    2482           0 :             CALL symmetrize_virial(virdeb)
    2483             : 
    2484             :             ! apply stress-tensor 1st and 2nd volume terms
    2485           0 :             DO i = 1, 3
    2486           0 :                virdeb%pv_ehartree(i, i) = virdeb%pv_ehartree(i, i) - 2.0_dp*(ehartree + dehartree)
    2487             :                virdeb%pv_virial(i, i) = virdeb%pv_virial(i, i) - exc - eexc &
    2488           0 :                                         - 2.0_dp*(ehartree + dehartree)
    2489           0 :                virdeb%pv_exc(i, i) = virdeb%pv_exc(i, i) - exc - eexc
    2490             :                ! The factor 2 is a hack. It compensates the plus sign in h_stress/pw_poisson_solve.
    2491             :                ! The sign in pw_poisson_solve is correct for FIST, but not for QS.
    2492             :                ! There should be a more elegant solution to that ...
    2493             :             END DO
    2494             : 
    2495           0 :             CALL para_env%sum(sttot)
    2496           0 :             stdeb = fconv*(virdeb%pv_virial - sttot)
    2497           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2498           0 :                'STRESS| Explicit electronic stress   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2499             : 
    2500           0 :             stdeb = fconv*(virdeb%pv_virial)
    2501           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
    2502           0 :                'STRESS| Explicit total stress   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
    2503             : 
    2504           0 :             CALL write_stress_tensor_components(virdeb, iounit, cell, unit_string)
    2505           0 :             CALL write_stress_tensor(virdeb%pv_virial, iounit, cell, unit_string, .FALSE.)
    2506             : 
    2507             :          END BLOCK
    2508             :       END IF
    2509             : 
    2510         260 :       CALL timestop(handle)
    2511             : 
    2512         780 :    END SUBROUTINE ec_build_ks_matrix_force
    2513             : 
    2514             : ! **************************************************************************************************
    2515             : !> \brief Solve KS equation for a given matrix
    2516             : !> \param qs_env ...
    2517             : !> \param ec_env ...
    2518             : !> \par History
    2519             : !>      03.2014 created [JGH]
    2520             : !> \author JGH
    2521             : ! **************************************************************************************************
    2522         346 :    SUBROUTINE ec_ks_solver(qs_env, ec_env)
    2523             : 
    2524             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2525             :       TYPE(energy_correction_type), POINTER              :: ec_env
    2526             : 
    2527             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ec_ks_solver'
    2528             : 
    2529             :       CHARACTER(LEN=default_string_length)               :: headline
    2530             :       INTEGER                                            :: handle, ispin, nspins
    2531         346 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ksmat, pmat, smat, wmat
    2532             :       TYPE(dft_control_type), POINTER                    :: dft_control
    2533             : 
    2534         346 :       CALL timeset(routineN, handle)
    2535             : 
    2536         346 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
    2537         346 :       nspins = dft_control%nspins
    2538             : 
    2539             :       ! create density matrix
    2540         346 :       IF (.NOT. ASSOCIATED(ec_env%matrix_p)) THEN
    2541         292 :          headline = "DENSITY MATRIX"
    2542         292 :          CALL dbcsr_allocate_matrix_set(ec_env%matrix_p, nspins, 1)
    2543         584 :          DO ispin = 1, nspins
    2544         292 :             ALLOCATE (ec_env%matrix_p(ispin, 1)%matrix)
    2545             :             CALL dbcsr_create(ec_env%matrix_p(ispin, 1)%matrix, name=TRIM(headline), &
    2546         292 :                               template=ec_env%matrix_s(1, 1)%matrix)
    2547         584 :             CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_p(ispin, 1)%matrix, ec_env%sab_orb)
    2548             :          END DO
    2549             :       END IF
    2550             :       ! create energy weighted density matrix
    2551         346 :       IF (.NOT. ASSOCIATED(ec_env%matrix_w)) THEN
    2552         292 :          headline = "ENERGY WEIGHTED DENSITY MATRIX"
    2553         292 :          CALL dbcsr_allocate_matrix_set(ec_env%matrix_w, nspins, 1)
    2554         584 :          DO ispin = 1, nspins
    2555         292 :             ALLOCATE (ec_env%matrix_w(ispin, 1)%matrix)
    2556             :             CALL dbcsr_create(ec_env%matrix_w(ispin, 1)%matrix, name=TRIM(headline), &
    2557         292 :                               template=ec_env%matrix_s(1, 1)%matrix)
    2558         584 :             CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_w(ispin, 1)%matrix, ec_env%sab_orb)
    2559             :          END DO
    2560             :       END IF
    2561             : 
    2562         346 :       IF (ec_env%mao) THEN
    2563           4 :          CALL mao_create_matrices(ec_env, ksmat, smat, pmat, wmat)
    2564             :       ELSE
    2565         342 :          ksmat => ec_env%matrix_ks
    2566         342 :          smat => ec_env%matrix_s
    2567         342 :          pmat => ec_env%matrix_p
    2568         342 :          wmat => ec_env%matrix_w
    2569             :       END IF
    2570             : 
    2571         658 :       SELECT CASE (ec_env%ks_solver)
    2572             :       CASE (ec_diagonalization)
    2573         312 :          CALL ec_diag_solver(qs_env, ksmat, smat, pmat, wmat)
    2574             :       CASE (ec_ot_diag)
    2575           4 :          CALL ec_ot_diag_solver(qs_env, ec_env, ksmat, smat, pmat, wmat)
    2576             :       CASE (ec_matrix_sign, ec_matrix_trs4, ec_matrix_tc2)
    2577          30 :          CALL ec_ls_init(qs_env, ksmat, smat)
    2578          30 :          CALL ec_ls_solver(qs_env, pmat, wmat, ec_ls_method=ec_env%ks_solver)
    2579             :       CASE DEFAULT
    2580         346 :          CPASSERT(.FALSE.)
    2581             :       END SELECT
    2582             : 
    2583         346 :       IF (ec_env%mao) THEN
    2584           4 :          CALL mao_release_matrices(ec_env, ksmat, smat, pmat, wmat)
    2585             :       END IF
    2586             : 
    2587         346 :       CALL timestop(handle)
    2588             : 
    2589         346 :    END SUBROUTINE ec_ks_solver
    2590             : 
    2591             : ! **************************************************************************************************
    2592             : !> \brief Create matrices with MAO sizes
    2593             : !> \param ec_env ...
    2594             : !> \param ksmat ...
    2595             : !> \param smat ...
    2596             : !> \param pmat ...
    2597             : !> \param wmat ...
    2598             : !> \par History
    2599             : !>      08.2016 created [JGH]
    2600             : !> \author JGH
    2601             : ! **************************************************************************************************
    2602           8 :    SUBROUTINE mao_create_matrices(ec_env, ksmat, smat, pmat, wmat)
    2603             : 
    2604             :       TYPE(energy_correction_type), POINTER              :: ec_env
    2605             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ksmat, smat, pmat, wmat
    2606             : 
    2607             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'mao_create_matrices'
    2608             : 
    2609             :       INTEGER                                            :: handle, ispin, nspins
    2610           4 :       INTEGER, DIMENSION(:), POINTER                     :: col_blk_sizes
    2611             :       TYPE(dbcsr_distribution_type)                      :: dbcsr_dist
    2612           4 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: mao_coef
    2613             :       TYPE(dbcsr_type)                                   :: cgmat
    2614             : 
    2615           4 :       CALL timeset(routineN, handle)
    2616             : 
    2617           4 :       mao_coef => ec_env%mao_coef
    2618             : 
    2619           4 :       NULLIFY (ksmat, smat, pmat, wmat)
    2620           4 :       nspins = SIZE(ec_env%matrix_ks, 1)
    2621           4 :       CALL dbcsr_get_info(mao_coef(1)%matrix, col_blk_size=col_blk_sizes, distribution=dbcsr_dist)
    2622           4 :       CALL dbcsr_allocate_matrix_set(ksmat, nspins, 1)
    2623           4 :       CALL dbcsr_allocate_matrix_set(smat, nspins, 1)
    2624           8 :       DO ispin = 1, nspins
    2625           4 :          ALLOCATE (ksmat(ispin, 1)%matrix)
    2626             :          CALL dbcsr_create(ksmat(ispin, 1)%matrix, dist=dbcsr_dist, name="MAO KS mat", &
    2627             :                            matrix_type=dbcsr_type_symmetric, row_blk_size=col_blk_sizes, &
    2628           4 :                            col_blk_size=col_blk_sizes)
    2629           4 :          ALLOCATE (smat(ispin, 1)%matrix)
    2630             :          CALL dbcsr_create(smat(ispin, 1)%matrix, dist=dbcsr_dist, name="MAO S mat", &
    2631             :                            matrix_type=dbcsr_type_symmetric, row_blk_size=col_blk_sizes, &
    2632           8 :                            col_blk_size=col_blk_sizes)
    2633             :       END DO
    2634             :       !
    2635           4 :       CALL dbcsr_create(cgmat, name="TEMP matrix", template=mao_coef(1)%matrix)
    2636           8 :       DO ispin = 1, nspins
    2637             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ec_env%matrix_s(1, 1)%matrix, mao_coef(ispin)%matrix, &
    2638           4 :                              0.0_dp, cgmat)
    2639           4 :          CALL dbcsr_multiply("T", "N", 1.0_dp, mao_coef(ispin)%matrix, cgmat, 0.0_dp, smat(ispin, 1)%matrix)
    2640             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ec_env%matrix_ks(1, 1)%matrix, mao_coef(ispin)%matrix, &
    2641           4 :                              0.0_dp, cgmat)
    2642           8 :          CALL dbcsr_multiply("T", "N", 1.0_dp, mao_coef(ispin)%matrix, cgmat, 0.0_dp, ksmat(ispin, 1)%matrix)
    2643             :       END DO
    2644           4 :       CALL dbcsr_release(cgmat)
    2645             : 
    2646           4 :       CALL dbcsr_allocate_matrix_set(pmat, nspins, 1)
    2647           8 :       DO ispin = 1, nspins
    2648           4 :          ALLOCATE (pmat(ispin, 1)%matrix)
    2649           4 :          CALL dbcsr_create(pmat(ispin, 1)%matrix, template=smat(1, 1)%matrix, name="MAO P mat")
    2650           8 :          CALL cp_dbcsr_alloc_block_from_nbl(pmat(ispin, 1)%matrix, ec_env%sab_orb)
    2651             :       END DO
    2652             : 
    2653           4 :       CALL dbcsr_allocate_matrix_set(wmat, nspins, 1)
    2654           8 :       DO ispin = 1, nspins
    2655           4 :          ALLOCATE (wmat(ispin, 1)%matrix)
    2656           4 :          CALL dbcsr_create(wmat(ispin, 1)%matrix, template=smat(1, 1)%matrix, name="MAO W mat")
    2657           8 :          CALL cp_dbcsr_alloc_block_from_nbl(wmat(ispin, 1)%matrix, ec_env%sab_orb)
    2658             :       END DO
    2659             : 
    2660           4 :       CALL timestop(handle)
    2661             : 
    2662           4 :    END SUBROUTINE mao_create_matrices
    2663             : 
    2664             : ! **************************************************************************************************
    2665             : !> \brief Release matrices with MAO sizes
    2666             : !> \param ec_env ...
    2667             : !> \param ksmat ...
    2668             : !> \param smat ...
    2669             : !> \param pmat ...
    2670             : !> \param wmat ...
    2671             : !> \par History
    2672             : !>      08.2016 created [JGH]
    2673             : !> \author JGH
    2674             : ! **************************************************************************************************
    2675           4 :    SUBROUTINE mao_release_matrices(ec_env, ksmat, smat, pmat, wmat)
    2676             : 
    2677             :       TYPE(energy_correction_type), POINTER              :: ec_env
    2678             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ksmat, smat, pmat, wmat
    2679             : 
    2680             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'mao_release_matrices'
    2681             : 
    2682             :       INTEGER                                            :: handle, ispin, nspins
    2683           4 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: mao_coef
    2684             :       TYPE(dbcsr_type)                                   :: cgmat
    2685             : 
    2686           4 :       CALL timeset(routineN, handle)
    2687             : 
    2688           4 :       mao_coef => ec_env%mao_coef
    2689           4 :       nspins = SIZE(mao_coef, 1)
    2690             : 
    2691             :       ! save pmat/wmat in full basis format
    2692           4 :       CALL dbcsr_create(cgmat, name="TEMP matrix", template=mao_coef(1)%matrix)
    2693           8 :       DO ispin = 1, nspins
    2694           4 :          CALL dbcsr_multiply("N", "N", 1.0_dp, mao_coef(ispin)%matrix, pmat(ispin, 1)%matrix, 0.0_dp, cgmat)
    2695             :          CALL dbcsr_multiply("N", "T", 1.0_dp, mao_coef(ispin)%matrix, cgmat, 0.0_dp, &
    2696           4 :                              ec_env%matrix_p(ispin, 1)%matrix, retain_sparsity=.TRUE.)
    2697           4 :          CALL dbcsr_multiply("N", "N", 1.0_dp, mao_coef(ispin)%matrix, wmat(ispin, 1)%matrix, 0.0_dp, cgmat)
    2698             :          CALL dbcsr_multiply("N", "T", 1.0_dp, mao_coef(ispin)%matrix, cgmat, 0.0_dp, &
    2699           8 :                              ec_env%matrix_w(ispin, 1)%matrix, retain_sparsity=.TRUE.)
    2700             :       END DO
    2701           4 :       CALL dbcsr_release(cgmat)
    2702             : 
    2703           4 :       CALL dbcsr_deallocate_matrix_set(ksmat)
    2704           4 :       CALL dbcsr_deallocate_matrix_set(smat)
    2705           4 :       CALL dbcsr_deallocate_matrix_set(pmat)
    2706           4 :       CALL dbcsr_deallocate_matrix_set(wmat)
    2707             : 
    2708           4 :       CALL timestop(handle)
    2709             : 
    2710           4 :    END SUBROUTINE mao_release_matrices
    2711             : 
    2712             : ! **************************************************************************************************
    2713             : !> \brief Solve KS equation using diagonalization
    2714             : !> \param qs_env ...
    2715             : !> \param matrix_ks ...
    2716             : !> \param matrix_s ...
    2717             : !> \param matrix_p ...
    2718             : !> \param matrix_w ...
    2719             : !> \par History
    2720             : !>      03.2014 created [JGH]
    2721             : !> \author JGH
    2722             : ! **************************************************************************************************
    2723         312 :    SUBROUTINE ec_diag_solver(qs_env, matrix_ks, matrix_s, matrix_p, matrix_w)
    2724             : 
    2725             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2726             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks, matrix_s, matrix_p, matrix_w
    2727             : 
    2728             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ec_diag_solver'
    2729             : 
    2730             :       INTEGER                                            :: handle, ispin, nmo(2), nsize, nspins
    2731             :       REAL(KIND=dp)                                      :: eps_filter, focc(2)
    2732         312 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: eigenvalues
    2733             :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
    2734             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct
    2735             :       TYPE(cp_fm_type)                                   :: fm_ks, fm_mo, fm_ortho
    2736             :       TYPE(dbcsr_type), POINTER                          :: buf1_dbcsr, buf2_dbcsr, buf3_dbcsr, &
    2737             :                                                             ortho_dbcsr, ref_matrix
    2738             :       TYPE(dft_control_type), POINTER                    :: dft_control
    2739             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2740             : 
    2741         312 :       CALL timeset(routineN, handle)
    2742             : 
    2743         312 :       NULLIFY (blacs_env, para_env)
    2744         312 :       CALL get_qs_env(qs_env=qs_env, blacs_env=blacs_env, para_env=para_env)
    2745             : 
    2746         312 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
    2747         312 :       eps_filter = dft_control%qs_control%eps_filter_matrix
    2748         312 :       nspins = dft_control%nspins
    2749             : 
    2750         312 :       nmo = 0
    2751         312 :       CALL get_qs_env(qs_env=qs_env, nelectron_spin=nmo)
    2752         936 :       focc = 1._dp
    2753         312 :       IF (nspins == 1) THEN
    2754         936 :          focc = 2._dp
    2755         312 :          nmo(1) = nmo(1)/2
    2756             :       END IF
    2757             : 
    2758         312 :       CALL dbcsr_get_info(matrix_ks(1, 1)%matrix, nfullrows_total=nsize)
    2759         936 :       ALLOCATE (eigenvalues(nsize))
    2760             : 
    2761         312 :       NULLIFY (fm_struct, ref_matrix)
    2762             :       CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=nsize, &
    2763         312 :                                ncol_global=nsize, para_env=para_env)
    2764         312 :       CALL cp_fm_create(fm_ortho, fm_struct)
    2765         312 :       CALL cp_fm_create(fm_ks, fm_struct)
    2766         312 :       CALL cp_fm_create(fm_mo, fm_struct)
    2767         312 :       CALL cp_fm_struct_release(fm_struct)
    2768             : 
    2769             :       ! factorization
    2770         312 :       ref_matrix => matrix_s(1, 1)%matrix
    2771         312 :       NULLIFY (ortho_dbcsr, buf1_dbcsr, buf2_dbcsr, buf3_dbcsr)
    2772         312 :       CALL dbcsr_init_p(ortho_dbcsr)
    2773             :       CALL dbcsr_create(ortho_dbcsr, template=ref_matrix, &
    2774         312 :                         matrix_type=dbcsr_type_no_symmetry)
    2775         312 :       CALL dbcsr_init_p(buf1_dbcsr)
    2776             :       CALL dbcsr_create(buf1_dbcsr, template=ref_matrix, &
    2777         312 :                         matrix_type=dbcsr_type_no_symmetry)
    2778         312 :       CALL dbcsr_init_p(buf2_dbcsr)
    2779             :       CALL dbcsr_create(buf2_dbcsr, template=ref_matrix, &
    2780         312 :                         matrix_type=dbcsr_type_no_symmetry)
    2781         312 :       CALL dbcsr_init_p(buf3_dbcsr)
    2782             :       CALL dbcsr_create(buf3_dbcsr, template=ref_matrix, &
    2783         312 :                         matrix_type=dbcsr_type_no_symmetry)
    2784             : 
    2785         312 :       ref_matrix => matrix_s(1, 1)%matrix
    2786         312 :       CALL copy_dbcsr_to_fm(ref_matrix, fm_ortho)
    2787         312 :       CALL cp_fm_cholesky_decompose(fm_ortho)
    2788         312 :       CALL cp_fm_triangular_invert(fm_ortho)
    2789         312 :       CALL cp_fm_set_all(fm_ks, 0.0_dp)
    2790         312 :       CALL cp_fm_to_fm_triangular(fm_ortho, fm_ks, "U")
    2791         312 :       CALL copy_fm_to_dbcsr(fm_ks, ortho_dbcsr)
    2792         624 :       DO ispin = 1, nspins
    2793             :          ! calculate ZHZ(T)
    2794         312 :          CALL dbcsr_desymmetrize(matrix_ks(ispin, 1)%matrix, buf1_dbcsr)
    2795             :          CALL dbcsr_multiply("N", "N", 1.0_dp, buf1_dbcsr, ortho_dbcsr, &
    2796         312 :                              0.0_dp, buf2_dbcsr, filter_eps=eps_filter)
    2797             :          CALL dbcsr_multiply("T", "N", 1.0_dp, ortho_dbcsr, buf2_dbcsr, &
    2798         312 :                              0.0_dp, buf1_dbcsr, filter_eps=eps_filter)
    2799             :          ! copy to fm format
    2800         312 :          CALL copy_dbcsr_to_fm(buf1_dbcsr, fm_ks)
    2801         312 :          CALL choose_eigv_solver(fm_ks, fm_mo, eigenvalues)
    2802             :          ! back transform of mos c = Z(T)*c
    2803         312 :          CALL copy_fm_to_dbcsr(fm_mo, buf1_dbcsr)
    2804             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ortho_dbcsr, buf1_dbcsr, &
    2805         312 :                              0.0_dp, buf2_dbcsr, filter_eps=eps_filter)
    2806             :          ! density matrix
    2807         312 :          CALL dbcsr_set(matrix_p(ispin, 1)%matrix, 0.0_dp)
    2808             :          CALL dbcsr_multiply("N", "T", focc(ispin), buf2_dbcsr, buf2_dbcsr, &
    2809             :                              1.0_dp, matrix_p(ispin, 1)%matrix, &
    2810         312 :                              retain_sparsity=.TRUE., last_k=nmo(ispin))
    2811             : 
    2812             :          ! energy weighted density matrix
    2813         312 :          CALL dbcsr_set(matrix_w(ispin, 1)%matrix, 0.0_dp)
    2814         312 :          CALL cp_fm_column_scale(fm_mo, eigenvalues)
    2815         312 :          CALL copy_fm_to_dbcsr(fm_mo, buf1_dbcsr)
    2816             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ortho_dbcsr, buf1_dbcsr, &
    2817         312 :                              0.0_dp, buf3_dbcsr, filter_eps=eps_filter)
    2818             :          CALL dbcsr_multiply("N", "T", focc(ispin), buf2_dbcsr, buf3_dbcsr, &
    2819             :                              1.0_dp, matrix_w(ispin, 1)%matrix, &
    2820         624 :                              retain_sparsity=.TRUE., last_k=nmo(ispin))
    2821             :       END DO
    2822             : 
    2823         312 :       CALL cp_fm_release(fm_ks)
    2824         312 :       CALL cp_fm_release(fm_mo)
    2825         312 :       CALL cp_fm_release(fm_ortho)
    2826         312 :       CALL dbcsr_release(ortho_dbcsr)
    2827         312 :       CALL dbcsr_release(buf1_dbcsr)
    2828         312 :       CALL dbcsr_release(buf2_dbcsr)
    2829         312 :       CALL dbcsr_release(buf3_dbcsr)
    2830         312 :       DEALLOCATE (ortho_dbcsr, buf1_dbcsr, buf2_dbcsr, buf3_dbcsr)
    2831         312 :       DEALLOCATE (eigenvalues)
    2832             : 
    2833         312 :       CALL timestop(handle)
    2834             : 
    2835         936 :    END SUBROUTINE ec_diag_solver
    2836             : 
    2837             : ! **************************************************************************************************
    2838             : !> \brief Calculate the energy correction
    2839             : !> \param ec_env ...
    2840             : !> \param unit_nr ...
    2841             : !> \author Creation (03.2014,JGH)
    2842             : ! **************************************************************************************************
    2843         530 :    SUBROUTINE ec_energy(ec_env, unit_nr)
    2844             :       TYPE(energy_correction_type)                       :: ec_env
    2845             :       INTEGER, INTENT(IN)                                :: unit_nr
    2846             : 
    2847             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ec_energy'
    2848             : 
    2849             :       INTEGER                                            :: handle, ispin, nspins
    2850             :       REAL(KIND=dp)                                      :: eband, trace
    2851             : 
    2852         530 :       CALL timeset(routineN, handle)
    2853             : 
    2854         530 :       nspins = SIZE(ec_env%matrix_p, 1)
    2855        1060 :       DO ispin = 1, nspins
    2856         530 :          CALL dbcsr_dot(ec_env%matrix_p(ispin, 1)%matrix, ec_env%matrix_s(1, 1)%matrix, trace)
    2857        1060 :          IF (unit_nr > 0) WRITE (unit_nr, '(T3,A,T65,F16.10)') 'Tr[PS] ', trace
    2858             :       END DO
    2859             : 
    2860             :       ! Total energy depends on energy correction method
    2861         530 :       SELECT CASE (ec_env%energy_functional)
    2862             :       CASE (ec_functional_harris)
    2863             : 
    2864             :          ! Get energy of "band structure" term
    2865             :          eband = 0.0_dp
    2866         692 :          DO ispin = 1, nspins
    2867         346 :             CALL dbcsr_dot(ec_env%matrix_ks(ispin, 1)%matrix, ec_env%matrix_p(ispin, 1)%matrix, trace)
    2868         692 :             eband = eband + trace
    2869             :          END DO
    2870         346 :          ec_env%eband = eband + ec_env%efield_nuclear
    2871             : 
    2872             :          ! Add Harris functional "correction" terms
    2873         346 :          ec_env%etotal = ec_env%eband + ec_env%ehartree + ec_env%exc - ec_env%vhxc + ec_env%edispersion - ec_env%ex
    2874         346 :          IF (unit_nr > 0) THEN
    2875         173 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Eband    ", ec_env%eband
    2876         173 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ehartree ", ec_env%ehartree
    2877         173 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Exc      ", ec_env%exc
    2878         173 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ex       ", ec_env%ex
    2879         173 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Evhxc    ", ec_env%vhxc
    2880         173 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Edisp    ", ec_env%edispersion
    2881         173 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Etotal Harris Functional   ", ec_env%etotal
    2882             :          END IF
    2883             : 
    2884             :       CASE (ec_functional_dc)
    2885             : 
    2886             :          ! Core hamiltonian energy
    2887         176 :          CALL calculate_ptrace(ec_env%matrix_h, ec_env%matrix_p, ec_env%ecore, SIZE(ec_env%matrix_p, 1))
    2888             : 
    2889         176 :          ec_env%ecore = ec_env%ecore + ec_env%efield_nuclear
    2890             :          ec_env%etotal = ec_env%ecore + ec_env%ehartree + ec_env%exc + ec_env%edispersion &
    2891         176 :                          + ec_env%ex + ec_env%exc_aux_fit
    2892             : 
    2893         176 :          IF (unit_nr > 0) THEN
    2894          88 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ecore    ", ec_env%ecore
    2895          88 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ehartree ", ec_env%ehartree
    2896          88 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Exc      ", ec_env%exc
    2897          88 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ex       ", ec_env%ex
    2898          88 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Exc_aux_fit", ec_env%exc_aux_fit
    2899          88 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Edisp    ", ec_env%edispersion
    2900          88 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Etotal Energy Functional   ", ec_env%etotal
    2901             :          END IF
    2902             : 
    2903             :       CASE (ec_functional_ext)
    2904             : 
    2905           8 :          ec_env%etotal = ec_env%ex
    2906           8 :          IF (unit_nr > 0) THEN
    2907           4 :             WRITE (unit_nr, '(T3,A,T56,F25.15)') "Etotal Energy Functional   ", ec_env%etotal
    2908             :          END IF
    2909             : 
    2910             :       CASE DEFAULT
    2911             : 
    2912         530 :          CPASSERT(.FALSE.)
    2913             : 
    2914             :       END SELECT
    2915             : 
    2916         530 :       CALL timestop(handle)
    2917             : 
    2918         530 :    END SUBROUTINE ec_energy
    2919             : 
    2920             : ! **************************************************************************************************
    2921             : !> \brief builds either the full neighborlist or neighborlists of molecular
    2922             : !> \brief subsets, depending on parameter values
    2923             : !> \param qs_env ...
    2924             : !> \param ec_env ...
    2925             : !> \par History
    2926             : !>       2012.07 created [Martin Haeufel]
    2927             : !>       2016.07 Adapted for Harris functional [JGH]
    2928             : !> \author Martin Haeufel
    2929             : ! **************************************************************************************************
    2930         530 :    SUBROUTINE ec_build_neighborlist(qs_env, ec_env)
    2931             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2932             :       TYPE(energy_correction_type), POINTER              :: ec_env
    2933             : 
    2934             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_neighborlist'
    2935             : 
    2936             :       INTEGER                                            :: handle, ikind, nkind, zat
    2937             :       LOGICAL                                            :: gth_potential_present, &
    2938             :                                                             sgp_potential_present, &
    2939             :                                                             skip_load_balance_distributed
    2940             :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: default_present, orb_present, &
    2941             :                                                             ppl_present, ppnl_present
    2942             :       REAL(dp)                                           :: subcells
    2943             :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: c_radius, orb_radius, ppl_radius, &
    2944             :                                                             ppnl_radius
    2945             :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: pair_radius
    2946         530 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2947             :       TYPE(cell_type), POINTER                           :: cell
    2948             :       TYPE(dft_control_type), POINTER                    :: dft_control
    2949             :       TYPE(distribution_1d_type), POINTER                :: distribution_1d
    2950             :       TYPE(distribution_2d_type), POINTER                :: distribution_2d
    2951             :       TYPE(gth_potential_type), POINTER                  :: gth_potential
    2952             :       TYPE(gto_basis_set_type), POINTER                  :: basis_set
    2953         530 :       TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:)  :: atom2d
    2954         530 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    2955             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    2956         530 :          POINTER                                         :: sab_cn, sab_vdw
    2957         530 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2958             :       TYPE(qs_dispersion_type), POINTER                  :: dispersion_env
    2959         530 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    2960             :       TYPE(qs_kind_type), POINTER                        :: qs_kind
    2961             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    2962             :       TYPE(sgp_potential_type), POINTER                  :: sgp_potential
    2963             : 
    2964         530 :       CALL timeset(routineN, handle)
    2965             : 
    2966         530 :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set)
    2967             :       CALL get_qs_kind_set(qs_kind_set, gth_potential_present=gth_potential_present, &
    2968         530 :                            sgp_potential_present=sgp_potential_present)
    2969         530 :       nkind = SIZE(qs_kind_set)
    2970        2650 :       ALLOCATE (c_radius(nkind), default_present(nkind))
    2971        2120 :       ALLOCATE (orb_radius(nkind), ppl_radius(nkind), ppnl_radius(nkind))
    2972        2120 :       ALLOCATE (orb_present(nkind), ppl_present(nkind), ppnl_present(nkind))
    2973        2120 :       ALLOCATE (pair_radius(nkind, nkind))
    2974        2260 :       ALLOCATE (atom2d(nkind))
    2975             : 
    2976             :       CALL get_qs_env(qs_env, &
    2977             :                       atomic_kind_set=atomic_kind_set, &
    2978             :                       cell=cell, &
    2979             :                       distribution_2d=distribution_2d, &
    2980             :                       local_particles=distribution_1d, &
    2981             :                       particle_set=particle_set, &
    2982         530 :                       molecule_set=molecule_set)
    2983             : 
    2984             :       CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
    2985         530 :                         molecule_set, .FALSE., particle_set)
    2986             : 
    2987        1200 :       DO ikind = 1, nkind
    2988         670 :          CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom2d(ikind)%list)
    2989         670 :          qs_kind => qs_kind_set(ikind)
    2990         670 :          CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set, basis_type="HARRIS")
    2991         670 :          IF (ASSOCIATED(basis_set)) THEN
    2992         670 :             orb_present(ikind) = .TRUE.
    2993         670 :             CALL get_gto_basis_set(gto_basis_set=basis_set, kind_radius=orb_radius(ikind))
    2994             :          ELSE
    2995           0 :             orb_present(ikind) = .FALSE.
    2996           0 :             orb_radius(ikind) = 0.0_dp
    2997             :          END IF
    2998         670 :          CALL get_qs_kind(qs_kind, gth_potential=gth_potential, sgp_potential=sgp_potential)
    2999        1200 :          IF (gth_potential_present .OR. sgp_potential_present) THEN
    3000         670 :             IF (ASSOCIATED(gth_potential)) THEN
    3001             :                CALL get_potential(potential=gth_potential, &
    3002             :                                   ppl_present=ppl_present(ikind), &
    3003             :                                   ppl_radius=ppl_radius(ikind), &
    3004             :                                   ppnl_present=ppnl_present(ikind), &
    3005         670 :                                   ppnl_radius=ppnl_radius(ikind))
    3006           0 :             ELSE IF (ASSOCIATED(sgp_potential)) THEN
    3007             :                CALL get_potential(potential=sgp_potential, &
    3008             :                                   ppl_present=ppl_present(ikind), &
    3009             :                                   ppl_radius=ppl_radius(ikind), &
    3010             :                                   ppnl_present=ppnl_present(ikind), &
    3011           0 :                                   ppnl_radius=ppnl_radius(ikind))
    3012             :             ELSE
    3013           0 :                ppl_present(ikind) = .FALSE.
    3014           0 :                ppl_radius(ikind) = 0.0_dp
    3015           0 :                ppnl_present(ikind) = .FALSE.
    3016           0 :                ppnl_radius(ikind) = 0.0_dp
    3017             :             END IF
    3018             :          END IF
    3019             :       END DO
    3020             : 
    3021         530 :       CALL section_vals_val_get(qs_env%input, "DFT%SUBCELLS", r_val=subcells)
    3022             : 
    3023             :       ! overlap
    3024         530 :       CALL pair_radius_setup(orb_present, orb_present, orb_radius, orb_radius, pair_radius)
    3025             :       CALL build_neighbor_lists(ec_env%sab_orb, particle_set, atom2d, cell, pair_radius, &
    3026         530 :                                 subcells=subcells, nlname="sab_orb")
    3027             :       ! pseudopotential
    3028         530 :       IF (gth_potential_present .OR. sgp_potential_present) THEN
    3029         530 :          IF (ANY(ppl_present)) THEN
    3030         530 :             CALL pair_radius_setup(orb_present, ppl_present, orb_radius, ppl_radius, pair_radius)
    3031             :             CALL build_neighbor_lists(ec_env%sac_ppl, particle_set, atom2d, cell, pair_radius, &
    3032         530 :                                       subcells=subcells, operator_type="ABC", nlname="sac_ppl")
    3033             :          END IF
    3034             : 
    3035         544 :          IF (ANY(ppnl_present)) THEN
    3036         524 :             CALL pair_radius_setup(orb_present, ppnl_present, orb_radius, ppnl_radius, pair_radius)
    3037             :             CALL build_neighbor_lists(ec_env%sap_ppnl, particle_set, atom2d, cell, pair_radius, &
    3038         524 :                                       subcells=subcells, operator_type="ABBA", nlname="sap_ppnl")
    3039             :          END IF
    3040             :       END IF
    3041             : 
    3042             :       ! Build the neighbor lists for the vdW pair potential
    3043        1200 :       c_radius(:) = 0.0_dp
    3044         530 :       dispersion_env => ec_env%dispersion_env
    3045         530 :       sab_vdw => dispersion_env%sab_vdw
    3046         530 :       sab_cn => dispersion_env%sab_cn
    3047         530 :       IF (dispersion_env%type == xc_vdw_fun_pairpot) THEN
    3048           0 :          c_radius(:) = dispersion_env%rc_disp
    3049           0 :          default_present = .TRUE. !include all atoms in vdW (even without basis)
    3050           0 :          CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
    3051             :          CALL build_neighbor_lists(sab_vdw, particle_set, atom2d, cell, pair_radius, &
    3052           0 :                                    subcells=subcells, operator_type="PP", nlname="sab_vdw")
    3053           0 :          dispersion_env%sab_vdw => sab_vdw
    3054           0 :          IF (dispersion_env%pp_type == vdw_pairpot_dftd3 .OR. &
    3055             :              dispersion_env%pp_type == vdw_pairpot_dftd3bj) THEN
    3056             :             ! Build the neighbor lists for coordination numbers as needed by the DFT-D3 method
    3057           0 :             DO ikind = 1, nkind
    3058           0 :                CALL get_atomic_kind(atomic_kind_set(ikind), z=zat)
    3059           0 :                c_radius(ikind) = 4._dp*ptable(zat)%covalent_radius*bohr
    3060             :             END DO
    3061           0 :             CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
    3062             :             CALL build_neighbor_lists(sab_cn, particle_set, atom2d, cell, pair_radius, &
    3063           0 :                                       subcells=subcells, operator_type="PP", nlname="sab_cn")
    3064           0 :             dispersion_env%sab_cn => sab_cn
    3065             :          END IF
    3066             :       END IF
    3067             : 
    3068             :       ! Release work storage
    3069         530 :       CALL atom2d_cleanup(atom2d)
    3070         530 :       DEALLOCATE (atom2d)
    3071         530 :       DEALLOCATE (orb_present, default_present, ppl_present, ppnl_present)
    3072         530 :       DEALLOCATE (orb_radius, ppl_radius, ppnl_radius, c_radius)
    3073         530 :       DEALLOCATE (pair_radius)
    3074             : 
    3075             :       ! Task list
    3076         530 :       CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control)
    3077         530 :       skip_load_balance_distributed = dft_control%qs_control%skip_load_balance_distributed
    3078         530 :       IF (ASSOCIATED(ec_env%task_list)) CALL deallocate_task_list(ec_env%task_list)
    3079         530 :       CALL allocate_task_list(ec_env%task_list)
    3080             :       CALL generate_qs_task_list(ks_env, ec_env%task_list, &
    3081             :                                  reorder_rs_grid_ranks=.FALSE., soft_valid=.FALSE., &
    3082             :                                  skip_load_balance_distributed=skip_load_balance_distributed, &
    3083         530 :                                  basis_type="HARRIS", sab_orb_external=ec_env%sab_orb)
    3084             : 
    3085         530 :       CALL timestop(handle)
    3086             : 
    3087        2120 :    END SUBROUTINE ec_build_neighborlist
    3088             : 
    3089             : ! **************************************************************************************************
    3090             : !> \brief ...
    3091             : !> \param qs_env ...
    3092             : !> \param ec_env ...
    3093             : ! **************************************************************************************************
    3094         436 :    SUBROUTINE ec_properties(qs_env, ec_env)
    3095             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3096             :       TYPE(energy_correction_type), POINTER              :: ec_env
    3097             : 
    3098             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ec_properties'
    3099             : 
    3100             :       CHARACTER(LEN=8), DIMENSION(3)                     :: rlab
    3101             :       CHARACTER(LEN=default_path_length)                 :: filename, my_pos_voro
    3102             :       CHARACTER(LEN=default_string_length)               :: description
    3103             :       INTEGER :: akind, handle, i, ia, iatom, idir, ikind, iounit, ispin, maxmom, nspins, &
    3104             :          reference, should_print_bqb, should_print_voro, unit_nr, unit_nr_voro
    3105             :       LOGICAL                                            :: append_voro, magnetic, periodic, &
    3106             :                                                             voro_print_txt
    3107             :       REAL(KIND=dp)                                      :: charge, dd, focc, tmp
    3108             :       REAL(KIND=dp), DIMENSION(3)                        :: cdip, pdip, rcc, rdip, ria, tdip
    3109         436 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: ref_point
    3110             :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    3111             :       TYPE(cell_type), POINTER                           :: cell
    3112             :       TYPE(cp_logger_type), POINTER                      :: logger
    3113             :       TYPE(cp_result_type), POINTER                      :: results
    3114         436 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s, moments
    3115             :       TYPE(dft_control_type), POINTER                    :: dft_control
    3116             :       TYPE(distribution_1d_type), POINTER                :: local_particles
    3117             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3118         436 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    3119             :       TYPE(pw_env_type), POINTER                         :: pw_env
    3120         436 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
    3121             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    3122             :       TYPE(pw_r3d_rs_type)                               :: rho_elec_rspace
    3123         436 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    3124             :       TYPE(section_vals_type), POINTER                   :: ec_section, print_key, print_key_bqb, &
    3125             :                                                             print_key_voro
    3126             : 
    3127         436 :       CALL timeset(routineN, handle)
    3128             : 
    3129         436 :       rlab(1) = "X"
    3130         436 :       rlab(2) = "Y"
    3131         436 :       rlab(3) = "Z"
    3132             : 
    3133         436 :       logger => cp_get_default_logger()
    3134         436 :       IF (logger%para_env%is_source()) THEN
    3135         218 :          iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    3136             :       ELSE
    3137             :          iounit = -1
    3138             :       END IF
    3139             : 
    3140         436 :       NULLIFY (dft_control)
    3141         436 :       CALL get_qs_env(qs_env, dft_control=dft_control)
    3142         436 :       nspins = dft_control%nspins
    3143             : 
    3144         436 :       ec_section => section_vals_get_subs_vals(qs_env%input, "DFT%ENERGY_CORRECTION")
    3145             :       print_key => section_vals_get_subs_vals(section_vals=ec_section, &
    3146         436 :                                               subsection_name="PRINT%MOMENTS")
    3147             : 
    3148         436 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
    3149             : 
    3150             :          maxmom = section_get_ival(section_vals=ec_section, &
    3151          20 :                                    keyword_name="PRINT%MOMENTS%MAX_MOMENT")
    3152             :          periodic = section_get_lval(section_vals=ec_section, &
    3153          20 :                                      keyword_name="PRINT%MOMENTS%PERIODIC")
    3154             :          reference = section_get_ival(section_vals=ec_section, &
    3155          20 :                                       keyword_name="PRINT%MOMENTS%REFERENCE")
    3156             :          magnetic = section_get_lval(section_vals=ec_section, &
    3157          20 :                                      keyword_name="PRINT%MOMENTS%MAGNETIC")
    3158          20 :          NULLIFY (ref_point)
    3159          20 :          CALL section_vals_val_get(ec_section, "PRINT%MOMENTS%REF_POINT", r_vals=ref_point)
    3160             :          unit_nr = cp_print_key_unit_nr(logger=logger, basis_section=ec_section, &
    3161             :                                         print_key_path="PRINT%MOMENTS", extension=".dat", &
    3162          20 :                                         middle_name="moments", log_filename=.FALSE.)
    3163             : 
    3164          20 :          IF (iounit > 0) THEN
    3165          10 :             IF (unit_nr /= iounit .AND. unit_nr > 0) THEN
    3166           0 :                INQUIRE (UNIT=unit_nr, NAME=filename)
    3167             :                WRITE (UNIT=iounit, FMT="(/,T2,A,2(/,T3,A),/)") &
    3168           0 :                   "MOMENTS", "The electric/magnetic moments are written to file:", &
    3169           0 :                   TRIM(filename)
    3170             :             ELSE
    3171          10 :                WRITE (UNIT=iounit, FMT="(/,T2,A)") "ELECTRIC/MAGNETIC MOMENTS"
    3172             :             END IF
    3173             :          END IF
    3174             : 
    3175          20 :          IF (periodic) THEN
    3176           0 :             CPABORT("Periodic moments not implemented with EC")
    3177             :          ELSE
    3178          20 :             CPASSERT(maxmom < 2)
    3179          20 :             CPASSERT(.NOT. magnetic)
    3180          20 :             IF (maxmom == 1) THEN
    3181          20 :                CALL get_qs_env(qs_env=qs_env, cell=cell, para_env=para_env)
    3182             :                ! reference point
    3183          20 :                CALL get_reference_point(rcc, qs_env=qs_env, reference=reference, ref_point=ref_point)
    3184             :                ! nuclear contribution
    3185          20 :                cdip = 0.0_dp
    3186             :                CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, &
    3187          20 :                                qs_kind_set=qs_kind_set, local_particles=local_particles)
    3188          60 :                DO ikind = 1, SIZE(local_particles%n_el)
    3189          88 :                   DO ia = 1, local_particles%n_el(ikind)
    3190          28 :                      iatom = local_particles%list(ikind)%array(ia)
    3191             :                      ! fold atomic positions back into unit cell
    3192         224 :                      ria = pbc(particle_set(iatom)%r - rcc, cell) + rcc
    3193         112 :                      ria = ria - rcc
    3194          28 :                      atomic_kind => particle_set(iatom)%atomic_kind
    3195          28 :                      CALL get_atomic_kind(atomic_kind, kind_number=akind)
    3196          28 :                      CALL get_qs_kind(qs_kind_set(akind), core_charge=charge)
    3197         152 :                      cdip(1:3) = cdip(1:3) - charge*ria(1:3)
    3198             :                   END DO
    3199             :                END DO
    3200          20 :                CALL para_env%sum(cdip)
    3201             :                !
    3202             :                ! direct density contribution
    3203          20 :                CALL ec_efield_integrals(qs_env, ec_env, rcc)
    3204             :                !
    3205          20 :                pdip = 0.0_dp
    3206          40 :                DO ispin = 1, nspins
    3207         100 :                   DO idir = 1, 3
    3208             :                      CALL dbcsr_dot(ec_env%matrix_p(ispin, 1)%matrix, &
    3209          60 :                                     ec_env%efield%dipmat(idir)%matrix, tmp)
    3210          80 :                      pdip(idir) = pdip(idir) + tmp
    3211             :                   END DO
    3212             :                END DO
    3213             :                !
    3214             :                ! response contribution
    3215          20 :                CALL get_qs_env(qs_env=qs_env, matrix_s=matrix_s)
    3216          20 :                NULLIFY (moments)
    3217          20 :                CALL dbcsr_allocate_matrix_set(moments, 4)
    3218         100 :                DO i = 1, 4
    3219          80 :                   ALLOCATE (moments(i)%matrix)
    3220          80 :                   CALL dbcsr_copy(moments(i)%matrix, matrix_s(1)%matrix, "Moments")
    3221         100 :                   CALL dbcsr_set(moments(i)%matrix, 0.0_dp)
    3222             :                END DO
    3223          20 :                CALL build_local_moment_matrix(qs_env, moments, 1, ref_point=rcc)
    3224             :                !
    3225             :                focc = 2.0_dp
    3226          20 :                IF (nspins == 2) focc = 1.0_dp
    3227          20 :                rdip = 0.0_dp
    3228          40 :                DO ispin = 1, nspins
    3229         100 :                   DO idir = 1, 3
    3230          60 :                      CALL dbcsr_dot(ec_env%matrix_z(ispin)%matrix, moments(idir)%matrix, tmp)
    3231          80 :                      rdip(idir) = rdip(idir) + tmp
    3232             :                   END DO
    3233             :                END DO
    3234          20 :                CALL dbcsr_deallocate_matrix_set(moments)
    3235             :                !
    3236          80 :                tdip = -(rdip + pdip + cdip)
    3237          20 :                IF (unit_nr > 0) THEN
    3238          10 :                   WRITE (unit_nr, "(T3,A)") "Dipoles are based on the traditional operator."
    3239          40 :                   dd = SQRT(SUM(tdip(1:3)**2))*debye
    3240          10 :                   WRITE (unit_nr, "(T3,A)") "Dipole moment [Debye]"
    3241             :                   WRITE (unit_nr, "(T5,3(A,A,F14.8,1X),T60,A,T67,F14.8)") &
    3242          40 :                      (TRIM(rlab(i)), "=", tdip(i)*debye, i=1, 3), "Total=", dd
    3243             :                END IF
    3244             :             END IF
    3245             :          END IF
    3246             : 
    3247             :          CALL cp_print_key_finished_output(unit_nr=unit_nr, logger=logger, &
    3248          20 :                                            basis_section=ec_section, print_key_path="PRINT%MOMENTS")
    3249          20 :          CALL get_qs_env(qs_env=qs_env, results=results)
    3250          20 :          description = "[DIPOLE]"
    3251          20 :          CALL cp_results_erase(results=results, description=description)
    3252          20 :          CALL put_results(results=results, description=description, values=tdip(1:3))
    3253             :       END IF
    3254             : 
    3255             :       ! Do a Voronoi Integration or write a compressed BQB File
    3256         436 :       print_key_voro => section_vals_get_subs_vals(ec_section, "PRINT%VORONOI")
    3257         436 :       print_key_bqb => section_vals_get_subs_vals(ec_section, "PRINT%E_DENSITY_BQB")
    3258         436 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key_voro), cp_p_file)) THEN
    3259           4 :          should_print_voro = 1
    3260             :       ELSE
    3261         432 :          should_print_voro = 0
    3262             :       END IF
    3263         436 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key_bqb), cp_p_file)) THEN
    3264           0 :          should_print_bqb = 1
    3265             :       ELSE
    3266         436 :          should_print_bqb = 0
    3267             :       END IF
    3268         436 :       IF ((should_print_voro /= 0) .OR. (should_print_bqb /= 0)) THEN
    3269             : 
    3270             :          CALL get_qs_env(qs_env=qs_env, &
    3271           4 :                          pw_env=pw_env)
    3272             :          CALL pw_env_get(pw_env=pw_env, &
    3273             :                          auxbas_pw_pool=auxbas_pw_pool, &
    3274           4 :                          pw_pools=pw_pools)
    3275           4 :          CALL auxbas_pw_pool%create_pw(pw=rho_elec_rspace)
    3276             : 
    3277           4 :          IF (dft_control%nspins > 1) THEN
    3278             : 
    3279             :             ! add Pout and Pz
    3280           0 :             CALL pw_copy(ec_env%rhoout_r(1), rho_elec_rspace)
    3281           0 :             CALL pw_axpy(ec_env%rhoout_r(2), rho_elec_rspace)
    3282             : 
    3283           0 :             CALL pw_axpy(ec_env%rhoz_r(1), rho_elec_rspace)
    3284           0 :             CALL pw_axpy(ec_env%rhoz_r(2), rho_elec_rspace)
    3285             :          ELSE
    3286             : 
    3287             :             ! add Pout and Pz
    3288           4 :             CALL pw_copy(ec_env%rhoout_r(1), rho_elec_rspace)
    3289           4 :             CALL pw_axpy(ec_env%rhoz_r(1), rho_elec_rspace)
    3290             :          END IF ! nspins
    3291             : 
    3292           4 :          IF (should_print_voro /= 0) THEN
    3293           4 :             CALL section_vals_val_get(print_key_voro, "OUTPUT_TEXT", l_val=voro_print_txt)
    3294           4 :             IF (voro_print_txt) THEN
    3295           4 :                append_voro = section_get_lval(ec_section, "PRINT%VORONOI%APPEND")
    3296           4 :                my_pos_voro = "REWIND"
    3297           4 :                IF (append_voro) THEN
    3298           0 :                   my_pos_voro = "APPEND"
    3299             :                END IF
    3300             :                unit_nr_voro = cp_print_key_unit_nr(logger, ec_section, "PRINT%VORONOI", extension=".voronoi", &
    3301           4 :                                                    file_position=my_pos_voro, log_filename=.FALSE.)
    3302             :             ELSE
    3303           0 :                unit_nr_voro = 0
    3304             :             END IF
    3305             :          ELSE
    3306           0 :             unit_nr_voro = 0
    3307             :          END IF
    3308             : 
    3309             :          CALL entry_voronoi_or_bqb(should_print_voro, should_print_bqb, print_key_voro, print_key_bqb, &
    3310           4 :                                    unit_nr_voro, qs_env, rho_elec_rspace)
    3311             : 
    3312           4 :          CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
    3313             : 
    3314           4 :          IF (unit_nr_voro > 0) THEN
    3315           2 :             CALL cp_print_key_finished_output(unit_nr_voro, logger, ec_section, "PRINT%VORONOI")
    3316             :          END IF
    3317             : 
    3318             :       END IF
    3319             : 
    3320         436 :       CALL timestop(handle)
    3321             : 
    3322         436 :    END SUBROUTINE ec_properties
    3323             : 
    3324             : ! **************************************************************************************************
    3325             : !> \brief Solve the Harris functional by linear scaling density purification scheme,
    3326             : !>        instead of the diagonalization performed in ec_diag_solver
    3327             : !>
    3328             : !> \param qs_env ...
    3329             : !> \param matrix_ks Harris Kohn-Sham matrix
    3330             : !> \param matrix_s Overlap matrix in Harris functional basis
    3331             : !> \par History
    3332             : !>       09.2020 created
    3333             : !> \author F.Belleflamme
    3334             : ! **************************************************************************************************
    3335          30 :    SUBROUTINE ec_ls_init(qs_env, matrix_ks, matrix_s)
    3336             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3337             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks, matrix_s
    3338             : 
    3339             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ec_ls_init'
    3340             : 
    3341             :       INTEGER                                            :: handle, ispin, nspins
    3342             :       TYPE(dft_control_type), POINTER                    :: dft_control
    3343             :       TYPE(energy_correction_type), POINTER              :: ec_env
    3344             :       TYPE(ls_scf_env_type), POINTER                     :: ls_env
    3345             : 
    3346          30 :       CALL timeset(routineN, handle)
    3347             : 
    3348             :       CALL get_qs_env(qs_env=qs_env, &
    3349             :                       dft_control=dft_control, &
    3350          30 :                       ec_env=ec_env)
    3351          30 :       nspins = dft_control%nspins
    3352          30 :       ls_env => ec_env%ls_env
    3353             : 
    3354             :       ! create the matrix template for use in the ls procedures
    3355             :       CALL matrix_ls_create(matrix_ls=ls_env%matrix_s, matrix_qs=matrix_s(1, 1)%matrix, &
    3356          30 :                             ls_mstruct=ls_env%ls_mstruct)
    3357             : 
    3358          30 :       IF (ALLOCATED(ls_env%matrix_p)) THEN
    3359          16 :          DO ispin = 1, SIZE(ls_env%matrix_p)
    3360          16 :             CALL dbcsr_release(ls_env%matrix_p(ispin))
    3361             :          END DO
    3362             :       ELSE
    3363          88 :          ALLOCATE (ls_env%matrix_p(nspins))
    3364             :       END IF
    3365             : 
    3366          60 :       DO ispin = 1, nspins
    3367             :          CALL dbcsr_create(ls_env%matrix_p(ispin), template=ls_env%matrix_s, &
    3368          60 :                            matrix_type=dbcsr_type_no_symmetry)
    3369             :       END DO
    3370             : 
    3371         120 :       ALLOCATE (ls_env%matrix_ks(nspins))
    3372          60 :       DO ispin = 1, nspins
    3373             :          CALL dbcsr_create(ls_env%matrix_ks(ispin), template=ls_env%matrix_s, &
    3374          60 :                            matrix_type=dbcsr_type_no_symmetry)
    3375             :       END DO
    3376             : 
    3377             :       ! Set up S matrix and needed functions of S
    3378          30 :       CALL ls_scf_init_matrix_s(matrix_s(1, 1)%matrix, ls_env)
    3379             : 
    3380             :       ! Bring KS matrix from QS to LS form
    3381             :       ! EC KS-matrix already calculated
    3382          60 :       DO ispin = 1, nspins
    3383             :          CALL matrix_qs_to_ls(matrix_ls=ls_env%matrix_ks(ispin), &
    3384             :                               matrix_qs=matrix_ks(ispin, 1)%matrix, &
    3385             :                               ls_mstruct=ls_env%ls_mstruct, &
    3386          60 :                               covariant=.TRUE.)
    3387             :       END DO
    3388             : 
    3389          30 :       CALL timestop(handle)
    3390             : 
    3391          30 :    END SUBROUTINE ec_ls_init
    3392             : 
    3393             : ! **************************************************************************************************
    3394             : !> \brief Solve the Harris functional by linear scaling density purification scheme,
    3395             : !>        instead of the diagonalization performed in ec_diag_solver
    3396             : !>
    3397             : !> \param qs_env ...
    3398             : !> \param matrix_p Harris dentiy matrix, calculated here
    3399             : !> \param matrix_w Harris energy weighted density matrix, calculated here
    3400             : !> \param ec_ls_method which purification scheme should be used
    3401             : !> \par History
    3402             : !>      12.2019 created [JGH]
    3403             : !>      08.2020 refactoring [fbelle]
    3404             : !> \author Fabian Belleflamme
    3405             : ! **************************************************************************************************
    3406             : 
    3407          30 :    SUBROUTINE ec_ls_solver(qs_env, matrix_p, matrix_w, ec_ls_method)
    3408             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3409             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_w
    3410             :       INTEGER, INTENT(IN)                                :: ec_ls_method
    3411             : 
    3412             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ec_ls_solver'
    3413             : 
    3414             :       INTEGER                                            :: handle, ispin, nelectron_spin_real, &
    3415             :                                                             nspins
    3416             :       INTEGER, DIMENSION(2)                              :: nmo
    3417          30 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: wmat
    3418          30 :       TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:)        :: matrix_ks_deviation
    3419             :       TYPE(dft_control_type), POINTER                    :: dft_control
    3420             :       TYPE(energy_correction_type), POINTER              :: ec_env
    3421             :       TYPE(ls_scf_env_type), POINTER                     :: ls_env
    3422             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3423             : 
    3424          30 :       CALL timeset(routineN, handle)
    3425             : 
    3426          30 :       NULLIFY (para_env)
    3427             :       CALL get_qs_env(qs_env, &
    3428             :                       dft_control=dft_control, &
    3429          30 :                       para_env=para_env)
    3430          30 :       nspins = dft_control%nspins
    3431          30 :       ec_env => qs_env%ec_env
    3432          30 :       ls_env => ec_env%ls_env
    3433             : 
    3434          30 :       nmo = 0
    3435          30 :       CALL get_qs_env(qs_env=qs_env, nelectron_spin=nmo)
    3436          30 :       IF (nspins == 1) nmo(1) = nmo(1)/2
    3437          90 :       ls_env%homo_spin(:) = 0.0_dp
    3438          90 :       ls_env%lumo_spin(:) = 0.0_dp
    3439             : 
    3440         120 :       ALLOCATE (matrix_ks_deviation(nspins))
    3441          60 :       DO ispin = 1, nspins
    3442          30 :          CALL dbcsr_create(matrix_ks_deviation(ispin), template=ls_env%matrix_ks(ispin))
    3443          60 :          CALL dbcsr_set(matrix_ks_deviation(ispin), 0.0_dp)
    3444             :       END DO
    3445             : 
    3446             :       ! F = S^-1/2 * F * S^-1/2
    3447          30 :       IF (ls_env%has_s_preconditioner) THEN
    3448          60 :          DO ispin = 1, nspins
    3449             :             CALL apply_matrix_preconditioner(ls_env%matrix_ks(ispin), "forward", &
    3450          30 :                                              ls_env%matrix_bs_sqrt, ls_env%matrix_bs_sqrt_inv)
    3451             : 
    3452          60 :             CALL dbcsr_filter(ls_env%matrix_ks(ispin), ls_env%eps_filter)
    3453             :          END DO
    3454             :       END IF
    3455             : 
    3456          60 :       DO ispin = 1, nspins
    3457          30 :          nelectron_spin_real = ls_env%nelectron_spin(ispin)
    3458          30 :          IF (ls_env%nspins == 1) nelectron_spin_real = nelectron_spin_real/2
    3459             : 
    3460          30 :          SELECT CASE (ec_ls_method)
    3461             :          CASE (ec_matrix_sign)
    3462             :             CALL density_matrix_sign(ls_env%matrix_p(ispin), &
    3463             :                                      ls_env%mu_spin(ispin), &
    3464             :                                      ls_env%fixed_mu, &
    3465             :                                      ls_env%sign_method, &
    3466             :                                      ls_env%sign_order, &
    3467             :                                      ls_env%matrix_ks(ispin), &
    3468             :                                      ls_env%matrix_s, &
    3469             :                                      ls_env%matrix_s_inv, &
    3470             :                                      nelectron_spin_real, &
    3471           2 :                                      ec_env%eps_default)
    3472             : 
    3473             :          CASE (ec_matrix_trs4)
    3474             :             CALL density_matrix_trs4( &
    3475             :                ls_env%matrix_p(ispin), &
    3476             :                ls_env%matrix_ks(ispin), &
    3477             :                ls_env%matrix_s_sqrt_inv, &
    3478             :                nelectron_spin_real, &
    3479             :                ec_env%eps_default, &
    3480             :                ls_env%homo_spin(ispin), &
    3481             :                ls_env%lumo_spin(ispin), &
    3482             :                ls_env%mu_spin(ispin), &
    3483             :                matrix_ks_deviation=matrix_ks_deviation(ispin), &
    3484             :                dynamic_threshold=ls_env%dynamic_threshold, &
    3485             :                eps_lanczos=ls_env%eps_lanczos, &
    3486          26 :                max_iter_lanczos=ls_env%max_iter_lanczos)
    3487             : 
    3488             :          CASE (ec_matrix_tc2)
    3489             :             CALL density_matrix_tc2( &
    3490             :                ls_env%matrix_p(ispin), &
    3491             :                ls_env%matrix_ks(ispin), &
    3492             :                ls_env%matrix_s_sqrt_inv, &
    3493             :                nelectron_spin_real, &
    3494             :                ec_env%eps_default, &
    3495             :                ls_env%homo_spin(ispin), &
    3496             :                ls_env%lumo_spin(ispin), &
    3497             :                non_monotonic=ls_env%non_monotonic, &
    3498             :                eps_lanczos=ls_env%eps_lanczos, &
    3499          30 :                max_iter_lanczos=ls_env%max_iter_lanczos)
    3500             : 
    3501             :          END SELECT
    3502             : 
    3503             :       END DO
    3504             : 
    3505             :       ! de-orthonormalize
    3506          30 :       IF (ls_env%has_s_preconditioner) THEN
    3507          60 :          DO ispin = 1, nspins
    3508             :             ! P = S^-1/2 * P_tilde * S^-1/2 (forward)
    3509             :             CALL apply_matrix_preconditioner(ls_env%matrix_p(ispin), "forward", &
    3510          30 :                                              ls_env%matrix_bs_sqrt, ls_env%matrix_bs_sqrt_inv)
    3511             : 
    3512          60 :             CALL dbcsr_filter(ls_env%matrix_p(ispin), ls_env%eps_filter)
    3513             :          END DO
    3514             :       END IF
    3515             : 
    3516             :       ! Closed-shell
    3517          30 :       IF (nspins == 1) CALL dbcsr_scale(ls_env%matrix_p(1), 2.0_dp)
    3518             : 
    3519          30 :       IF (ls_env%report_all_sparsities) CALL post_scf_sparsities(ls_env)
    3520             : 
    3521             :       ! ls_scf_dm_to_ks
    3522             :       ! Density matrix from LS to EC
    3523          60 :       DO ispin = 1, nspins
    3524             :          CALL matrix_ls_to_qs(matrix_qs=matrix_p(ispin, 1)%matrix, &
    3525             :                               matrix_ls=ls_env%matrix_p(ispin), &
    3526             :                               ls_mstruct=ls_env%ls_mstruct, &
    3527          60 :                               covariant=.FALSE.)
    3528             :       END DO
    3529             : 
    3530          30 :       wmat => matrix_w(:, 1)
    3531          30 :       CALL calculate_w_matrix_ls(wmat, ec_env%ls_env)
    3532             : 
    3533             :       ! clean up
    3534          30 :       CALL dbcsr_release(ls_env%matrix_s)
    3535          30 :       IF (ls_env%has_s_preconditioner) THEN
    3536          30 :          CALL dbcsr_release(ls_env%matrix_bs_sqrt)
    3537          30 :          CALL dbcsr_release(ls_env%matrix_bs_sqrt_inv)
    3538             :       END IF
    3539          30 :       IF (ls_env%needs_s_inv) THEN
    3540           2 :          CALL dbcsr_release(ls_env%matrix_s_inv)
    3541             :       END IF
    3542          30 :       IF (ls_env%use_s_sqrt) THEN
    3543          30 :          CALL dbcsr_release(ls_env%matrix_s_sqrt)
    3544          30 :          CALL dbcsr_release(ls_env%matrix_s_sqrt_inv)
    3545             :       END IF
    3546             : 
    3547          60 :       DO ispin = 1, SIZE(ls_env%matrix_ks)
    3548          60 :          CALL dbcsr_release(ls_env%matrix_ks(ispin))
    3549             :       END DO
    3550          30 :       DEALLOCATE (ls_env%matrix_ks)
    3551             : 
    3552          60 :       DO ispin = 1, nspins
    3553          60 :          CALL dbcsr_release(matrix_ks_deviation(ispin))
    3554             :       END DO
    3555          30 :       DEALLOCATE (matrix_ks_deviation)
    3556             : 
    3557          30 :       CALL timestop(handle)
    3558             : 
    3559          30 :    END SUBROUTINE ec_ls_solver
    3560             : 
    3561             : ! **************************************************************************************************
    3562             : !> \brief Use OT-diagonalziation to obtain density matrix from Harris Kohn-Sham matrix
    3563             : !>        Initial guess of density matrix is either the atomic block initial guess from SCF
    3564             : !>        or the ground-state density matrix. The latter only works if the same basis is used
    3565             : !>
    3566             : !> \param qs_env ...
    3567             : !> \param ec_env ...
    3568             : !> \param matrix_ks Harris Kohn-Sham matrix
    3569             : !> \param matrix_s Overlap matrix in Harris functional basis
    3570             : !> \param matrix_p Harris dentiy matrix, calculated here
    3571             : !> \param matrix_w Harris energy weighted density matrix, calculated here
    3572             : !>
    3573             : !> \par History
    3574             : !>       09.2020 created
    3575             : !> \author F.Belleflamme
    3576             : ! **************************************************************************************************
    3577           4 :    SUBROUTINE ec_ot_diag_solver(qs_env, ec_env, matrix_ks, matrix_s, matrix_p, matrix_w)
    3578             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3579             :       TYPE(energy_correction_type), POINTER              :: ec_env
    3580             :       TYPE(dbcsr_p_type), DIMENSION(:, :), INTENT(IN), &
    3581             :          POINTER                                         :: matrix_ks, matrix_s
    3582             :       TYPE(dbcsr_p_type), DIMENSION(:, :), &
    3583             :          INTENT(INOUT), POINTER                          :: matrix_p, matrix_w
    3584             : 
    3585             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ec_ot_diag_solver'
    3586             : 
    3587             :       INTEGER                                            :: handle, homo, ikind, iounit, ispin, &
    3588             :                                                             max_iter, nao, nkind, nmo, nspins
    3589             :       INTEGER, DIMENSION(2)                              :: nelectron_spin
    3590           4 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: eigenvalues
    3591           4 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3592             :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
    3593             :       TYPE(cp_fm_type)                                   :: sv
    3594             :       TYPE(cp_fm_type), POINTER                          :: mo_coeff
    3595             :       TYPE(cp_logger_type), POINTER                      :: logger
    3596           4 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: p_rmpv
    3597           4 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: rho_ao
    3598             :       TYPE(dft_control_type), POINTER                    :: dft_control
    3599             :       TYPE(gto_basis_set_type), POINTER                  :: basis_set, harris_basis
    3600           4 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
    3601             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3602           4 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    3603             :       TYPE(preconditioner_type), POINTER                 :: local_preconditioner
    3604           4 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    3605             :       TYPE(qs_kind_type), POINTER                        :: qs_kind
    3606             :       TYPE(qs_rho_type), POINTER                         :: rho
    3607             : 
    3608           4 :       CALL timeset(routineN, handle)
    3609             : 
    3610           4 :       logger => cp_get_default_logger()
    3611           4 :       iounit = cp_logger_get_default_unit_nr(logger)
    3612             : 
    3613           4 :       CPASSERT(ASSOCIATED(qs_env))
    3614           4 :       CPASSERT(ASSOCIATED(ec_env))
    3615           4 :       CPASSERT(ASSOCIATED(matrix_ks))
    3616           4 :       CPASSERT(ASSOCIATED(matrix_s))
    3617           4 :       CPASSERT(ASSOCIATED(matrix_p))
    3618           4 :       CPASSERT(ASSOCIATED(matrix_w))
    3619             : 
    3620             :       CALL get_qs_env(qs_env=qs_env, &
    3621             :                       atomic_kind_set=atomic_kind_set, &
    3622             :                       blacs_env=blacs_env, &
    3623             :                       dft_control=dft_control, &
    3624             :                       nelectron_spin=nelectron_spin, &
    3625             :                       para_env=para_env, &
    3626             :                       particle_set=particle_set, &
    3627           4 :                       qs_kind_set=qs_kind_set)
    3628           4 :       nspins = dft_control%nspins
    3629             : 
    3630             :       ! Maximum number of OT iterations for diagonalization
    3631           4 :       max_iter = 200
    3632             : 
    3633             :       ! If linear scaling, need to allocate and init MO set
    3634             :       ! set it to qs_env%mos
    3635           4 :       IF (dft_control%qs_control%do_ls_scf) THEN
    3636           0 :          CALL ec_mos_init(qs_env, matrix_s(1, 1)%matrix)
    3637             :       END IF
    3638             : 
    3639           4 :       CALL get_qs_env(qs_env, mos=mos)
    3640             : 
    3641             :       ! Inital guess to use
    3642           4 :       NULLIFY (p_rmpv)
    3643             : 
    3644             :       ! Using ether ground-state DM or ATOMIC GUESS requires
    3645             :       ! Harris functional to use the same basis set
    3646           4 :       CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, nkind=nkind)
    3647           4 :       CALL uppercase(ec_env%basis)
    3648             :       ! Harris basis only differs from ground-state basis if explicitly added
    3649             :       ! thus only two cases that need to be tested
    3650             :       ! 1) explicit Harris basis present?
    3651           4 :       IF (ec_env%basis == "HARRIS") THEN
    3652          12 :          DO ikind = 1, nkind
    3653           8 :             qs_kind => qs_kind_set(ikind)
    3654             :             ! Basis sets of ground-state
    3655           8 :             CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set, basis_type="ORB")
    3656             :             ! Basis sets of energy correction
    3657           8 :             CALL get_qs_kind(qs_kind=qs_kind, basis_set=harris_basis, basis_type="HARRIS")
    3658             : 
    3659          12 :             IF (basis_set%name .NE. harris_basis%name) THEN
    3660           0 :                CPABORT("OT-Diag initial guess: Harris and ground state need to use the same basis")
    3661             :             END IF
    3662             :          END DO
    3663             :       END IF
    3664             :       ! 2) Harris uses MAOs
    3665           4 :       IF (ec_env%mao) THEN
    3666           0 :          CPABORT("OT-Diag initial guess: not implemented for MAOs")
    3667             :       END IF
    3668             : 
    3669             :       ! Initital guess obtained for OT Diagonalization
    3670           6 :       SELECT CASE (ec_env%ec_initial_guess)
    3671             :       CASE (ec_ot_atomic)
    3672             : 
    3673           2 :          p_rmpv => matrix_p(:, 1)
    3674             : 
    3675             :          CALL calculate_atomic_block_dm(p_rmpv, matrix_s(1, 1)%matrix, atomic_kind_set, qs_kind_set, &
    3676           2 :                                         nspins, nelectron_spin, iounit, para_env)
    3677             : 
    3678             :       CASE (ec_ot_gs)
    3679             : 
    3680           2 :          CALL get_qs_env(qs_env, rho=rho)
    3681           2 :          CALL qs_rho_get(rho, rho_ao_kp=rho_ao)
    3682           2 :          p_rmpv => rho_ao(:, 1)
    3683             : 
    3684             :       CASE DEFAULT
    3685           4 :          CPABORT("Unknown inital guess for OT-Diagonalization (Harris functional)")
    3686             :       END SELECT
    3687             : 
    3688           8 :       DO ispin = 1, nspins
    3689             :          CALL get_mo_set(mo_set=mos(ispin), &
    3690             :                          mo_coeff=mo_coeff, &
    3691             :                          nmo=nmo, &
    3692             :                          nao=nao, &
    3693           4 :                          homo=homo)
    3694             : 
    3695             :          ! Calculate first MOs
    3696           4 :          CALL cp_fm_set_all(mo_coeff, 0.0_dp)
    3697           4 :          CALL cp_fm_init_random(mo_coeff, nmo)
    3698             : 
    3699           4 :          CALL cp_fm_create(sv, mo_coeff%matrix_struct, "SV")
    3700             :          ! multiply times PS
    3701             :          ! PS*C(:,1:nomo)+C(:,nomo+1:nmo) (nomo=NINT(nelectron/maxocc))
    3702           4 :          CALL cp_dbcsr_sm_fm_multiply(matrix_s(1, 1)%matrix, mo_coeff, sv, nmo)
    3703           4 :          CALL cp_dbcsr_sm_fm_multiply(p_rmpv(ispin)%matrix, sv, mo_coeff, homo)
    3704           4 :          CALL cp_fm_release(sv)
    3705             :          ! and ortho the result
    3706             :          ! If DFBT or SE, then needs has_unit_metrix option
    3707          16 :          CALL make_basis_sm(mo_coeff, nmo, matrix_s(1, 1)%matrix)
    3708             :       END DO
    3709             : 
    3710             :       ! Preconditioner
    3711             :       NULLIFY (local_preconditioner)
    3712           4 :       ALLOCATE (local_preconditioner)
    3713             :       CALL init_preconditioner(local_preconditioner, para_env=para_env, &
    3714           4 :                                blacs_env=blacs_env)
    3715           8 :       DO ispin = 1, nspins
    3716             :          CALL make_preconditioner(local_preconditioner, &
    3717             :                                   precon_type=ot_precond_full_single_inverse, &
    3718             :                                   solver_type=ot_precond_solver_default, &
    3719             :                                   matrix_h=matrix_ks(ispin, 1)%matrix, &
    3720             :                                   matrix_s=matrix_s(ispin, 1)%matrix, &
    3721             :                                   convert_precond_to_dbcsr=.TRUE., &
    3722           4 :                                   mo_set=mos(ispin), energy_gap=0.2_dp)
    3723             : 
    3724             :          CALL get_mo_set(mos(ispin), &
    3725             :                          mo_coeff=mo_coeff, &
    3726             :                          eigenvalues=eigenvalues, &
    3727             :                          nmo=nmo, &
    3728           4 :                          homo=homo)
    3729             :          CALL ot_eigensolver(matrix_h=matrix_ks(ispin, 1)%matrix, &
    3730             :                              matrix_s=matrix_s(1, 1)%matrix, &
    3731             :                              matrix_c_fm=mo_coeff, &
    3732             :                              preconditioner=local_preconditioner, &
    3733             :                              eps_gradient=ec_env%eps_default, &
    3734             :                              iter_max=max_iter, &
    3735           4 :                              silent=.FALSE.)
    3736             :          CALL calculate_subspace_eigenvalues(mo_coeff, matrix_ks(ispin, 1)%matrix, &
    3737           4 :                                              evals_arg=eigenvalues, do_rotation=.TRUE.)
    3738             : 
    3739             :          ! Deallocate preconditioner
    3740           4 :          CALL destroy_preconditioner(local_preconditioner)
    3741           4 :          DEALLOCATE (local_preconditioner)
    3742             : 
    3743             :          !fm->dbcsr
    3744             :          CALL copy_fm_to_dbcsr(mos(ispin)%mo_coeff, &
    3745          12 :                                mos(ispin)%mo_coeff_b)
    3746             :       END DO
    3747             : 
    3748             :       ! Calculate density matrix from MOs
    3749           8 :       DO ispin = 1, nspins
    3750           4 :          CALL calculate_density_matrix(mos(ispin), matrix_p(ispin, 1)%matrix)
    3751             : 
    3752           8 :          CALL calculate_w_matrix(mos(ispin), matrix_w(ispin, 1)%matrix)
    3753             :       END DO
    3754             : 
    3755             :       ! Get rid of MO environment again
    3756           4 :       IF (dft_control%qs_control%do_ls_scf) THEN
    3757           0 :          DO ispin = 1, nspins
    3758           0 :             CALL deallocate_mo_set(mos(ispin))
    3759             :          END DO
    3760           0 :          IF (ASSOCIATED(qs_env%mos)) THEN
    3761           0 :             DO ispin = 1, SIZE(qs_env%mos)
    3762           0 :                CALL deallocate_mo_set(qs_env%mos(ispin))
    3763             :             END DO
    3764           0 :             DEALLOCATE (qs_env%mos)
    3765             :          END IF
    3766             :       END IF
    3767             : 
    3768           4 :       CALL timestop(handle)
    3769             : 
    3770           4 :    END SUBROUTINE ec_ot_diag_solver
    3771             : 
    3772             : END MODULE energy_corrections
    3773             : 

Generated by: LCOV version 1.15