LCOV - code coverage report
Current view: top level - src - energy_corrections.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 82.8 % 1683 1394
Test Date: 2025-12-04 06:27:48 Functions: 95.7 % 23 22

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

Generated by: LCOV version 2.0-1