LCOV - code coverage report
Current view: top level - src - qs_ks_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:561f475) Lines: 93.1 % 607 565
Test Date: 2026-06-21 06:48:54 Functions: 100.0 % 7 7

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief routines that build the Kohn-Sham matrix (i.e calculate the coulomb
      10              : !>        and xc parts
      11              : !> \author Fawzi Mohamed
      12              : !> \par History
      13              : !>      - 05.2002 moved from qs_scf (see there the history) [fawzi]
      14              : !>      - JGH [30.08.02] multi-grid arrays independent from density and potential
      15              : !>      - 10.2002 introduced pools, uses updated rho as input,
      16              : !>                removed most temporary variables, renamed may vars,
      17              : !>                began conversion to LSD [fawzi]
      18              : !>      - 10.2004 moved calculate_w_matrix here [Joost VandeVondele]
      19              : !>                introduced energy derivative wrt MOs [Joost VandeVondele]
      20              : !>      - SCCS implementation (16.10.2013,MK)
      21              : ! **************************************************************************************************
      22              : MODULE qs_ks_methods
      23              :    USE accint_weights_forces,           ONLY: accint_weight_force
      24              :    USE admm_dm_methods,                 ONLY: admm_dm_calc_rho_aux,&
      25              :                                               admm_dm_merge_ks_matrix
      26              :    USE admm_methods,                    ONLY: admm_mo_calc_rho_aux,&
      27              :                                               admm_mo_calc_rho_aux_kp,&
      28              :                                               admm_mo_merge_ks_matrix,&
      29              :                                               admm_update_ks_atom,&
      30              :                                               calc_admm_mo_derivatives,&
      31              :                                               calc_admm_ovlp_forces,&
      32              :                                               calc_admm_ovlp_forces_kp
      33              :    USE admm_types,                      ONLY: admm_type,&
      34              :                                               get_admm_env
      35              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      36              :                                               get_atomic_kind_set
      37              :    USE cell_types,                      ONLY: cell_type
      38              :    USE cp_control_types,                ONLY: dft_control_type
      39              :    USE cp_dbcsr_api,                    ONLY: &
      40              :         dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_filter, dbcsr_get_info, dbcsr_multiply, &
      41              :         dbcsr_p_type, dbcsr_release, dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, &
      42              :         dbcsr_type_symmetric
      43              :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      44              :    USE cp_dbcsr_operations,             ONLY: dbcsr_allocate_matrix_set,&
      45              :                                               dbcsr_copy_columns_hack
      46              :    USE cp_ddapc,                        ONLY: qs_ks_ddapc
      47              :    USE cp_fm_types,                     ONLY: cp_fm_type
      48              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      49              :                                               cp_logger_get_default_io_unit,&
      50              :                                               cp_logger_type
      51              :    USE cp_output_handling,              ONLY: cp_p_file,&
      52              :                                               cp_print_key_should_output
      53              :    USE dft_plus_u,                      ONLY: plus_u
      54              :    USE gce_methods,                     ONLY: planar_averaged_v_hartree_3d,&
      55              :                                               planar_counter_charge
      56              :    USE hartree_local_methods,           ONLY: Vh_1c_gg_integrals
      57              :    USE hartree_local_types,             ONLY: ecoul_1center_type
      58              :    USE hfx_ace_methods,                 ONLY: hfx_ace_ks_matrix
      59              :    USE hfx_admm_utils,                  ONLY: hfx_admm_init,&
      60              :                                               hfx_ks_matrix,&
      61              :                                               hfx_ks_matrix_kp
      62              :    USE input_constants,                 ONLY: do_ppl_grid,&
      63              :                                               outer_scf_becke_constraint,&
      64              :                                               outer_scf_hirshfeld_constraint,&
      65              :                                               smeagol_runtype_emtransport
      66              :    USE input_section_types,             ONLY: section_vals_get,&
      67              :                                               section_vals_get_subs_vals,&
      68              :                                               section_vals_type,&
      69              :                                               section_vals_val_get
      70              :    USE kg_correction,                   ONLY: kg_ekin_subset
      71              :    USE kinds,                           ONLY: default_string_length,&
      72              :                                               dp
      73              :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      74              :                                               kpoint_type
      75              :    USE lri_environment_methods,         ONLY: v_int_ppl_energy
      76              :    USE lri_environment_types,           ONLY: lri_density_type,&
      77              :                                               lri_environment_type,&
      78              :                                               lri_kind_type
      79              :    USE mathlib,                         ONLY: abnormal_value
      80              :    USE message_passing,                 ONLY: mp_para_env_type
      81              :    USE particle_types,                  ONLY: particle_type
      82              :    USE pw_env_types,                    ONLY: pw_env_get,&
      83              :                                               pw_env_type
      84              :    USE pw_methods,                      ONLY: pw_axpy,&
      85              :                                               pw_copy,&
      86              :                                               pw_integral_ab,&
      87              :                                               pw_integrate_function,&
      88              :                                               pw_scale,&
      89              :                                               pw_transfer,&
      90              :                                               pw_zero
      91              :    USE pw_poisson_methods,              ONLY: pw_poisson_solve
      92              :    USE pw_poisson_types,                ONLY: pw_poisson_implicit,&
      93              :                                               pw_poisson_type
      94              :    USE pw_pool_types,                   ONLY: pw_pool_type
      95              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      96              :                                               pw_r3d_rs_type
      97              :    USE qmmm_image_charge,               ONLY: add_image_pot_to_hartree_pot,&
      98              :                                               calculate_image_pot,&
      99              :                                               integrate_potential_devga_rspace
     100              :    USE qs_cdft_types,                   ONLY: cdft_control_type
     101              :    USE qs_charges_types,                ONLY: qs_charges_type
     102              :    USE qs_core_energies,                ONLY: calculate_ptrace
     103              :    USE qs_dftb_matrices,                ONLY: build_dftb_ks_matrix
     104              :    USE qs_efield_berry,                 ONLY: qs_efield_berry_phase
     105              :    USE qs_efield_local,                 ONLY: qs_efield_local_operator
     106              :    USE qs_energy_types,                 ONLY: qs_energy_type
     107              :    USE qs_environment_types,            ONLY: get_qs_env,&
     108              :                                               qs_environment_type
     109              :    USE qs_force_types,                  ONLY: qs_force_type
     110              :    USE qs_gapw_densities,               ONLY: prepare_gapw_den
     111              :    USE qs_harris_types,                 ONLY: harris_type
     112              :    USE qs_harris_utils,                 ONLY: harris_set_potentials
     113              :    USE qs_integrate_potential,          ONLY: integrate_ppl_rspace,&
     114              :                                               integrate_rho_nlcc,&
     115              :                                               integrate_v_core_rspace
     116              :    USE qs_kind_types,                   ONLY: qs_kind_type
     117              :    USE qs_ks_apply_restraints,          ONLY: qs_ks_cdft_constraint,&
     118              :                                               qs_ks_mulliken_restraint,&
     119              :                                               qs_ks_s2_restraint
     120              :    USE qs_ks_atom,                      ONLY: update_ks_atom
     121              :    USE qs_ks_qmmm_methods,              ONLY: qmmm_calculate_energy,&
     122              :                                               qmmm_modify_hartree_pot
     123              :    USE qs_ks_types,                     ONLY: qs_ks_env_type,&
     124              :                                               set_ks_env
     125              :    USE qs_ks_utils,                     ONLY: &
     126              :         calc_v_sic_rspace, calculate_zmp_potential, compute_matrix_vxc, compute_matrix_vxc_kp, &
     127              :         get_embed_potential_energy, low_spin_roks, print_densities, print_detailed_energy, &
     128              :         sic_explicit_orbitals, sum_up_and_integrate
     129              :    USE qs_local_rho_types,              ONLY: local_rho_type
     130              :    USE qs_mo_types,                     ONLY: get_mo_set,&
     131              :                                               mo_set_type
     132              :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
     133              :    USE qs_rho0_ggrid,                   ONLY: integrate_vhg0_rspace
     134              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
     135              :                                               qs_rho_type
     136              :    USE qs_sccs,                         ONLY: sccs
     137              :    USE qs_vxc,                          ONLY: qs_vxc_create
     138              :    USE qs_vxc_atom,                     ONLY: calculate_vxc_atom
     139              :    USE rtp_admm_methods,                ONLY: rtp_admm_calc_rho_aux,&
     140              :                                               rtp_admm_merge_ks_matrix
     141              :    USE se_fock_matrix,                  ONLY: build_se_fock_matrix
     142              :    USE skala_gpw_functional,            ONLY: ensure_native_skala_grid_scope,&
     143              :                                               get_gauxc_section,&
     144              :                                               xc_section_uses_native_skala_grid
     145              :    USE smeagol_interface,               ONLY: smeagol_shift_v_hartree
     146              :    USE surface_dipole,                  ONLY: calc_dipsurf_potential
     147              :    USE tblite_ks_matrix,                ONLY: build_tblite_ks_matrix
     148              :    USE virial_types,                    ONLY: virial_type
     149              :    USE xc_gauxc_functional,             ONLY: apply_gauxc
     150              :    USE xtb_ks_matrix,                   ONLY: build_xtb_ks_matrix
     151              : #include "./base/base_uses.f90"
     152              : 
     153              :    IMPLICIT NONE
     154              : 
     155              :    PRIVATE
     156              : 
     157              :    LOGICAL, PARAMETER :: debug_this_module = .TRUE.
     158              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_ks_methods'
     159              : 
     160              :    PUBLIC :: calc_rho_tot_gspace, qs_ks_update_qs_env, qs_ks_build_kohn_sham_matrix, &
     161              :              qs_ks_allocate_basics, evaluate_core_matrix_traces, rebuild_ks_matrix
     162              : 
     163              : CONTAINS
     164              : 
     165              : ! **************************************************************************************************
     166              : !> \brief routine where the real calculations are made: the
     167              : !>      KS matrix is calculated
     168              : !> \param qs_env the qs_env to update
     169              : !> \param calculate_forces if true calculate the quantities needed
     170              : !>        to calculate the forces. Defaults to false.
     171              : !> \param just_energy if true updates the energies but not the
     172              : !>        ks matrix. Defaults to false
     173              : !> \param print_active ...
     174              : !> \param ext_ks_matrix ...
     175              : !> \param ext_xc_section ...
     176              : !> \par History
     177              : !>      06.2002 moved from qs_scf to qs_ks_methods, use of ks_env
     178              : !>              new did_change scheme [fawzi]
     179              : !>      10.2002 introduced pools, uses updated rho as input, LSD [fawzi]
     180              : !>      10.2004 build_kohn_sham matrix now also computes the derivatives
     181              : !>              of the total energy wrt to the MO coefs, if instructed to
     182              : !>              do so. This appears useful for orbital dependent functionals
     183              : !>              where the KS matrix alone (however this might be defined)
     184              : !>               does not contain the info to construct this derivative.
     185              : !> \author Matthias Krack
     186              : !> \note
     187              : !>      make rho, energy and qs_charges optional, defaulting
     188              : !>      to qs_env components?
     189              : ! **************************************************************************************************
     190       120127 :    SUBROUTINE qs_ks_build_kohn_sham_matrix(qs_env, calculate_forces, just_energy, &
     191              :                                            print_active, ext_ks_matrix, ext_xc_section)
     192              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     193              :       LOGICAL, INTENT(in)                                :: calculate_forces, just_energy
     194              :       LOGICAL, INTENT(IN), OPTIONAL                      :: print_active
     195              :       TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
     196              :          POINTER                                         :: ext_ks_matrix
     197              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: ext_xc_section
     198              : 
     199              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_ks_build_kohn_sham_matrix'
     200              :       CHARACTER(len=default_string_length)               :: name
     201              :       INTEGER                                            :: ace_rebuild_frequency, atom_a, handle, &
     202              :                                                             iatom, ikind, img, ispin, natom, &
     203              :                                                             nimages, nspins
     204       120127 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind, kind_of
     205              :       LOGICAL :: ace_active, do_adiabatic_rescaling, do_ddapc, do_hfx, do_kpoints, do_ppl, dokp, &
     206              :          gapw, gapw_xc, just_energy_xc, lrigpw, my_print, native_grid_use_cuda, &
     207              :          native_skala_restore_exc, rigpw, use_gauxc_matrix, use_virial
     208              :       CHARACTER(LEN=*), PARAMETER :: native_skala_gapw_xc_msg = &
     209              :          "Native SKALA grid does not support METHOD GAPW_XC; "// &
     210              :          "the GAPW_XC one-center XC correction needs a dedicated SKALA design."
     211              : 
     212              :       REAL(KIND=dp)                                      :: ecore_ppl, edisp, ee_ener, ekin_mol, &
     213              :                                                             mulliken_order_p, &
     214              :                                                             native_skala_exc_scf, &
     215              :                                                             native_skala_total_scf, vscale
     216       120127 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: native_skala_atom_force
     217              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: h_stress, pv_loc
     218              :       TYPE(admm_type), POINTER                           :: admm_env
     219       120127 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     220              :       TYPE(cdft_control_type), POINTER                   :: cdft_control
     221              :       TYPE(cell_type), POINTER                           :: cell
     222              :       TYPE(cp_logger_type), POINTER                      :: logger
     223       120127 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ksmat, matrix_vxc, mo_derivs
     224       120127 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix, ks_matrix_im, matrix_h, &
     225       120127 :                                                             matrix_h_im, matrix_s, matrix_vxc_kp, &
     226       120127 :                                                             my_rho, rho_ao
     227              :       TYPE(dft_control_type), POINTER                    :: dft_control
     228       120127 :       TYPE(ecoul_1center_type), DIMENSION(:), POINTER    :: ecoul_1c
     229              :       TYPE(harris_type), POINTER                         :: harris_env
     230              :       TYPE(kpoint_type), POINTER                         :: kpoints
     231              :       TYPE(local_rho_type), POINTER                      :: local_rho_set
     232              :       TYPE(lri_density_type), POINTER                    :: lri_density
     233              :       TYPE(lri_environment_type), POINTER                :: lri_env
     234       120127 :       TYPE(lri_kind_type), DIMENSION(:), POINTER         :: lri_v_int
     235              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     236       120127 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     237              :       TYPE(pw_c1d_gs_type)                               :: rho_tot_gspace, v_hartree_gspace
     238              :       TYPE(pw_c1d_gs_type), POINTER                      :: rho_core
     239              :       TYPE(pw_env_type), POINTER                         :: pw_env
     240              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
     241              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     242       120127 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, v_rspace_embed, v_rspace_new, &
     243       120127 :                                                             v_rspace_new_aux_fit, v_tau_rspace, &
     244       120127 :                                                             v_tau_rspace_aux_fit
     245              :       TYPE(pw_r3d_rs_type), POINTER :: rho0_s_rs, rho_nlcc, rhoz_cneo_s_rs, v_hartree_rspace, &
     246              :          v_sccs_rspace, v_sic_rspace, v_spin_ddapc_rest_r, vee, vppl_rspace
     247              :       TYPE(qs_energy_type), POINTER                      :: energy
     248       120127 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     249       120127 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     250              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     251              :       TYPE(qs_rho_type), POINTER                         :: rho, rho1, rho_struct, rho_xc
     252              :       TYPE(section_vals_type), POINTER                   :: ace_section, &
     253              :                                                             adiabatic_rescaling_section, &
     254              :                                                             gauxc_section, hfx_sections, input, &
     255              :                                                             scf_section, xc_section
     256              :       TYPE(virial_type), POINTER                         :: virial
     257              : 
     258       120127 :       CALL timeset(routineN, handle)
     259       120127 :       NULLIFY (admm_env, atomic_kind_set, cell, dft_control, force, logger, mo_derivs, my_rho, &
     260       120127 :                rho_struct, para_env, pw_env, virial, vppl_rspace, &
     261       120127 :                ace_section, &
     262       120127 :                adiabatic_rescaling_section, hfx_sections, input, scf_section, &
     263       120127 :                xc_section, gauxc_section, matrix_h, matrix_h_im, matrix_s, auxbas_pw_pool, poisson_env, &
     264       120127 :                v_rspace_new, v_rspace_new_aux_fit, v_tau_rspace, v_tau_rspace_aux_fit, matrix_vxc, &
     265       120127 :                matrix_vxc_kp, &
     266       120127 :                vee, rho_nlcc, ks_env, ks_matrix, ks_matrix_im, rho, energy, rho_xc, rho_r, rho_ao, &
     267       120127 :                rho_core, particle_set, qs_kind_set, kpoints)
     268              : 
     269       120127 :       CPASSERT(ASSOCIATED(qs_env))
     270              : 
     271       120127 :       logger => cp_get_default_logger()
     272       120127 :       my_print = .TRUE.
     273       120127 :       IF (PRESENT(print_active)) my_print = print_active
     274       120127 :       use_gauxc_matrix = .FALSE.
     275       120127 :       native_skala_restore_exc = .FALSE.
     276              : 
     277              :       CALL get_qs_env(qs_env, &
     278              :                       ks_env=ks_env, &
     279              :                       dft_control=dft_control, &
     280              :                       matrix_h_kp=matrix_h, &
     281              :                       matrix_h_im_kp=matrix_h_im, &
     282              :                       matrix_s_kp=matrix_s, &
     283              :                       matrix_ks_kp=ks_matrix, &
     284              :                       matrix_ks_im_kp=ks_matrix_im, &
     285              :                       matrix_vxc=matrix_vxc, &
     286              :                       matrix_vxc_kp=matrix_vxc_kp, &
     287              :                       pw_env=pw_env, &
     288              :                       cell=cell, &
     289              :                       atomic_kind_set=atomic_kind_set, &
     290              :                       para_env=para_env, &
     291              :                       input=input, &
     292              :                       virial=virial, &
     293              :                       v_hartree_rspace=v_hartree_rspace, &
     294              :                       vee=vee, &
     295              :                       rho_nlcc=rho_nlcc, &
     296              :                       rho=rho, &
     297              :                       rho_core=rho_core, &
     298              :                       rho_xc=rho_xc, &
     299              :                       energy=energy, &
     300              :                       force=force, &
     301              :                       kpoints=kpoints, &
     302              :                       do_kpoints=do_kpoints, &
     303              :                       particle_set=particle_set, &
     304              :                       qs_kind_set=qs_kind_set, &
     305       120127 :                       natom=natom)
     306              : 
     307       120127 :       CALL qs_rho_get(rho, rho_r=rho_r, rho_ao_kp=rho_ao)
     308              : 
     309       120127 :       nimages = dft_control%nimages
     310       120127 :       nspins = dft_control%nspins
     311              : 
     312              :       ! remap pointer to allow for non-kpoint external ks matrix
     313       120127 :       IF (PRESENT(ext_ks_matrix)) ks_matrix(1:nspins, 1:1) => ext_ks_matrix(1:nspins)
     314              : 
     315       120127 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     316              : 
     317       120127 :       adiabatic_rescaling_section => section_vals_get_subs_vals(input, "DFT%XC%ADIABATIC_RESCALING")
     318       120127 :       CALL section_vals_get(adiabatic_rescaling_section, explicit=do_adiabatic_rescaling)
     319       120127 :       just_energy_xc = just_energy
     320       120127 :       IF (do_adiabatic_rescaling) THEN
     321              :          !! If we perform adiabatic rescaling, the xc potential has to be scaled by the xc- and
     322              :          !! HFX-energy. Thus, let us first calculate the energy
     323           44 :          just_energy_xc = .TRUE.
     324              :       END IF
     325              : 
     326       120127 :       CPASSERT(ASSOCIATED(matrix_h))
     327       120127 :       CPASSERT(ASSOCIATED(matrix_s))
     328       120127 :       CPASSERT(ASSOCIATED(rho))
     329       120127 :       CPASSERT(ASSOCIATED(pw_env))
     330       120127 :       CPASSERT(SIZE(ks_matrix, 1) > 0)
     331       120127 :       dokp = (nimages > 1)
     332              : 
     333              :       ! Setup the possible usage of DDAPC charges
     334              :       do_ddapc = dft_control%qs_control%ddapc_restraint .OR. &
     335              :                  qs_env%cp_ddapc_ewald%do_decoupling .OR. &
     336              :                  qs_env%cp_ddapc_ewald%do_qmmm_periodic_decpl .OR. &
     337       120127 :                  qs_env%cp_ddapc_ewald%do_solvation
     338              : 
     339              :       ! Check if LRIGPW is used
     340       120127 :       lrigpw = dft_control%qs_control%lrigpw
     341       120127 :       rigpw = dft_control%qs_control%rigpw
     342       120127 :       IF (rigpw) THEN
     343           26 :          CPASSERT(nimages == 1)
     344              :       END IF
     345           26 :       IF (lrigpw .AND. rigpw) THEN
     346            0 :          CPABORT(" LRI and RI are not compatible")
     347              :       END IF
     348              : 
     349              :       ! Check for GAPW method : additional terms for local densities
     350       120127 :       gapw = dft_control%qs_control%gapw
     351       120127 :       gapw_xc = dft_control%qs_control%gapw_xc
     352       120127 :       IF (gapw_xc .AND. gapw) THEN
     353            0 :          CPABORT(" GAPW and GAPW_XC are not compatible")
     354              :       END IF
     355       120127 :       IF ((gapw .AND. lrigpw) .OR. (gapw_xc .AND. lrigpw)) THEN
     356            0 :          CPABORT(" GAPW/GAPW_XC and LRIGPW are not compatible")
     357              :       END IF
     358       120127 :       IF ((gapw .AND. rigpw) .OR. (gapw_xc .AND. rigpw)) THEN
     359            0 :          CPABORT(" GAPW/GAPW_XC and RIGPW are not compatible")
     360              :       END IF
     361              : 
     362       120127 :       do_ppl = dft_control%qs_control%do_ppl_method == do_ppl_grid
     363       120127 :       IF (do_ppl) THEN
     364           60 :          CPASSERT(.NOT. gapw)
     365           60 :          CALL get_qs_env(qs_env=qs_env, vppl=vppl_rspace)
     366              :       END IF
     367              : 
     368       120127 :       IF (gapw_xc) THEN
     369         4032 :          CPASSERT(ASSOCIATED(rho_xc))
     370              :       END IF
     371              : 
     372              :       ! gets the tmp grids
     373       120127 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, poisson_env=poisson_env)
     374              : 
     375       120127 :       IF (gapw .AND. (poisson_env%parameters%solver == pw_poisson_implicit)) THEN
     376            0 :          CPABORT("The implicit Poisson solver cannot be used in conjunction with GAPW.")
     377              :       END IF
     378              : 
     379              :       ! ***  Prepare densities for gapw ***
     380       120127 :       IF (gapw .OR. gapw_xc) THEN
     381        24408 :          CALL prepare_gapw_den(qs_env, do_rho0=(.NOT. gapw_xc))
     382              :       END IF
     383              : 
     384              :       ! Calculate the Hartree potential
     385       120127 :       CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
     386       120127 :       CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
     387              : 
     388       120127 :       scf_section => section_vals_get_subs_vals(input, "DFT%SCF")
     389              :       IF (BTEST(cp_print_key_should_output(logger%iter_info, scf_section, &
     390              :                                            "PRINT%DETAILED_ENERGY"), &
     391              :                 cp_p_file) .AND. &
     392       120127 :           (.NOT. gapw) .AND. (.NOT. gapw_xc) .AND. &
     393              :           (.NOT. (poisson_env%parameters%solver == pw_poisson_implicit))) THEN
     394          916 :          CALL pw_zero(rho_tot_gspace)
     395          916 :          CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho, skip_nuclear_density=.TRUE.)
     396              :          CALL pw_poisson_solve(poisson_env, rho_tot_gspace, energy%e_hartree, &
     397          916 :                                v_hartree_gspace)
     398          916 :          CALL pw_zero(rho_tot_gspace)
     399          916 :          CALL pw_zero(v_hartree_gspace)
     400              :       END IF
     401              : 
     402              :       ! Get the total density in g-space [ions + electrons]
     403       120127 :       CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho)
     404              : 
     405       120127 :       IF (qs_env%scf_control%gce%do_gce .AND. .NOT. dft_control%do_pcc) THEN
     406            0 :          CPABORT("GCE requires DFT%PLANAR_COUNTER_CHARGE to define the countercharge plane.")
     407              :       END IF
     408              : 
     409              :       ! Add the planar counter charge density
     410       120127 :       IF (dft_control%do_pcc) THEN
     411           22 :          CALL planar_counter_charge(rho_tot_gspace, dft_control%pcc_control, auxbas_pw_pool)
     412              :       END IF
     413              : 
     414       120127 :       IF (my_print) THEN
     415       120105 :          CALL print_densities(qs_env, rho)
     416              :       END IF
     417              : 
     418       120127 :       IF (dft_control%do_sccs) THEN
     419              :          ! Self-consistent continuum solvation (SCCS) model
     420              :          NULLIFY (v_sccs_rspace)
     421          132 :          ALLOCATE (v_sccs_rspace)
     422          132 :          CALL auxbas_pw_pool%create_pw(v_sccs_rspace)
     423              : 
     424          132 :          IF (poisson_env%parameters%solver == pw_poisson_implicit) THEN
     425            0 :             CPABORT("The implicit Poisson solver cannot be used together with SCCS.")
     426              :          END IF
     427              : 
     428          132 :          IF (use_virial .AND. calculate_forces) THEN
     429              :             CALL sccs(qs_env, rho_tot_gspace, v_hartree_gspace, v_sccs_rspace, &
     430            0 :                       h_stress=h_stress)
     431            0 :             virial%pv_ehartree = virial%pv_ehartree + h_stress/REAL(para_env%num_pe, dp)
     432            0 :             virial%pv_virial = virial%pv_virial + h_stress/REAL(para_env%num_pe, dp)
     433              :          ELSE
     434          132 :             CALL sccs(qs_env, rho_tot_gspace, v_hartree_gspace, v_sccs_rspace)
     435              :          END IF
     436              :       ELSE
     437              :          ! Getting the Hartree energy and Hartree potential.  Also getting the stress tensor
     438              :          ! from the Hartree term if needed.  No nuclear force information here
     439       119995 :          IF (use_virial .AND. calculate_forces) THEN
     440          434 :             h_stress(:, :) = 0.0_dp
     441              :             CALL pw_poisson_solve(poisson_env, rho_tot_gspace, energy%hartree, &
     442              :                                   v_hartree_gspace, h_stress=h_stress, &
     443          434 :                                   rho_core=rho_core)
     444         5642 :             virial%pv_ehartree = virial%pv_ehartree + h_stress/REAL(para_env%num_pe, dp)
     445         5642 :             virial%pv_virial = virial%pv_virial + h_stress/REAL(para_env%num_pe, dp)
     446              :          ELSE
     447              :             CALL pw_poisson_solve(poisson_env, rho_tot_gspace, energy%hartree, &
     448       119561 :                                   v_hartree_gspace, rho_core=rho_core)
     449              :          END IF
     450              :       END IF
     451              : 
     452       120127 :       IF (dft_control%do_paep .OR. qs_env%scf_control%gce%do_gce) THEN
     453           22 :          CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
     454              :          CALL planar_averaged_v_hartree_3d(v_hartree_rspace, dft_control, qs_env%scf_control%gce%do_gce, &
     455           22 :                                            qs_env%scf_control%gce%ref_esp, para_env)
     456              :       END IF
     457              : 
     458              :       ! In case decouple periodic images and/or apply restraints to charges
     459       120127 :       IF (do_ddapc) THEN
     460              :          CALL qs_ks_ddapc(qs_env, auxbas_pw_pool, rho_tot_gspace, v_hartree_gspace, &
     461              :                           v_spin_ddapc_rest_r, energy, calculate_forces, ks_matrix, &
     462         1742 :                           just_energy)
     463              :       ELSE
     464       118385 :          dft_control%qs_control%ddapc_explicit_potential = .FALSE.
     465       118385 :          dft_control%qs_control%ddapc_restraint_is_spin = .FALSE.
     466       118385 :          IF (.NOT. just_energy) THEN
     467       109161 :             CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
     468       109161 :             CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
     469              :          END IF
     470              :       END IF
     471       120127 :       CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
     472              : 
     473       120127 :       IF (dft_control%correct_surf_dip) THEN
     474          110 :          IF (dft_control%surf_dip_correct_switch) THEN
     475          110 :             CALL calc_dipsurf_potential(qs_env, energy)
     476          110 :             energy%hartree = energy%hartree + energy%surf_dipole
     477              :          END IF
     478              :       END IF
     479              : 
     480              :       ! SIC
     481              :       CALL calc_v_sic_rspace(v_sic_rspace, energy, qs_env, dft_control, rho, poisson_env, &
     482       120127 :                              just_energy, calculate_forces, auxbas_pw_pool)
     483              : 
     484              :       ! Check if CDFT constraint is needed
     485       120127 :       CALL qs_ks_cdft_constraint(qs_env, auxbas_pw_pool, calculate_forces, cdft_control)
     486              : 
     487              :       ! Adds the External Potential if requested
     488       120127 :       IF (dft_control%apply_external_potential) THEN
     489              :          ! Compute the energy due to the external potential
     490              :          ee_ener = 0.0_dp
     491          728 :          DO ispin = 1, nspins
     492          728 :             ee_ener = ee_ener + pw_integral_ab(rho_r(ispin), vee)
     493              :          END DO
     494          364 :          IF (.NOT. just_energy) THEN
     495          364 :             IF (gapw) THEN
     496              :                CALL get_qs_env(qs_env=qs_env, &
     497              :                                rho0_s_rs=rho0_s_rs, &
     498           42 :                                rhoz_cneo_s_rs=rhoz_cneo_s_rs)
     499           42 :                CPASSERT(ASSOCIATED(rho0_s_rs))
     500           42 :                IF (ASSOCIATED(rhoz_cneo_s_rs)) THEN
     501            0 :                   CALL pw_axpy(rhoz_cneo_s_rs, rho0_s_rs)
     502              :                END IF
     503           42 :                ee_ener = ee_ener + pw_integral_ab(rho0_s_rs, vee)
     504           42 :                IF (ASSOCIATED(rhoz_cneo_s_rs)) THEN
     505            0 :                   CALL pw_axpy(rhoz_cneo_s_rs, rho0_s_rs, -1.0_dp)
     506              :                END IF
     507              :             END IF
     508              :          END IF
     509              :          ! the sign accounts for the charge of the electrons
     510          364 :          energy%ee = -ee_ener
     511              :       END IF
     512              : 
     513              :       ! Adds the QM/MM potential
     514       120127 :       IF (qs_env%qmmm) THEN
     515              :          CALL qmmm_calculate_energy(qs_env=qs_env, &
     516              :                                     rho=rho_r, &
     517              :                                     v_qmmm=qs_env%ks_qmmm_env%v_qmmm_rspace, &
     518         6306 :                                     qmmm_energy=energy%qmmm_el)
     519         6306 :          IF (qs_env%qmmm_env_qm%image_charge) THEN
     520              :             CALL calculate_image_pot(v_hartree_rspace=v_hartree_rspace, &
     521              :                                      rho_hartree_gspace=rho_tot_gspace, &
     522              :                                      energy=energy, &
     523              :                                      qmmm_env=qs_env%qmmm_env_qm, &
     524           60 :                                      qs_env=qs_env)
     525           60 :             IF (.NOT. just_energy) THEN
     526              :                CALL add_image_pot_to_hartree_pot(v_hartree=v_hartree_rspace, &
     527              :                                                  v_metal=qs_env%ks_qmmm_env%v_metal_rspace, &
     528           60 :                                                  qs_env=qs_env)
     529           60 :                IF (calculate_forces) THEN
     530              :                   CALL integrate_potential_devga_rspace( &
     531              :                      potential=v_hartree_rspace, coeff=qs_env%image_coeff, &
     532              :                      forces=qs_env%qmmm_env_qm%image_charge_pot%image_forcesMM, &
     533           20 :                      qmmm_env=qs_env%qmmm_env_qm, qs_env=qs_env)
     534              :                END IF
     535              :             END IF
     536           60 :             CALL qs_env%ks_qmmm_env%v_metal_rspace%release()
     537           60 :             DEALLOCATE (qs_env%ks_qmmm_env%v_metal_rspace)
     538              :          END IF
     539         6306 :          IF (.NOT. just_energy) THEN
     540              :             CALL qmmm_modify_hartree_pot(v_hartree=v_hartree_rspace, &
     541         6222 :                                          v_qmmm=qs_env%ks_qmmm_env%v_qmmm_rspace, scale=1.0_dp)
     542              :          END IF
     543              :       END IF
     544       120127 :       CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
     545              : 
     546              :       ! SMEAGOL interface
     547       120127 :       IF (dft_control%smeagol_control%smeagol_enabled .AND. &
     548              :           dft_control%smeagol_control%run_type == smeagol_runtype_emtransport) THEN
     549            0 :          CPASSERT(ASSOCIATED(dft_control%smeagol_control%aux))
     550              :          CALL smeagol_shift_v_hartree(v_hartree_rspace, cell, &
     551              :                                       dft_control%smeagol_control%aux%HartreeLeadsLeft, &
     552              :                                       dft_control%smeagol_control%aux%HartreeLeadsRight, &
     553              :                                       dft_control%smeagol_control%aux%HartreeLeadsBottom, &
     554              :                                       dft_control%smeagol_control%aux%VBias, &
     555              :                                       dft_control%smeagol_control%aux%minL, &
     556              :                                       dft_control%smeagol_control%aux%maxR, &
     557              :                                       dft_control%smeagol_control%aux%isexplicit_maxR, &
     558            0 :                                       dft_control%smeagol_control%aux%isexplicit_HartreeLeadsBottom)
     559              :       END IF
     560              : 
     561              :       ! calculate the density matrix for the fitted mo_coeffs
     562       120127 :       IF (dft_control%do_admm) THEN
     563        13020 :          IF (PRESENT(ext_xc_section)) THEN
     564            0 :             CALL hfx_admm_init(qs_env, calculate_forces, ext_xc_section)
     565              :          ELSE
     566        13020 :             CALL hfx_admm_init(qs_env, calculate_forces)
     567              :          END IF
     568              : 
     569        13020 :          IF (dft_control%do_admm_mo) THEN
     570        12806 :             IF (qs_env%run_rtp) THEN
     571           92 :                CALL rtp_admm_calc_rho_aux(qs_env)
     572              :             ELSE
     573        12714 :                IF (dokp) THEN
     574          156 :                   CALL admm_mo_calc_rho_aux_kp(qs_env)
     575              :                ELSE
     576        12558 :                   CALL admm_mo_calc_rho_aux(qs_env)
     577              :                END IF
     578              :             END IF
     579          214 :          ELSEIF (dft_control%do_admm_dm) THEN
     580          214 :             CALL admm_dm_calc_rho_aux(qs_env)
     581              :          END IF
     582              :       END IF
     583              : 
     584              :       ! only activate stress calculation if
     585       120127 :       IF (use_virial .AND. calculate_forces) virial%pv_calculate = .TRUE.
     586              : 
     587              :       ! *** calculate the xc potential on the pw density ***
     588              :       ! *** associates v_rspace_new if the xc potential needs to be computed.
     589              :       ! If we do wavefunction fitting, we need the vxc_potential in the auxiliary basis set
     590       120127 :       IF (dft_control%do_admm) THEN
     591        13020 :          CALL get_qs_env(qs_env, admm_env=admm_env)
     592        13020 :          xc_section => admm_env%xc_section_aux
     593        13020 :          CALL get_admm_env(admm_env, rho_aux_fit=rho_struct)
     594              : 
     595              :          ! here we ignore a possible vdW section in admm_env%xc_section_aux
     596              :          CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=xc_section, &
     597              :                             vxc_rho=v_rspace_new_aux_fit, vxc_tau=v_tau_rspace_aux_fit, exc=energy%exc_aux_fit, &
     598        13020 :                             just_energy=just_energy_xc)
     599              : 
     600        13020 :          IF (admm_env%do_gapw) THEN
     601              :             !compute the potential due to atomic densities
     602              :             CALL calculate_vxc_atom(qs_env, energy_only=just_energy_xc, exc1=energy%exc1_aux_fit, &
     603              :                                     kind_set_external=admm_env%admm_gapw_env%admm_kind_set, &
     604              :                                     xc_section_external=xc_section, &
     605         4394 :                                     rho_atom_set_external=admm_env%admm_gapw_env%local_rho_set%rho_atom_set)
     606              : 
     607              :          END IF
     608              : 
     609        13020 :          NULLIFY (rho_struct)
     610              : 
     611        13020 :          IF (use_virial .AND. calculate_forces) THEN
     612           20 :             vscale = 1.0_dp
     613              :             !Note: ADMMS and ADMMP stress tensor only for closed-shell calculations
     614           20 :             IF (admm_env%do_admms) vscale = admm_env%gsi(1)**(2.0_dp/3.0_dp)
     615           20 :             IF (admm_env%do_admmp) vscale = admm_env%gsi(1)**2
     616          260 :             virial%pv_exc = virial%pv_exc - vscale*virial%pv_xc
     617          260 :             virial%pv_virial = virial%pv_virial - vscale*virial%pv_xc
     618              :             ! virial%pv_xc will be zeroed in the xc routines
     619              :          END IF
     620        13020 :          xc_section => admm_env%xc_section_primary
     621              :       ELSE
     622       107107 :          xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     623              :          ! build ks matrix with an xc section potentially different from the one defined in input
     624       107107 :          IF (PRESENT(ext_xc_section)) xc_section => ext_xc_section
     625              :       END IF
     626              : 
     627       120127 :       IF (gapw_xc) THEN
     628         4032 :          CALL get_qs_env(qs_env=qs_env, rho_xc=rho_struct)
     629              :       ELSE
     630       116095 :          CALL get_qs_env(qs_env=qs_env, rho=rho_struct)
     631              :       END IF
     632              : 
     633              :       ! zmp
     634       120127 :       IF (dft_control%apply_external_density .OR. dft_control%apply_external_vxc) THEN
     635            0 :          energy%exc = 0.0_dp
     636            0 :          CALL calculate_zmp_potential(qs_env, v_rspace_new, rho, exc=energy%exc)
     637              :       ELSE
     638              :          ! Embedding potential (runs regardless of XC method)
     639       120127 :          IF (dft_control%apply_embed_pot) THEN
     640          868 :             NULLIFY (v_rspace_embed)
     641          868 :             energy%embed_corr = 0.0_dp
     642              :             CALL get_embed_potential_energy(qs_env, rho, v_rspace_embed, dft_control, &
     643          868 :                                             energy%embed_corr, just_energy)
     644              :          END IF
     645              : 
     646              :          ! Everything else, either via GauXC or manual XC computation
     647       120127 :          IF (dft_control%use_gauxc) THEN
     648          522 :             IF (xc_section_uses_native_skala_grid(xc_section)) THEN
     649          144 :                CALL ensure_native_skala_grid_scope(xc_section)
     650          144 :                IF (gapw_xc) THEN
     651            0 :                   CPABORT(native_skala_gapw_xc_msg)
     652              :                END IF
     653          144 :                IF (gapw) THEN
     654           16 :                   DO ikind = 1, SIZE(qs_kind_set)
     655              :                      IF (qs_kind_set(ikind)%paw_atom .AND. .NOT. &
     656            8 :                          qs_kind_set(ikind)%gpw_type_forced .AND. &
     657              :                          (ASSOCIATED(qs_kind_set(ikind)%gth_potential) .OR. &
     658            8 :                           ASSOCIATED(qs_kind_set(ikind)%sgp_potential))) THEN
     659              :                         CALL cp_abort(__LOCATION__, &
     660              :                                       "Native SKALA grid evaluation with METHOD GAPW and "// &
     661              :                                       "pseudopotentials requires KIND%GPW_TYPE. PAW/one-center "// &
     662            0 :                                       "GAPW+GTH/ECP is not implemented.")
     663              :                      END IF
     664              :                   END DO
     665              :                END IF
     666          144 :                IF ((.NOT. do_kpoints) .AND. nimages /= 1) THEN
     667              :                   CALL cp_abort(__LOCATION__, &
     668              :                                 "Native SKALA grid evaluation supports multiple images only "// &
     669            0 :                                 "for k-point calculations.")
     670              :                END IF
     671          144 :                IF (do_kpoints) THEN
     672            0 :                   CPASSERT(ASSOCIATED(kpoints))
     673            0 :                   gauxc_section => get_gauxc_section(xc_section)
     674            0 :                   CPASSERT(ASSOCIATED(gauxc_section))
     675            0 :                   CALL section_vals_val_get(gauxc_section, "NATIVE_GRID_USE_CUDA", l_val=native_grid_use_cuda)
     676            0 :                   IF (.NOT. native_grid_use_cuda) THEN
     677              :                      CALL cp_abort(__LOCATION__, &
     678              :                                    "Native SKALA grid evaluation with k-points currently requires "// &
     679              :                                    "GAUXC%NATIVE_GRID_USE_CUDA T. The CPU TorchScript path can "// &
     680              :                                    "destabilize the k-point diagonalization through "// &
     681              :                                    "libtorch_cpu/OpenBLAS library interactions; use the CUDA SKALA model/path for "// &
     682            0 :                                    "k-point runs.")
     683              :                   END IF
     684              :                END IF
     685          144 :                IF (dft_control%roks) THEN
     686            0 :                   CPABORT("Native SKALA grid evaluation does not support ROKS.")
     687              :                END IF
     688          144 :                IF (dft_control%do_admm) THEN
     689            0 :                   CPABORT("Native SKALA grid evaluation does not support ADMM.")
     690              :                END IF
     691              :                ! Force/stress rebuilds re-enter this path for derivatives and VXC only;
     692              :                ! keep the already evaluated SCF energy contribution.
     693          144 :                native_skala_restore_exc = calculate_forces
     694          144 :                IF (native_skala_restore_exc) THEN
     695           16 :                   native_skala_exc_scf = energy%exc
     696           16 :                   native_skala_total_scf = energy%total
     697              :                END IF
     698          144 :                IF (calculate_forces) THEN
     699           48 :                   ALLOCATE (native_skala_atom_force(3, natom))
     700              :                   CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=xc_section, &
     701              :                                      vxc_rho=v_rspace_new, vxc_tau=v_tau_rspace, exc=energy%exc, &
     702              :                                      edisp=edisp, dispersion_env=qs_env%dispersion_env, &
     703              :                                      just_energy=just_energy_xc, &
     704           16 :                                      native_skala_atom_force=native_skala_atom_force)
     705           16 :                   CPASSERT(ASSOCIATED(force))
     706           16 :                   CPASSERT(ASSOCIATED(atomic_kind_set))
     707           16 :                   CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
     708           48 :                   DO iatom = 1, natom
     709           32 :                      ikind = kind_of(iatom)
     710           32 :                      atom_a = atom_of_kind(iatom)
     711              :                      force(ikind)%rho_elec(:, atom_a) = force(ikind)%rho_elec(:, atom_a) + &
     712          144 :                                                         native_skala_atom_force(:, iatom)
     713              :                   END DO
     714           32 :                   DEALLOCATE (atom_of_kind, kind_of, native_skala_atom_force)
     715              :                ELSE
     716              :                   CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=xc_section, &
     717              :                                      vxc_rho=v_rspace_new, vxc_tau=v_tau_rspace, exc=energy%exc, &
     718              :                                      edisp=edisp, dispersion_env=qs_env%dispersion_env, &
     719          128 :                                      just_energy=just_energy_xc)
     720              :                END IF
     721          144 :                IF (native_skala_restore_exc) energy%exc = native_skala_exc_scf
     722          144 :                IF (gapw) THEN
     723            8 :                   CALL calculate_vxc_atom(qs_env, just_energy_xc, energy%exc1, xc_section_external=xc_section)
     724              :                END IF
     725          144 :                IF (edisp /= 0.0_dp) energy%dispersion = edisp
     726          144 :                IF (qs_env%requires_matrix_vxc .AND. ASSOCIATED(v_rspace_new)) THEN
     727            0 :                   IF (do_kpoints) THEN
     728            0 :                      CALL compute_matrix_vxc_kp(qs_env=qs_env, v_rspace=v_rspace_new, matrix_vxc_kp=matrix_vxc_kp)
     729            0 :                      CALL set_ks_env(ks_env, matrix_vxc_kp=matrix_vxc_kp)
     730              :                   ELSE
     731            0 :                      CALL compute_matrix_vxc(qs_env=qs_env, v_rspace=v_rspace_new, matrix_vxc=matrix_vxc)
     732            0 :                      CALL set_ks_env(ks_env, matrix_vxc=matrix_vxc)
     733              :                   END IF
     734              :                END IF
     735              :             ELSE
     736          378 :                IF (gapw_xc) THEN
     737              :                   CALL cp_abort(__LOCATION__, &
     738              :                                 "GauXC with METHOD GAPW_XC is unsupported. The "// &
     739            0 :                                 "GAPW_XC one-center XC correction needs a dedicated GauXC design.")
     740              :                END IF
     741          378 :                use_gauxc_matrix = .TRUE.
     742          378 :                CALL apply_gauxc(qs_env, xc_section, calculate_forces)
     743              :             END IF
     744              :          ELSE
     745              :             CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=xc_section, &
     746              :                                vxc_rho=v_rspace_new, vxc_tau=v_tau_rspace, exc=energy%exc, &
     747              :                                edisp=edisp, dispersion_env=qs_env%dispersion_env, &
     748       119605 :                                just_energy=just_energy_xc)
     749       119605 :             IF (edisp /= 0.0_dp) energy%dispersion = edisp
     750       119605 :             IF (qs_env%requires_matrix_vxc .AND. ASSOCIATED(v_rspace_new)) THEN
     751            2 :                CALL compute_matrix_vxc(qs_env=qs_env, v_rspace=v_rspace_new, matrix_vxc=matrix_vxc)
     752            2 :                CALL set_ks_env(ks_env, matrix_vxc=matrix_vxc)
     753              :             END IF
     754              : 
     755       119605 :             IF (gapw .OR. gapw_xc) THEN
     756        24390 :                CALL calculate_vxc_atom(qs_env, just_energy_xc, energy%exc1, xc_section_external=xc_section)
     757              :             END IF
     758              :          END IF
     759              :       END IF
     760              : 
     761              :       ! set hartree and xc potentials for use in Harris method
     762       120127 :       IF (qs_env%harris_method) THEN
     763           80 :          CALL get_qs_env(qs_env, harris_env=harris_env)
     764           80 :          CALL harris_set_potentials(harris_env, v_hartree_rspace, v_rspace_new)
     765              :       END IF
     766              : 
     767       120127 :       NULLIFY (rho_struct)
     768       120127 :       IF (use_virial .AND. calculate_forces) THEN
     769         5642 :          virial%pv_exc = virial%pv_exc - virial%pv_xc
     770         5642 :          virial%pv_virial = virial%pv_virial - virial%pv_xc
     771              :       END IF
     772              : 
     773              :       ! *** Add Hartree-Fock contribution if required ***
     774       120127 :       hfx_sections => section_vals_get_subs_vals(xc_section, "HF")
     775       120127 :       CALL section_vals_get(hfx_sections, explicit=do_hfx)
     776              : 
     777       120127 :       ace_active = .FALSE.
     778       120127 :       ace_rebuild_frequency = 1
     779              : 
     780       120127 :       IF (do_hfx) THEN
     781        28628 :          ace_section => section_vals_get_subs_vals(hfx_sections, "ACE")
     782        28628 :          IF (ASSOCIATED(ace_section)) THEN
     783        28628 :             CALL section_vals_val_get(ace_section, "ACTIVE", l_val=ace_active)
     784        28628 :             CALL section_vals_val_get(ace_section, "REBUILD_FREQUENCY", i_val=ace_rebuild_frequency)
     785              :          END IF
     786              :       END IF
     787              : 
     788       120127 :       IF (do_hfx) THEN
     789        28628 :          IF (dokp) THEN
     790          274 :             IF (ace_active) THEN
     791            0 :                CPABORT("ACE-HFX for k-points is not implemented yet")
     792              :             ELSE
     793          274 :                CALL hfx_ks_matrix_kp(qs_env, ks_matrix, energy, calculate_forces)
     794              :             END IF
     795              : 
     796              :          ELSE
     797              :             ! ext_xc_section may contain a hfx section
     798        28354 :             IF (ace_active) THEN
     799              :                CALL hfx_ace_ks_matrix(qs_env, ks_matrix, rho, energy, calculate_forces, &
     800              :                                       just_energy, v_rspace_new, v_tau_rspace, &
     801           48 :                                       ace_rebuild_frequency, ext_xc_section=xc_section)
     802              :             ELSE
     803              :                CALL hfx_ks_matrix(qs_env, ks_matrix, rho, energy, calculate_forces, &
     804        28306 :                                   just_energy, v_rspace_new, v_tau_rspace, ext_xc_section=xc_section)
     805              :             END IF
     806              :          END IF
     807              :       END IF !do_hfx
     808              : 
     809       120127 :       IF (do_ppl .AND. calculate_forces) THEN
     810           12 :          CPASSERT(.NOT. gapw)
     811           26 :          DO ispin = 1, nspins
     812           26 :             CALL integrate_ppl_rspace(rho_r(ispin), qs_env)
     813              :          END DO
     814              :       END IF
     815              : 
     816       120127 :       IF (ASSOCIATED(rho_nlcc) .AND. calculate_forces) THEN
     817           72 :          DO ispin = 1, nspins
     818           36 :             CALL integrate_rho_nlcc(v_rspace_new(ispin), qs_env)
     819           72 :             IF (dft_control%do_admm) CALL integrate_rho_nlcc(v_rspace_new_aux_fit(ispin), qs_env)
     820              :          END DO
     821              :       END IF
     822              : 
     823              :       ! calculate KG correction
     824       120127 :       IF (dft_control%qs_control%do_kg .AND. just_energy) THEN
     825              : 
     826           12 :          CPASSERT(nimages == 1)
     827           12 :          ksmat => ks_matrix(:, 1)
     828           12 :          CALL kg_ekin_subset(qs_env, ksmat, ekin_mol, calculate_forces, do_kernel=.FALSE.)
     829              : 
     830              :          ! subtract kg corr from the total energy
     831           12 :          energy%exc = energy%exc - ekin_mol
     832              : 
     833              :       END IF
     834              : 
     835              :       ! ***  Single atom contributions ***
     836       120127 :       IF (.NOT. just_energy) THEN
     837       110519 :          IF (calculate_forces) THEN
     838              :             ! Getting nuclear force contribution from the core charge density
     839         5913 :             IF ((poisson_env%parameters%solver == pw_poisson_implicit) .AND. &
     840              :                 (poisson_env%parameters%dielectric_params%dielec_core_correction)) THEN
     841           28 :                BLOCK
     842              :                   TYPE(pw_r3d_rs_type) :: v_minus_veps
     843           28 :                   CALL auxbas_pw_pool%create_pw(v_minus_veps)
     844           28 :                   CALL pw_copy(v_hartree_rspace, v_minus_veps)
     845           28 :                   CALL pw_axpy(poisson_env%implicit_env%v_eps, v_minus_veps, -v_hartree_rspace%pw_grid%dvol)
     846           28 :                   CALL integrate_v_core_rspace(v_minus_veps, qs_env)
     847           28 :                   CALL auxbas_pw_pool%give_back_pw(v_minus_veps)
     848              :                END BLOCK
     849              :             ELSE
     850         5885 :                CALL integrate_v_core_rspace(v_hartree_rspace, qs_env)
     851              :             END IF
     852              :          END IF
     853              : 
     854       110519 :          IF (.NOT. do_hfx) THEN
     855              :             ! Initialize the Kohn-Sham matrix with the core Hamiltonian matrix
     856              :             ! (sets ks sparsity equal to matrix_h sparsity)
     857       183565 :             DO ispin = 1, nspins
     858       662021 :                DO img = 1, nimages
     859       478456 :                   CALL dbcsr_get_info(ks_matrix(ispin, img)%matrix, name=name) ! keep the name
     860       577748 :                   CALL dbcsr_copy(ks_matrix(ispin, img)%matrix, matrix_h(1, img)%matrix, name=name)
     861              :                END DO
     862              :             END DO
     863              :             ! imaginary part if required
     864        84273 :             IF (qs_env%run_rtp) THEN
     865         2036 :                IF (dft_control%rtp_control%velocity_gauge) THEN
     866          150 :                   CPASSERT(ASSOCIATED(matrix_h_im))
     867          150 :                   CPASSERT(ASSOCIATED(ks_matrix_im))
     868          300 :                   DO ispin = 1, nspins
     869          450 :                      DO img = 1, nimages
     870          150 :                         CALL dbcsr_get_info(ks_matrix_im(ispin, img)%matrix, name=name) ! keep the name
     871          300 :                         CALL dbcsr_copy(ks_matrix_im(ispin, img)%matrix, matrix_h_im(1, img)%matrix, name=name)
     872              :                      END DO
     873              :                   END DO
     874              :                END IF
     875              :             END IF
     876              :          END IF
     877              : 
     878       110519 :          IF (use_virial .AND. calculate_forces) THEN
     879         5642 :             pv_loc = virial%pv_virial
     880              :          END IF
     881              :          ! sum up potentials and integrate
     882              :          ! Pointing my_rho to the density matrix rho_ao
     883       110519 :          my_rho => rho_ao
     884              : 
     885              :          CALL sum_up_and_integrate(qs_env, ks_matrix, rho, my_rho, vppl_rspace, &
     886              :                                    v_rspace_new, v_rspace_new_aux_fit, v_tau_rspace, v_tau_rspace_aux_fit, &
     887              :                                    v_sic_rspace, v_spin_ddapc_rest_r, v_sccs_rspace, v_rspace_embed, &
     888       110519 :                                    cdft_control, calculate_forces)
     889              : 
     890       110519 :          IF (use_gauxc_matrix) THEN
     891          378 :             IF (dokp) THEN
     892            0 :                CALL get_qs_env(qs_env=qs_env, matrix_vxc_kp=matrix_vxc_kp)
     893            0 :                CPASSERT(ASSOCIATED(matrix_vxc_kp))
     894            0 :                DO ispin = 1, nspins
     895            0 :                   DO img = 1, nimages
     896              :                      CALL dbcsr_add(ks_matrix(ispin, img)%matrix, matrix_vxc_kp(ispin, img)%matrix, &
     897            0 :                                     1.0_dp, 1.0_dp)
     898              :                   END DO
     899              :                END DO
     900              :             ELSE
     901          378 :                CALL get_qs_env(qs_env=qs_env, matrix_vxc=matrix_vxc)
     902          378 :                CPASSERT(ASSOCIATED(matrix_vxc))
     903          378 :                CPASSERT(nimages == 1)
     904          778 :                DO ispin = 1, nspins
     905          778 :                   CALL dbcsr_add(ks_matrix(ispin, 1)%matrix, matrix_vxc(ispin)%matrix, 1.0_dp, 1.0_dp)
     906              :                END DO
     907              :             END IF
     908              :          END IF
     909              : 
     910       110519 :          IF (gapw .OR. gapw_xc) THEN
     911        23626 :             IF (calculate_forces) THEN
     912          702 :                IF (gapw_xc) THEN
     913          112 :                   CALL get_qs_env(qs_env=qs_env, rho_xc=rho_struct)
     914              :                ELSE
     915          590 :                   CALL get_qs_env(qs_env=qs_env, rho=rho_struct)
     916              :                END IF
     917          702 :                NULLIFY (rho1)
     918          702 :                IF (dft_control%use_gauxc .AND. gapw) THEN
     919              :                   ! GauXC evaluates GAPW XC directly on its molecular quadrature
     920              :                   ! grid.  The native accurate-XCINT force correction applies to
     921              :                   ! CP2K's regular-grid XC density and would otherwise try to
     922              :                   ! evaluate the GAUXC section through xc_derivatives.
     923              :                   CONTINUE
     924              :                ELSE
     925          698 :                   CALL accint_weight_force(qs_env, rho_struct, rho1, 0, xc_section)
     926              :                END IF
     927              :                !
     928          702 :                IF (dft_control%do_admm) THEN
     929           90 :                   CALL get_qs_env(qs_env, admm_env=admm_env)
     930           90 :                   xc_section => admm_env%xc_section_aux
     931           90 :                   CALL get_admm_env(admm_env, rho_aux_fit=rho_struct)
     932           90 :                   vscale = 1.0_dp
     933           90 :                   IF (admm_env%do_admmp) THEN
     934            8 :                      vscale = admm_env%gsi(1)**2
     935           82 :                   ELSE IF (admm_env%do_admms) THEN
     936            6 :                      vscale = admm_env%gsi(1)**(2.0_dp/3.0_dp)
     937              :                   END IF
     938           90 :                   CALL accint_weight_force(qs_env, rho_struct, rho1, 0, xc_section, force_scale=vscale)
     939              :                END IF
     940              :             END IF
     941              :          END IF
     942              : 
     943       110519 :          IF (use_virial .AND. calculate_forces) THEN
     944         5642 :             virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - pv_loc)
     945              :          END IF
     946       110519 :          IF (dft_control%qs_control%do_kg) THEN
     947          982 :             CPASSERT(nimages == 1)
     948          982 :             ksmat => ks_matrix(:, 1)
     949              : 
     950          982 :             IF (use_virial .AND. calculate_forces) THEN
     951          208 :                pv_loc = virial%pv_virial
     952              :             END IF
     953              : 
     954          982 :             CALL kg_ekin_subset(qs_env, ksmat, ekin_mol, calculate_forces, do_kernel=.FALSE.)
     955              :             ! subtract kg corr from the total energy
     956          982 :             energy%exc = energy%exc - ekin_mol
     957              : 
     958              :             ! virial corrections
     959          982 :             IF (use_virial .AND. calculate_forces) THEN
     960              : 
     961              :                ! Integral contribution
     962          208 :                virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - pv_loc)
     963              : 
     964              :                ! GGA contribution
     965          208 :                virial%pv_exc = virial%pv_exc + virial%pv_xc
     966          208 :                virial%pv_virial = virial%pv_virial + virial%pv_xc
     967          208 :                virial%pv_xc = 0.0_dp
     968              :             END IF
     969              :          END IF
     970              : 
     971              :       ELSE
     972              :          IF (do_hfx) THEN
     973              :             IF (.FALSE.) THEN
     974              :                CPWARN("KS matrix no longer correct. Check possible problems with property calculations!")
     975              :             END IF
     976              :          END IF
     977              :       END IF ! .NOT. just energy
     978       120127 :       IF (dft_control%qs_control%ddapc_explicit_potential) THEN
     979          164 :          CALL auxbas_pw_pool%give_back_pw(v_spin_ddapc_rest_r)
     980          164 :          DEALLOCATE (v_spin_ddapc_rest_r)
     981              :       END IF
     982              : 
     983       120127 :       IF (calculate_forces .AND. dft_control%qs_control%cdft) THEN
     984          118 :          IF (.NOT. cdft_control%transfer_pot) THEN
     985          212 :             DO iatom = 1, SIZE(cdft_control%group)
     986          114 :                CALL auxbas_pw_pool%give_back_pw(cdft_control%group(iatom)%weight)
     987          212 :                DEALLOCATE (cdft_control%group(iatom)%weight)
     988              :             END DO
     989           98 :             IF (cdft_control%atomic_charges) THEN
     990           78 :                DO iatom = 1, cdft_control%natoms
     991           78 :                   CALL auxbas_pw_pool%give_back_pw(cdft_control%charge(iatom))
     992              :                END DO
     993           26 :                DEALLOCATE (cdft_control%charge)
     994              :             END IF
     995           98 :             IF (cdft_control%type == outer_scf_becke_constraint .AND. &
     996              :                 cdft_control%becke_control%cavity_confine) THEN
     997           88 :                IF (.NOT. ASSOCIATED(cdft_control%becke_control%cavity_mat)) THEN
     998           64 :                   CALL auxbas_pw_pool%give_back_pw(cdft_control%becke_control%cavity)
     999              :                ELSE
    1000           24 :                   DEALLOCATE (cdft_control%becke_control%cavity_mat)
    1001              :                END IF
    1002           10 :             ELSE IF (cdft_control%type == outer_scf_hirshfeld_constraint) THEN
    1003            2 :                IF (ASSOCIATED(cdft_control%hirshfeld_control%hirshfeld_env%fnorm)) THEN
    1004            0 :                   CALL auxbas_pw_pool%give_back_pw(cdft_control%hirshfeld_control%hirshfeld_env%fnorm)
    1005              :                END IF
    1006              :             END IF
    1007           98 :             IF (ASSOCIATED(cdft_control%charges_fragment)) DEALLOCATE (cdft_control%charges_fragment)
    1008           98 :             cdft_control%save_pot = .FALSE.
    1009           98 :             cdft_control%need_pot = .TRUE.
    1010           98 :             cdft_control%external_control = .FALSE.
    1011              :          END IF
    1012              :       END IF
    1013              : 
    1014       120127 :       IF (dft_control%do_sccs) THEN
    1015          132 :          CALL auxbas_pw_pool%give_back_pw(v_sccs_rspace)
    1016          132 :          DEALLOCATE (v_sccs_rspace)
    1017              :       END IF
    1018              : 
    1019       120127 :       IF (gapw) THEN
    1020        20376 :          IF (dft_control%apply_external_potential) THEN
    1021              :             ! Integrals of the Hartree potential with g0_soft
    1022              :             CALL qmmm_modify_hartree_pot(v_hartree=v_hartree_rspace, &
    1023           42 :                                          v_qmmm=vee, scale=-1.0_dp)
    1024              :          END IF
    1025        20376 :          CALL integrate_vhg0_rspace(qs_env, v_hartree_rspace, para_env, calculate_forces)
    1026              :          ! Place Vh_1c_gg_integrals after integrate_vhg0_rspace for CNEO calculations
    1027              :          ! because vhg0 integral is needed to build the complete nuclear equation
    1028        20376 :          CALL get_qs_env(qs_env, ecoul_1c=ecoul_1c, local_rho_set=local_rho_set)
    1029              :          CALL Vh_1c_gg_integrals(qs_env, energy%hartree_1c, ecoul_1c, local_rho_set, para_env, tddft=.FALSE., &
    1030        20376 :                                  core_2nd=.FALSE.)
    1031              :          ! CNEO quantum nuclear core energy (kinetic + Z*erfc(r)/r potential from classical nuclei)
    1032        20376 :          energy%core_cneo = 0.0_dp
    1033        20376 :          IF (ASSOCIATED(local_rho_set%rhoz_cneo_set)) THEN
    1034          184 :             DO iatom = 1, SIZE(local_rho_set%rhoz_cneo_set)
    1035          184 :                energy%core_cneo = energy%core_cneo + local_rho_set%rhoz_cneo_set(iatom)%e_core
    1036              :             END DO
    1037              :          END IF
    1038              :       END IF
    1039              : 
    1040       120127 :       IF (gapw .OR. gapw_xc) THEN
    1041              :          ! Single atom contributions in the KS matrix ***
    1042        24408 :          CALL update_ks_atom(qs_env, ks_matrix, rho_ao, calculate_forces)
    1043        24408 :          IF (dft_control%do_admm) THEN
    1044              :             !Single atom contribution to the AUX matrices
    1045              :             !Note: also update ks_aux_fit matrix in case of rtp
    1046         4394 :             CALL admm_update_ks_atom(qs_env, calculate_forces)
    1047              :          END IF
    1048              :       END IF
    1049              : 
    1050              :       !Calculation of Mulliken restraint, if requested
    1051              :       CALL qs_ks_mulliken_restraint(energy, dft_control, just_energy, para_env, &
    1052       120127 :                                     ks_matrix, matrix_s, rho, mulliken_order_p)
    1053              : 
    1054              :       ! Add DFT+U contribution, if requested
    1055       120127 :       IF (dft_control%dft_plus_u) THEN
    1056         1768 :          IF (just_energy) THEN
    1057          616 :             CALL plus_u(qs_env=qs_env)
    1058              :          ELSE
    1059         1152 :             CALL plus_u(qs_env=qs_env, matrix_h=ks_matrix)
    1060              :          END IF
    1061              :       ELSE
    1062       118359 :          energy%dft_plus_u = 0.0_dp
    1063              :       END IF
    1064              : 
    1065              :       ! At this point the ks matrix should be up to date, filter it if requested
    1066       263957 :       DO ispin = 1, nspins
    1067       801081 :          DO img = 1, nimages
    1068              :             CALL dbcsr_filter(ks_matrix(ispin, img)%matrix, &
    1069       680954 :                               dft_control%qs_control%eps_filter_matrix)
    1070              :          END DO
    1071              :       END DO
    1072              : 
    1073              :       !** merge the auxiliary KS matrix and the primary one
    1074       120127 :       IF (dft_control%do_admm_mo) THEN
    1075        12806 :          IF (qs_env%run_rtp) THEN
    1076           92 :             CALL rtp_admm_merge_ks_matrix(qs_env)
    1077              :          ELSE
    1078        12714 :             CALL admm_mo_merge_ks_matrix(qs_env)
    1079              :          END IF
    1080       107321 :       ELSEIF (dft_control%do_admm_dm) THEN
    1081          214 :          CALL admm_dm_merge_ks_matrix(qs_env)
    1082              :       END IF
    1083              : 
    1084              :       ! External field (nonperiodic case)
    1085       120127 :       CALL qs_efield_local_operator(qs_env, just_energy, calculate_forces)
    1086              : 
    1087              :       ! Right now we can compute the orbital derivative here, as it depends currently only on the available
    1088              :       ! Kohn-Sham matrix. This might change in the future, in which case more pieces might need to be assembled
    1089              :       ! from this routine, notice that this part of the calculation in not linear scaling
    1090              :       ! right now this operation is only non-trivial because of occupation numbers and the restricted keyword
    1091       120127 :       IF (qs_env%requires_mo_derivs .AND. .NOT. just_energy .AND. .NOT. qs_env%run_rtp) THEN
    1092        44075 :          CALL get_qs_env(qs_env, mo_derivs=mo_derivs)
    1093        44075 :          CPASSERT(nimages == 1)
    1094        44075 :          ksmat => ks_matrix(:, 1)
    1095        44075 :          CALL calc_mo_derivatives(qs_env, ksmat, mo_derivs)
    1096              :       END IF
    1097              : 
    1098              :       ! ADMM overlap forces
    1099       120127 :       IF (calculate_forces .AND. dft_control%do_admm) THEN
    1100          316 :          IF (dokp) THEN
    1101           30 :             CALL calc_admm_ovlp_forces_kp(qs_env)
    1102              :          ELSE
    1103          286 :             CALL calc_admm_ovlp_forces(qs_env)
    1104              :          END IF
    1105              :       END IF
    1106              : 
    1107              :       ! deal with low spin roks
    1108              :       CALL low_spin_roks(energy, qs_env, dft_control, do_hfx, just_energy, &
    1109       120127 :                          calculate_forces, auxbas_pw_pool)
    1110              : 
    1111              :       ! deal with sic on explicit orbitals
    1112              :       CALL sic_explicit_orbitals(energy, qs_env, dft_control, poisson_env, just_energy, &
    1113       120127 :                                  calculate_forces, auxbas_pw_pool)
    1114              : 
    1115              :       ! Periodic external field
    1116       120127 :       CALL qs_efield_berry_phase(qs_env, just_energy, calculate_forces)
    1117              : 
    1118              :       ! adds s2_restraint energy and orbital derivatives
    1119              :       CALL qs_ks_s2_restraint(dft_control, qs_env, matrix_s, &
    1120       120127 :                               energy, calculate_forces, just_energy)
    1121              : 
    1122       120127 :       IF (do_ppl) THEN
    1123              :          ! update core energy for grid based local pseudopotential
    1124           60 :          ecore_ppl = 0._dp
    1125          126 :          DO ispin = 1, nspins
    1126          126 :             ecore_ppl = ecore_ppl + pw_integral_ab(vppl_rspace, rho_r(ispin))
    1127              :          END DO
    1128           60 :          energy%core = energy%core + ecore_ppl
    1129              :       END IF
    1130              : 
    1131       120127 :       IF (lrigpw) THEN
    1132              :          ! update core energy for ppl_ri method
    1133          432 :          CALL get_qs_env(qs_env, lri_env=lri_env, lri_density=lri_density)
    1134          432 :          IF (lri_env%ppl_ri) THEN
    1135            8 :             ecore_ppl = 0._dp
    1136           16 :             DO ispin = 1, nspins
    1137            8 :                lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
    1138           16 :                CALL v_int_ppl_energy(qs_env, lri_v_int, ecore_ppl)
    1139              :             END DO
    1140            8 :             energy%core = energy%core + ecore_ppl
    1141              :          END IF
    1142              :       END IF
    1143              : 
    1144              :       ! Sum all energy terms to obtain the total energy
    1145              :       energy%total = energy%core_overlap + energy%core_self + energy%core_cneo + energy%core + &
    1146              :                      energy%hartree + energy%hartree_1c + energy%exc + energy%exc1 + energy%ex + &
    1147              :                      energy%dispersion + energy%gcp + energy%qmmm_el + energy%mulliken + &
    1148              :                      SUM(energy%ddapc_restraint) + energy%s2_restraint + &
    1149              :                      energy%dft_plus_u + energy%kTS + &
    1150              :                      energy%efield + energy%efield_core + energy%ee + &
    1151              :                      energy%ee_core + energy%exc_aux_fit + energy%image_charge + &
    1152       240358 :                      energy%sccs_pol + energy%cdft + energy%exc1_aux_fit
    1153              : 
    1154       120127 :       IF (dft_control%apply_embed_pot) energy%total = energy%total + energy%embed_corr
    1155              : 
    1156       120127 :       IF (native_skala_restore_exc) energy%total = native_skala_total_scf
    1157              : 
    1158       120127 :       IF (abnormal_value(energy%total)) &
    1159            0 :          CPABORT("KS energy is an abnormal value (NaN/Inf).")
    1160              : 
    1161              :       ! Print detailed energy
    1162       120127 :       IF (my_print) THEN
    1163       120105 :          CALL print_detailed_energy(qs_env, dft_control, input, energy, mulliken_order_p)
    1164              :       END IF
    1165              : 
    1166       120127 :       CALL timestop(handle)
    1167              : 
    1168       240254 :    END SUBROUTINE qs_ks_build_kohn_sham_matrix
    1169              : 
    1170              : ! **************************************************************************************************
    1171              : !> \brief ...
    1172              : !> \param rho_tot_gspace ...
    1173              : !> \param qs_env ...
    1174              : !> \param rho ...
    1175              : !> \param skip_nuclear_density ...
    1176              : ! **************************************************************************************************
    1177       123853 :    SUBROUTINE calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho, skip_nuclear_density)
    1178              :       TYPE(pw_c1d_gs_type), INTENT(INOUT)                :: rho_tot_gspace
    1179              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1180              :       TYPE(qs_rho_type), POINTER                         :: rho
    1181              :       LOGICAL, INTENT(IN), OPTIONAL                      :: skip_nuclear_density
    1182              : 
    1183              :       INTEGER                                            :: ispin
    1184              :       LOGICAL                                            :: my_skip
    1185              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1186       123853 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g
    1187              :       TYPE(pw_c1d_gs_type), POINTER                      :: rho0_s_gs, rho_core, rhoz_cneo_s_gs
    1188              :       TYPE(qs_charges_type), POINTER                     :: qs_charges
    1189              : 
    1190       123853 :       my_skip = .FALSE.
    1191          930 :       IF (PRESENT(skip_nuclear_density)) my_skip = skip_nuclear_density
    1192              : 
    1193       123853 :       CALL qs_rho_get(rho, rho_g=rho_g)
    1194       123853 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
    1195              : 
    1196       123853 :       IF (.NOT. my_skip) THEN
    1197       122933 :          NULLIFY (rho_core)
    1198       122933 :          CALL get_qs_env(qs_env=qs_env, rho_core=rho_core)
    1199       122933 :          IF (dft_control%qs_control%gapw) THEN
    1200        20696 :             NULLIFY (rho0_s_gs, rhoz_cneo_s_gs)
    1201        20696 :             CALL get_qs_env(qs_env=qs_env, rho0_s_gs=rho0_s_gs, rhoz_cneo_s_gs=rhoz_cneo_s_gs)
    1202        20696 :             CPASSERT(ASSOCIATED(rho0_s_gs))
    1203        20696 :             CALL pw_copy(rho0_s_gs, rho_tot_gspace)
    1204        20696 :             IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
    1205           48 :                CALL pw_axpy(rhoz_cneo_s_gs, rho_tot_gspace)
    1206              :             END IF
    1207        20696 :             IF (dft_control%qs_control%gapw_control%nopaw_as_gpw) THEN
    1208         1676 :                CALL pw_axpy(rho_core, rho_tot_gspace)
    1209              :             END IF
    1210              :          ELSE
    1211       102237 :             CALL pw_copy(rho_core, rho_tot_gspace)
    1212              :          END IF
    1213       269879 :          DO ispin = 1, dft_control%nspins
    1214       269879 :             CALL pw_axpy(rho_g(ispin), rho_tot_gspace)
    1215              :          END DO
    1216       122933 :          CALL get_qs_env(qs_env=qs_env, qs_charges=qs_charges)
    1217       122933 :          qs_charges%total_rho_gspace = pw_integrate_function(rho_tot_gspace, isign=-1)
    1218              :       ELSE
    1219         1844 :          DO ispin = 1, dft_control%nspins
    1220         1844 :             CALL pw_axpy(rho_g(ispin), rho_tot_gspace)
    1221              :          END DO
    1222              :       END IF
    1223              : 
    1224       123853 :    END SUBROUTINE calc_rho_tot_gspace
    1225              : 
    1226              : ! **************************************************************************************************
    1227              : !> \brief compute MO derivatives
    1228              : !> \param qs_env the qs_env to update
    1229              : !> \param ks_matrix ...
    1230              : !> \param mo_derivs ...
    1231              : !> \par History
    1232              : !>      01.2014 created, transferred from qs_ks_build_kohn_sham_matrix in
    1233              : !>      separate subroutine
    1234              : !> \author Dorothea Golze
    1235              : ! **************************************************************************************************
    1236        44075 :    SUBROUTINE calc_mo_derivatives(qs_env, ks_matrix, mo_derivs)
    1237              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1238              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ks_matrix, mo_derivs
    1239              : 
    1240              :       INTEGER                                            :: ispin
    1241              :       LOGICAL                                            :: uniform_occupation
    1242        44075 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: occupation_numbers
    1243              :       TYPE(cp_fm_type), POINTER                          :: mo_coeff
    1244              :       TYPE(dbcsr_type)                                   :: mo_derivs2_tmp1, mo_derivs2_tmp2
    1245              :       TYPE(dbcsr_type), POINTER                          :: mo_coeff_b
    1246              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1247        44075 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mo_array
    1248              : 
    1249        44075 :       NULLIFY (dft_control, mo_array, mo_coeff, mo_coeff_b, occupation_numbers)
    1250              : 
    1251              :       CALL get_qs_env(qs_env, &
    1252              :                       dft_control=dft_control, &
    1253        44075 :                       mos=mo_array)
    1254              : 
    1255        96123 :       DO ispin = 1, SIZE(mo_derivs)
    1256              : 
    1257              :          CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff=mo_coeff, &
    1258        52048 :                          mo_coeff_b=mo_coeff_b, occupation_numbers=occupation_numbers)
    1259              :          CALL dbcsr_multiply('n', 'n', 1.0_dp, ks_matrix(ispin)%matrix, mo_coeff_b, &
    1260        52048 :                              0.0_dp, mo_derivs(ispin)%matrix)
    1261              : 
    1262        96123 :          IF (dft_control%restricted) THEN
    1263              :             ! only the first mo_set are actual variables, but we still need both
    1264          636 :             CPASSERT(ispin == 1)
    1265          636 :             CPASSERT(SIZE(mo_array) == 2)
    1266              :             ! use a temporary array with the same size as the first spin for the second spin
    1267              : 
    1268              :             ! uniform_occupation is needed for this case, otherwise we can not
    1269              :             ! reconstruct things in ot, since we irreversibly sum
    1270          636 :             CALL get_mo_set(mo_set=mo_array(1), uniform_occupation=uniform_occupation)
    1271          636 :             CPASSERT(uniform_occupation)
    1272          636 :             CALL get_mo_set(mo_set=mo_array(2), uniform_occupation=uniform_occupation)
    1273          636 :             CPASSERT(uniform_occupation)
    1274              : 
    1275              :             ! The beta-spin might have fewer orbitals than alpa-spin...
    1276              :             ! create temporary matrices with beta_nmo columns
    1277          636 :             CALL get_mo_set(mo_set=mo_array(2), mo_coeff_b=mo_coeff_b)
    1278          636 :             CALL dbcsr_create(mo_derivs2_tmp1, template=mo_coeff_b)
    1279              : 
    1280              :             ! calculate beta derivatives
    1281          636 :             CALL dbcsr_multiply('n', 'n', 1.0_dp, ks_matrix(2)%matrix, mo_coeff_b, 0.0_dp, mo_derivs2_tmp1)
    1282              : 
    1283              :             ! create larger matrix with alpha_nmo columns
    1284          636 :             CALL dbcsr_create(mo_derivs2_tmp2, template=mo_derivs(1)%matrix)
    1285          636 :             CALL dbcsr_set(mo_derivs2_tmp2, 0.0_dp)
    1286              : 
    1287              :             ! copy into larger matrix, fills the first beta_nmo columns
    1288              :             CALL dbcsr_copy_columns_hack(mo_derivs2_tmp2, mo_derivs2_tmp1, &
    1289              :                                          mo_array(2)%nmo, 1, 1, &
    1290              :                                          para_env=mo_array(1)%mo_coeff%matrix_struct%para_env, &
    1291          636 :                                          blacs_env=mo_array(1)%mo_coeff%matrix_struct%context)
    1292              : 
    1293              :             ! add beta contribution to alpa mo_derivs
    1294          636 :             CALL dbcsr_add(mo_derivs(1)%matrix, mo_derivs2_tmp2, 1.0_dp, 1.0_dp)
    1295          636 :             CALL dbcsr_release(mo_derivs2_tmp1)
    1296          636 :             CALL dbcsr_release(mo_derivs2_tmp2)
    1297              :          END IF
    1298              :       END DO
    1299              : 
    1300        44075 :       IF (dft_control%do_admm_mo) THEN
    1301         6390 :          CALL calc_admm_mo_derivatives(qs_env, mo_derivs)
    1302              :       END IF
    1303              : 
    1304        44075 :    END SUBROUTINE calc_mo_derivatives
    1305              : 
    1306              : ! **************************************************************************************************
    1307              : !> \brief updates the Kohn Sham matrix of the given qs_env (facility method)
    1308              : !> \param qs_env the qs_env to update
    1309              : !> \param calculate_forces if true calculate the quantities needed
    1310              : !>        to calculate the forces. Defaults to false.
    1311              : !> \param just_energy if true updates the energies but not the
    1312              : !>        ks matrix. Defaults to false
    1313              : !> \param print_active ...
    1314              : !> \par History
    1315              : !>      4.2002 created [fawzi]
    1316              : !>      8.2014 kpoints [JGH]
    1317              : !>     10.2014 refractored [Ole Schuett]
    1318              : !> \author Fawzi Mohamed
    1319              : ! **************************************************************************************************
    1320       259414 :    SUBROUTINE qs_ks_update_qs_env(qs_env, calculate_forces, just_energy, &
    1321              :                                   print_active)
    1322              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1323              :       LOGICAL, INTENT(IN), OPTIONAL                      :: calculate_forces, just_energy, &
    1324              :                                                             print_active
    1325              : 
    1326              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_ks_update_qs_env'
    1327              : 
    1328              :       INTEGER                                            :: handle, unit_nr
    1329              :       LOGICAL                                            :: c_forces, do_rebuild, energy_only, &
    1330              :                                                             forces_up_to_date, potential_changed, &
    1331              :                                                             rho_changed, s_mstruct_changed
    1332              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1333              : 
    1334       259414 :       NULLIFY (ks_env)
    1335       259414 :       unit_nr = cp_logger_get_default_io_unit()
    1336              : 
    1337       259414 :       c_forces = .FALSE.
    1338       259414 :       energy_only = .FALSE.
    1339       259414 :       IF (PRESENT(just_energy)) energy_only = just_energy
    1340       259414 :       IF (PRESENT(calculate_forces)) c_forces = calculate_forces
    1341              : 
    1342       259414 :       IF (c_forces) THEN
    1343        10427 :          CALL timeset(routineN//'_forces', handle)
    1344              :       ELSE
    1345       248987 :          CALL timeset(routineN, handle)
    1346              :       END IF
    1347              : 
    1348       259414 :       CPASSERT(ASSOCIATED(qs_env))
    1349              : 
    1350              :       CALL get_qs_env(qs_env, &
    1351              :                       ks_env=ks_env, &
    1352              :                       rho_changed=rho_changed, &
    1353              :                       s_mstruct_changed=s_mstruct_changed, &
    1354              :                       potential_changed=potential_changed, &
    1355       259414 :                       forces_up_to_date=forces_up_to_date)
    1356              : 
    1357       259414 :       do_rebuild = .FALSE.
    1358       259414 :       do_rebuild = do_rebuild .OR. rho_changed
    1359         8547 :       do_rebuild = do_rebuild .OR. s_mstruct_changed
    1360         8547 :       do_rebuild = do_rebuild .OR. potential_changed
    1361         8547 :       do_rebuild = do_rebuild .OR. (c_forces .AND. .NOT. forces_up_to_date)
    1362              : 
    1363              :       IF (do_rebuild) THEN
    1364       251249 :          CALL evaluate_core_matrix_traces(qs_env)
    1365              : 
    1366              :          ! the ks matrix will be rebuilt so this is fine now
    1367       251249 :          CALL set_ks_env(ks_env, potential_changed=.FALSE.)
    1368              : 
    1369              :          CALL rebuild_ks_matrix(qs_env, &
    1370              :                                 calculate_forces=c_forces, &
    1371              :                                 just_energy=energy_only, &
    1372       251249 :                                 print_active=print_active)
    1373              : 
    1374       251249 :          IF (.NOT. energy_only) THEN
    1375              :             CALL set_ks_env(ks_env, &
    1376              :                             rho_changed=.FALSE., &
    1377              :                             s_mstruct_changed=.FALSE., &
    1378       462579 :                             forces_up_to_date=forces_up_to_date .OR. c_forces)
    1379              :          END IF
    1380              :       END IF
    1381              : 
    1382       259414 :       CALL timestop(handle)
    1383              : 
    1384       259414 :    END SUBROUTINE qs_ks_update_qs_env
    1385              : 
    1386              : ! **************************************************************************************************
    1387              : !> \brief Calculates the traces of the core matrices and the density matrix.
    1388              : !> \param qs_env ...
    1389              : !> \param rho_ao_ext ...
    1390              : !> \author Ole Schuett
    1391              : ! **************************************************************************************************
    1392       274557 :    SUBROUTINE evaluate_core_matrix_traces(qs_env, rho_ao_ext)
    1393              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1394              :       TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
    1395              :          POINTER                                         :: rho_ao_ext
    1396              : 
    1397              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'evaluate_core_matrix_traces'
    1398              : 
    1399              :       INTEGER                                            :: handle
    1400              :       REAL(KIND=dp)                                      :: energy_core_im
    1401       274557 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrixkp_h, matrixkp_t, rho_ao_kp
    1402              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1403              :       TYPE(qs_energy_type), POINTER                      :: energy
    1404              :       TYPE(qs_rho_type), POINTER                         :: rho
    1405              : 
    1406       274557 :       CALL timeset(routineN, handle)
    1407       274557 :       NULLIFY (energy, rho, dft_control, rho_ao_kp, matrixkp_t, matrixkp_h)
    1408              : 
    1409              :       CALL get_qs_env(qs_env, &
    1410              :                       rho=rho, &
    1411              :                       energy=energy, &
    1412              :                       dft_control=dft_control, &
    1413              :                       kinetic_kp=matrixkp_t, &
    1414       274557 :                       matrix_h_kp=matrixkp_h)
    1415              : 
    1416       274557 :       IF (PRESENT(rho_ao_ext)) THEN
    1417        23232 :          rho_ao_kp => rho_ao_ext
    1418              :       ELSE
    1419       251325 :          CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
    1420              :       END IF
    1421              : 
    1422       274557 :       CALL calculate_ptrace(matrixkp_h, rho_ao_kp, energy%core, dft_control%nspins)
    1423              : 
    1424              :       ! Add the imaginary part in the RTP case
    1425       274557 :       IF (qs_env%run_rtp) THEN
    1426         3220 :          IF (dft_control%rtp_control%velocity_gauge) THEN
    1427          150 :             CALL get_qs_env(qs_env, matrix_h_im_kp=matrixkp_h)
    1428          150 :             CALL qs_rho_get(rho, rho_ao_im_kp=rho_ao_kp)
    1429          150 :             CALL calculate_ptrace(matrixkp_h, rho_ao_kp, energy_core_im, dft_control%nspins)
    1430          150 :             energy%core = energy%core - energy_core_im
    1431              :          END IF
    1432              :       END IF
    1433              : 
    1434              :       ! kinetic energy
    1435       274557 :       IF (ASSOCIATED(matrixkp_t)) &
    1436       119903 :          CALL calculate_ptrace(matrixkp_t, rho_ao_kp, energy%kinetic, dft_control%nspins)
    1437              : 
    1438       274557 :       CALL timestop(handle)
    1439       274557 :    END SUBROUTINE evaluate_core_matrix_traces
    1440              : 
    1441              : ! **************************************************************************************************
    1442              : !> \brief Constructs a new Khon-Sham matrix
    1443              : !> \param qs_env ...
    1444              : !> \param calculate_forces ...
    1445              : !> \param just_energy ...
    1446              : !> \param print_active ...
    1447              : !> \author Ole Schuett
    1448              : ! **************************************************************************************************
    1449       251269 :    SUBROUTINE rebuild_ks_matrix(qs_env, calculate_forces, just_energy, print_active)
    1450              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1451              :       LOGICAL, INTENT(IN)                                :: calculate_forces, just_energy
    1452              :       LOGICAL, INTENT(IN), OPTIONAL                      :: print_active
    1453              : 
    1454              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'rebuild_ks_matrix'
    1455              : 
    1456              :       INTEGER                                            :: handle
    1457              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1458              : 
    1459       251269 :       CALL timeset(routineN, handle)
    1460       251269 :       NULLIFY (dft_control)
    1461              : 
    1462       251269 :       CALL get_qs_env(qs_env, dft_control=dft_control)
    1463              : 
    1464       251269 :       IF (dft_control%qs_control%semi_empirical) THEN
    1465              :          CALL build_se_fock_matrix(qs_env, &
    1466              :                                    calculate_forces=calculate_forces, &
    1467        41226 :                                    just_energy=just_energy)
    1468              : 
    1469       210043 :       ELSEIF (dft_control%qs_control%dftb) THEN
    1470              :          CALL build_dftb_ks_matrix(qs_env, &
    1471              :                                    calculate_forces=calculate_forces, &
    1472        29638 :                                    just_energy=just_energy)
    1473              : 
    1474       180405 :       ELSEIF (dft_control%qs_control%xtb) THEN
    1475        60490 :          IF (dft_control%qs_control%xtb_control%do_tblite) THEN
    1476              :             CALL build_tblite_ks_matrix(qs_env, &
    1477              :                                         calculate_forces=calculate_forces, &
    1478        25632 :                                         just_energy=just_energy)
    1479              :          ELSE
    1480              :             CALL build_xtb_ks_matrix(qs_env, &
    1481              :                                      calculate_forces=calculate_forces, &
    1482        34858 :                                      just_energy=just_energy)
    1483              :          END IF
    1484              :       ELSE
    1485              :          CALL qs_ks_build_kohn_sham_matrix(qs_env, &
    1486              :                                            calculate_forces=calculate_forces, &
    1487              :                                            just_energy=just_energy, &
    1488       119915 :                                            print_active=print_active)
    1489              :       END IF
    1490              : 
    1491       251269 :       CALL timestop(handle)
    1492              : 
    1493       251269 :    END SUBROUTINE rebuild_ks_matrix
    1494              : 
    1495              : ! **************************************************************************************************
    1496              : !> \brief Allocate ks_matrix if necessary, take current overlap matrix as template
    1497              : !> \param qs_env ...
    1498              : !> \param is_complex ...
    1499              : !> \par History
    1500              : !>    refactoring 04.03.2011 [MI]
    1501              : !> \author
    1502              : ! **************************************************************************************************
    1503              : 
    1504        27614 :    SUBROUTINE qs_ks_allocate_basics(qs_env, is_complex)
    1505              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1506              :       LOGICAL, INTENT(in)                                :: is_complex
    1507              : 
    1508              :       CHARACTER(LEN=default_string_length)               :: headline
    1509              :       INTEGER                                            :: ic, ispin, nimages, nspins
    1510              :       LOGICAL                                            :: do_kpoints
    1511        27614 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_s_kp, matrixkp_im_ks, matrixkp_ks
    1512              :       TYPE(dbcsr_type), POINTER                          :: refmatrix
    1513              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1514              :       TYPE(kpoint_type), POINTER                         :: kpoints
    1515              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1516        27614 :          POINTER                                         :: sab_orb
    1517              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1518              : 
    1519        27614 :       NULLIFY (dft_control, ks_env, matrix_s_kp, sab_orb, matrixkp_ks, refmatrix, matrixkp_im_ks, kpoints)
    1520              : 
    1521              :       CALL get_qs_env(qs_env, &
    1522              :                       dft_control=dft_control, &
    1523              :                       matrix_s_kp=matrix_s_kp, &
    1524              :                       ks_env=ks_env, &
    1525              :                       kpoints=kpoints, &
    1526              :                       do_kpoints=do_kpoints, &
    1527              :                       matrix_ks_kp=matrixkp_ks, &
    1528        27614 :                       matrix_ks_im_kp=matrixkp_im_ks)
    1529              : 
    1530        27614 :       IF (do_kpoints) THEN
    1531         3150 :          CALL get_kpoint_info(kpoints, sab_nl=sab_orb)
    1532              :       ELSE
    1533        24464 :          CALL get_qs_env(qs_env, sab_orb=sab_orb)
    1534              :       END IF
    1535              : 
    1536        27614 :       nspins = dft_control%nspins
    1537        27614 :       nimages = dft_control%nimages
    1538              : 
    1539        27614 :       IF (.NOT. ASSOCIATED(matrixkp_ks)) THEN
    1540        27572 :          CALL dbcsr_allocate_matrix_set(matrixkp_ks, nspins, nimages)
    1541        27572 :          refmatrix => matrix_s_kp(1, 1)%matrix
    1542        58634 :          DO ispin = 1, nspins
    1543       283036 :             DO ic = 1, nimages
    1544       224402 :                IF (nspins > 1) THEN
    1545        28048 :                   IF (ispin == 1) THEN
    1546        14024 :                      headline = "KOHN-SHAM MATRIX FOR ALPHA SPIN"
    1547              :                   ELSE
    1548        14024 :                      headline = "KOHN-SHAM MATRIX FOR BETA SPIN"
    1549              :                   END IF
    1550              :                ELSE
    1551       196354 :                   headline = "KOHN-SHAM MATRIX"
    1552              :                END IF
    1553       224402 :                ALLOCATE (matrixkp_ks(ispin, ic)%matrix)
    1554              :                CALL dbcsr_create(matrix=matrixkp_ks(ispin, ic)%matrix, template=refmatrix, &
    1555       224402 :                                  name=TRIM(headline), matrix_type=dbcsr_type_symmetric)
    1556       224402 :                CALL cp_dbcsr_alloc_block_from_nbl(matrixkp_ks(ispin, ic)%matrix, sab_orb)
    1557       255464 :                CALL dbcsr_set(matrixkp_ks(ispin, ic)%matrix, 0.0_dp)
    1558              :             END DO
    1559              :          END DO
    1560        27572 :          CALL set_ks_env(ks_env, matrix_ks_kp=matrixkp_ks)
    1561              :       END IF
    1562              : 
    1563        27614 :       IF (is_complex) THEN
    1564          144 :          IF (.NOT. ASSOCIATED(matrixkp_im_ks)) THEN
    1565          144 :             CPASSERT(nspins == SIZE(matrixkp_ks, 1))
    1566          144 :             CPASSERT(nimages == SIZE(matrixkp_ks, 2))
    1567          144 :             CALL dbcsr_allocate_matrix_set(matrixkp_im_ks, nspins, nimages)
    1568          306 :             DO ispin = 1, nspins
    1569          468 :                DO ic = 1, nimages
    1570          162 :                   IF (nspins > 1) THEN
    1571           36 :                      IF (ispin == 1) THEN
    1572           18 :                         headline = "IMAGINARY KOHN-SHAM MATRIX FOR ALPHA SPIN"
    1573              :                      ELSE
    1574           18 :                         headline = "IMAGINARY KOHN-SHAM MATRIX FOR BETA SPIN"
    1575              :                      END IF
    1576              :                   ELSE
    1577          126 :                      headline = "IMAGINARY KOHN-SHAM MATRIX"
    1578              :                   END IF
    1579          162 :                   ALLOCATE (matrixkp_im_ks(ispin, ic)%matrix)
    1580          162 :                   refmatrix => matrixkp_ks(ispin, ic)%matrix  ! base on real part, but anti-symmetric
    1581              :                   CALL dbcsr_create(matrix=matrixkp_im_ks(ispin, ic)%matrix, template=refmatrix, &
    1582          162 :                                     name=TRIM(headline), matrix_type=dbcsr_type_antisymmetric)
    1583          162 :                   CALL cp_dbcsr_alloc_block_from_nbl(matrixkp_im_ks(ispin, ic)%matrix, sab_orb)
    1584          324 :                   CALL dbcsr_set(matrixkp_im_ks(ispin, ic)%matrix, 0.0_dp)
    1585              :                END DO
    1586              :             END DO
    1587          144 :             CALL set_ks_env(ks_env, matrix_ks_im_kp=matrixkp_im_ks)
    1588              :          END IF
    1589              :       END IF
    1590              : 
    1591        27614 :    END SUBROUTINE qs_ks_allocate_basics
    1592              : 
    1593              : END MODULE qs_ks_methods
        

Generated by: LCOV version 2.0-1