LCOV - code coverage report
Current view: top level - src - energy_corrections.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:70636b1) Lines: 82.4 % 1943 1602
Test Date: 2026-02-11 07:00:35 Functions: 92.6 % 27 25

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

Generated by: LCOV version 2.0-1