LCOV - code coverage report
Current view: top level - src - qs_energy_utils.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 92.8 % 181 168
Test Date: 2025-07-25 12:55:17 Functions: 100.0 % 3 3

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Utility subroutine for qs energy calculation
      10              : !> \par History
      11              : !>      none
      12              : !> \author MK (29.10.2002)
      13              : ! **************************************************************************************************
      14              : MODULE qs_energy_utils
      15              :    USE atomic_kind_types,               ONLY: atomic_kind_type
      16              :    USE atprop_types,                    ONLY: atprop_array_add,&
      17              :                                               atprop_array_init,&
      18              :                                               atprop_type
      19              :    USE cp_control_types,                ONLY: dft_control_type
      20              :    USE cp_control_utils,                ONLY: read_ddapc_section
      21              :    USE cp_dbcsr_api,                    ONLY: dbcsr_copy,&
      22              :                                               dbcsr_create,&
      23              :                                               dbcsr_p_type,&
      24              :                                               dbcsr_release,&
      25              :                                               dbcsr_set
      26              :    USE et_coupling,                     ONLY: calc_et_coupling
      27              :    USE et_coupling_proj,                ONLY: calc_et_coupling_proj
      28              :    USE hartree_local_methods,           ONLY: Vh_1c_gg_integrals
      29              :    USE hartree_local_types,             ONLY: ecoul_1center_type
      30              :    USE input_section_types,             ONLY: section_vals_get,&
      31              :                                               section_vals_get_subs_vals,&
      32              :                                               section_vals_type
      33              :    USE kinds,                           ONLY: dp
      34              :    USE message_passing,                 ONLY: mp_para_env_type
      35              :    USE mulliken,                        ONLY: atom_trace
      36              :    USE post_scf_bandstructure_methods,  ONLY: post_scf_bandstructure
      37              :    USE pw_env_types,                    ONLY: pw_env_get,&
      38              :                                               pw_env_type
      39              :    USE pw_methods,                      ONLY: pw_axpy,&
      40              :                                               pw_scale
      41              :    USE pw_pool_types,                   ONLY: pw_pool_type
      42              :    USE pw_types,                        ONLY: pw_r3d_rs_type
      43              :    USE qs_core_hamiltonian,             ONLY: core_matrices
      44              :    USE qs_dispersion_types,             ONLY: qs_dispersion_type
      45              :    USE qs_energy_types,                 ONLY: qs_energy_type
      46              :    USE qs_environment_types,            ONLY: get_qs_env,&
      47              :                                               qs_environment_type
      48              :    USE qs_integrate_potential,          ONLY: integrate_v_core_rspace,&
      49              :                                               integrate_v_rspace
      50              :    USE qs_kind_types,                   ONLY: qs_kind_type
      51              :    USE qs_ks_atom,                      ONLY: update_ks_atom
      52              :    USE qs_ks_methods,                   ONLY: qs_ks_update_qs_env
      53              :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      54              :    USE qs_linres_module,                ONLY: linres_calculation_low
      55              :    USE qs_local_rho_types,              ONLY: local_rho_type
      56              :    USE qs_rho0_ggrid,                   ONLY: integrate_vhg0_rspace
      57              :    USE qs_rho_atom_types,               ONLY: rho_atom_type,&
      58              :                                               zero_rho_atom_integrals
      59              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      60              :                                               qs_rho_type
      61              :    USE qs_scf,                          ONLY: scf
      62              :    USE qs_tddfpt2_methods,              ONLY: tddfpt
      63              :    USE qs_vxc,                          ONLY: qs_xc_density
      64              :    USE qs_vxc_atom,                     ONLY: calculate_vxc_atom
      65              :    USE rixs_methods,                    ONLY: rixs
      66              :    USE tip_scan_methods,                ONLY: tip_scanning
      67              :    USE xas_methods,                     ONLY: xas
      68              :    USE xas_tdp_methods,                 ONLY: xas_tdp
      69              :    USE xc_derivatives,                  ONLY: xc_functionals_get_needs
      70              :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      71              : #include "./base/base_uses.f90"
      72              : 
      73              :    IMPLICIT NONE
      74              : 
      75              :    PRIVATE
      76              : 
      77              : ! *** Global parameters ***
      78              : 
      79              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_energy_utils'
      80              : 
      81              :    PUBLIC :: qs_energies_properties
      82              : 
      83              : CONTAINS
      84              : 
      85              : ! **************************************************************************************************
      86              : !> \brief Refactoring of qs_energies_scf. Moves computation of properties
      87              : !>        into separate subroutine
      88              : !> \param qs_env ...
      89              : !> \param calc_forces ...
      90              : !> \par History
      91              : !>      05.2013 created [Florian Schiffmann]
      92              : ! **************************************************************************************************
      93              : 
      94        86804 :    SUBROUTINE qs_energies_properties(qs_env, calc_forces)
      95              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      96              :       LOGICAL, INTENT(IN)                                :: calc_forces
      97              : 
      98              :       CHARACTER(len=*), PARAMETER :: routineN = 'qs_energies_properties'
      99              : 
     100              :       INTEGER                                            :: handle, natom
     101              :       LOGICAL                                            :: do_et, do_et_proj, &
     102              :                                                             do_post_scf_bandstructure, do_tip_scan
     103              :       REAL(KIND=dp)                                      :: ekts
     104              :       TYPE(atprop_type), POINTER                         :: atprop
     105              :       TYPE(dft_control_type), POINTER                    :: dft_control
     106              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     107              :       TYPE(pw_env_type), POINTER                         :: pw_env
     108              :       TYPE(pw_r3d_rs_type), POINTER                      :: v_hartree_rspace
     109              :       TYPE(qs_energy_type), POINTER                      :: energy
     110              :       TYPE(section_vals_type), POINTER                   :: input, post_scf_bands_section, &
     111              :                                                             proj_section, rest_b_section, &
     112              :                                                             tip_scan_section
     113              : 
     114        21701 :       NULLIFY (atprop, energy, pw_env)
     115        21701 :       CALL timeset(routineN, handle)
     116              : 
     117              :       ! atomic energies using Mulliken partition
     118              :       CALL get_qs_env(qs_env, &
     119              :                       dft_control=dft_control, &
     120              :                       input=input, &
     121              :                       atprop=atprop, &
     122              :                       energy=energy, &
     123              :                       v_hartree_rspace=v_hartree_rspace, &
     124              :                       para_env=para_env, &
     125        21701 :                       pw_env=pw_env)
     126        21701 :       IF (atprop%energy) THEN
     127          140 :          CALL qs_energies_mulliken(qs_env)
     128          140 :          CALL get_qs_env(qs_env, natom=natom)
     129              :          IF (.NOT. dft_control%qs_control%semi_empirical .AND. &
     130          140 :              .NOT. dft_control%qs_control%xtb .AND. &
     131              :              .NOT. dft_control%qs_control%dftb) THEN
     132              :             ! Nuclear charge correction
     133           36 :             CALL integrate_v_core_rspace(v_hartree_rspace, qs_env)
     134           36 :             IF (.NOT. ASSOCIATED(atprop%ateb)) THEN
     135            8 :                CALL atprop_array_init(atprop%ateb, natom)
     136              :             END IF
     137              :             ! Kohn-Sham Functional corrections
     138           36 :             CALL ks_xc_correction(qs_env)
     139              :          END IF
     140          140 :          CALL atprop_array_add(atprop%atener, atprop%ateb)
     141          140 :          CALL atprop_array_add(atprop%atener, atprop%ateself)
     142          140 :          CALL atprop_array_add(atprop%atener, atprop%atexc)
     143          140 :          CALL atprop_array_add(atprop%atener, atprop%atecoul)
     144          140 :          CALL atprop_array_add(atprop%atener, atprop%atevdw)
     145          140 :          CALL atprop_array_add(atprop%atener, atprop%ategcp)
     146          140 :          CALL atprop_array_add(atprop%atener, atprop%atecc)
     147          140 :          CALL atprop_array_add(atprop%atener, atprop%ate1c)
     148              :          ! entropic energy
     149          140 :          ekts = energy%kts/REAL(natom, KIND=dp)/REAL(para_env%num_pe, KIND=dp)
     150         7504 :          atprop%atener(:) = atprop%atener(:) + ekts
     151              :       END IF
     152              : 
     153              :       ! ET coupling - projection-operator approach
     154        21701 :       NULLIFY (proj_section)
     155              :       proj_section => &
     156        21701 :          section_vals_get_subs_vals(input, "PROPERTIES%ET_COUPLING%PROJECTION")
     157        21701 :       CALL section_vals_get(proj_section, explicit=do_et_proj)
     158        21701 :       IF (do_et_proj) THEN
     159           10 :          CALL calc_et_coupling_proj(qs_env)
     160              :       END IF
     161              : 
     162              :       ! **********  Calculate the electron transfer coupling elements********
     163        21701 :       do_et = .FALSE.
     164        21701 :       do_et = dft_control%qs_control%et_coupling_calc
     165        21701 :       IF (do_et) THEN
     166            0 :          qs_env%et_coupling%energy = energy%total
     167            0 :          qs_env%et_coupling%keep_matrix = .TRUE.
     168            0 :          qs_env%et_coupling%first_run = .TRUE.
     169            0 :          CALL qs_ks_update_qs_env(qs_env, calculate_forces=.FALSE., just_energy=.TRUE.)
     170            0 :          qs_env%et_coupling%first_run = .FALSE.
     171            0 :          IF (dft_control%qs_control%ddapc_restraint) THEN
     172            0 :             rest_b_section => section_vals_get_subs_vals(input, "PROPERTIES%ET_COUPLING%DDAPC_RESTRAINT_B")
     173              :             CALL read_ddapc_section(qs_control=dft_control%qs_control, &
     174            0 :                                     ddapc_restraint_section=rest_b_section)
     175              :          END IF
     176            0 :          CALL scf(qs_env=qs_env)
     177            0 :          qs_env%et_coupling%keep_matrix = .TRUE.
     178              : 
     179            0 :          CALL qs_ks_update_qs_env(qs_env, calculate_forces=.FALSE., just_energy=.TRUE.)
     180            0 :          CALL calc_et_coupling(qs_env)
     181              :       END IF
     182              : 
     183              :       !Properties
     184              : 
     185        21701 :       IF (dft_control%do_xas_calculation) THEN
     186           42 :          CALL xas(qs_env, dft_control)
     187              :       END IF
     188              : 
     189        21701 :       IF (dft_control%do_xas_tdp_calculation) THEN
     190           50 :          CALL xas_tdp(qs_env)
     191              :       END IF
     192              : 
     193              :       ! Compute Linear Response properties as post-scf
     194        21701 :       IF (.NOT. qs_env%linres_run) THEN
     195        21201 :          CALL linres_calculation_low(qs_env)
     196              :       END IF
     197              : 
     198        21701 :       IF (dft_control%tddfpt2_control%enabled) THEN
     199         1066 :          CALL tddfpt(qs_env, calc_forces)
     200              :       END IF
     201              : 
     202              :       ! stand-alone RIXS, does not depend on previous xas_tdp and/or tddfpt2 calculations
     203        21701 :       IF (qs_env%do_rixs) CALL rixs(qs_env)
     204              : 
     205              :       ! post-SCF bandstructure calculation from higher level methods
     206        21701 :       NULLIFY (post_scf_bands_section)
     207        21701 :       post_scf_bands_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%BANDSTRUCTURE")
     208        21701 :       CALL section_vals_get(post_scf_bands_section, explicit=do_post_scf_bandstructure)
     209        21701 :       IF (do_post_scf_bandstructure) THEN
     210           28 :          CALL post_scf_bandstructure(qs_env, post_scf_bands_section)
     211              :       END IF
     212              : 
     213              :       ! tip scan
     214        21701 :       NULLIFY (tip_scan_section)
     215        21701 :       tip_scan_section => section_vals_get_subs_vals(input, "PROPERTIES%TIP_SCAN")
     216        21701 :       CALL section_vals_get(tip_scan_section, explicit=do_tip_scan)
     217        21701 :       IF (do_tip_scan) THEN
     218            0 :          CALL tip_scanning(qs_env, tip_scan_section)
     219              :       END IF
     220              : 
     221        21701 :       CALL timestop(handle)
     222              : 
     223        21701 :    END SUBROUTINE qs_energies_properties
     224              : 
     225              : ! **************************************************************************************************
     226              : !> \brief   Use a simple Mulliken-like energy decomposition
     227              : !> \param qs_env ...
     228              : !> \date    07.2011
     229              : !> \author  JHU
     230              : !> \version 1.0
     231              : ! **************************************************************************************************
     232          140 :    SUBROUTINE qs_energies_mulliken(qs_env)
     233              : 
     234              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     235              : 
     236              :       INTEGER                                            :: ispin, natom, nspin
     237          140 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: atcore
     238              :       TYPE(atprop_type), POINTER                         :: atprop
     239              :       TYPE(dbcsr_p_type), ALLOCATABLE, DIMENSION(:), &
     240          140 :          TARGET                                          :: core_mat
     241          140 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_h, matrix_ks, rho_ao
     242          140 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: math, matp
     243              :       TYPE(dft_control_type), POINTER                    :: dft_control
     244              :       TYPE(qs_rho_type), POINTER                         :: rho
     245              : 
     246          140 :       CALL get_qs_env(qs_env=qs_env, atprop=atprop)
     247          140 :       IF (atprop%energy) THEN
     248          140 :          CALL get_qs_env(qs_env=qs_env, matrix_ks=matrix_ks, matrix_h=matrix_h, rho=rho)
     249          140 :          CALL qs_rho_get(rho, rho_ao=rho_ao)
     250              :          ! E = 0.5*Tr(H*P+F*P)
     251         7504 :          atprop%atener = 0._dp
     252          140 :          nspin = SIZE(rho_ao)
     253          284 :          DO ispin = 1, nspin
     254              :             CALL atom_trace(matrix_h(1)%matrix, rho_ao(ispin)%matrix, &
     255          144 :                             0.5_dp, atprop%atener)
     256              :             CALL atom_trace(matrix_ks(ispin)%matrix, rho_ao(ispin)%matrix, &
     257          284 :                             0.5_dp, atprop%atener)
     258              :          END DO
     259              :          !
     260          140 :          CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
     261              :          IF (.NOT. dft_control%qs_control%semi_empirical .AND. &
     262          140 :              .NOT. dft_control%qs_control%xtb .AND. &
     263              :              .NOT. dft_control%qs_control%dftb) THEN
     264           36 :             CALL get_qs_env(qs_env=qs_env, natom=natom)
     265          108 :             ALLOCATE (atcore(natom))
     266          160 :             atcore = 0.0_dp
     267          108 :             ALLOCATE (core_mat(1))
     268           36 :             ALLOCATE (core_mat(1)%matrix)
     269           36 :             CALL dbcsr_create(core_mat(1)%matrix, template=matrix_h(1)%matrix)
     270           36 :             CALL dbcsr_copy(core_mat(1)%matrix, matrix_h(1)%matrix)
     271           36 :             CALL dbcsr_set(core_mat(1)%matrix, 0.0_dp)
     272           36 :             math(1:1, 1:1) => core_mat(1:1)
     273           36 :             matp(1:nspin, 1:1) => rho_ao(1:nspin)
     274           36 :             CALL core_matrices(qs_env, math, matp, .FALSE., 0, atcore=atcore)
     275          160 :             atprop%atener = atprop%atener + 0.5_dp*atcore
     276           76 :             DO ispin = 1, nspin
     277              :                CALL atom_trace(core_mat(1)%matrix, rho_ao(ispin)%matrix, &
     278           76 :                                -0.5_dp, atprop%atener)
     279              :             END DO
     280           36 :             DEALLOCATE (atcore)
     281           36 :             CALL dbcsr_release(core_mat(1)%matrix)
     282           36 :             DEALLOCATE (core_mat(1)%matrix)
     283           36 :             DEALLOCATE (core_mat)
     284              :          END IF
     285              :       END IF
     286              : 
     287          280 :    END SUBROUTINE qs_energies_mulliken
     288              : 
     289              : ! **************************************************************************************************
     290              : !> \brief ...
     291              : !> \param qs_env ...
     292              : ! **************************************************************************************************
     293           36 :    SUBROUTINE ks_xc_correction(qs_env)
     294              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     295              : 
     296              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ks_xc_correction'
     297              : 
     298              :       INTEGER                                            :: handle, iatom, ispin, natom, nspins
     299              :       LOGICAL                                            :: gapw, gapw_xc
     300              :       REAL(KIND=dp)                                      :: eh1, exc1
     301           36 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     302              :       TYPE(atprop_type), POINTER                         :: atprop
     303           36 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s, rho_ao, xcmat
     304           36 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p
     305              :       TYPE(dft_control_type), POINTER                    :: dft_control
     306           36 :       TYPE(ecoul_1center_type), DIMENSION(:), POINTER    :: ecoul_1c
     307              :       TYPE(local_rho_type), POINTER                      :: local_rho_set
     308              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     309              :       TYPE(pw_env_type), POINTER                         :: pw_env
     310              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     311              :       TYPE(pw_r3d_rs_type)                               :: xc_den
     312           36 :       TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:)    :: vtau, vxc
     313              :       TYPE(pw_r3d_rs_type), POINTER                      :: v_hartree_rspace
     314              :       TYPE(qs_dispersion_type), POINTER                  :: dispersion_env
     315           36 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     316              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     317              :       TYPE(qs_rho_type), POINTER                         :: rho_struct
     318           36 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho_atom_set
     319              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section, xc_section
     320              :       TYPE(xc_rho_cflags_type)                           :: needs
     321              : 
     322           36 :       CALL timeset(routineN, handle)
     323              : 
     324           36 :       CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control, pw_env=pw_env, atprop=atprop)
     325              : 
     326           36 :       IF (atprop%energy) THEN
     327              : 
     328           36 :          nspins = dft_control%nspins
     329           36 :          xc_section => section_vals_get_subs_vals(qs_env%input, "DFT%XC")
     330           36 :          xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
     331           36 :          needs = xc_functionals_get_needs(xc_fun_section, (nspins == 2), .TRUE.)
     332           36 :          gapw = dft_control%qs_control%gapw
     333           36 :          gapw_xc = dft_control%qs_control%gapw_xc
     334              : 
     335              :          ! Nuclear charge correction
     336           36 :          CALL get_qs_env(qs_env, v_hartree_rspace=v_hartree_rspace)
     337           36 :          IF (gapw .OR. gapw_xc) THEN
     338              :             CALL get_qs_env(qs_env=qs_env, local_rho_set=local_rho_set, &
     339              :                             rho_atom_set=rho_atom_set, ecoul_1c=ecoul_1c, &
     340           12 :                             natom=natom, para_env=para_env)
     341           12 :             CALL zero_rho_atom_integrals(rho_atom_set)
     342           12 :             CALL calculate_vxc_atom(qs_env, .FALSE., exc1)
     343           12 :             IF (gapw) THEN
     344            8 :                CALL Vh_1c_gg_integrals(qs_env, eh1, ecoul_1c, local_rho_set, para_env, tddft=.FALSE.)
     345            8 :                CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
     346              :                CALL integrate_vhg0_rspace(qs_env, v_hartree_rspace, para_env, calculate_forces=.FALSE., &
     347            8 :                                           local_rho_set=local_rho_set, atener=atprop%ateb)
     348              :             END IF
     349              :          END IF
     350              : 
     351           36 :          CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     352           36 :          CALL auxbas_pw_pool%create_pw(xc_den)
     353          148 :          ALLOCATE (vxc(nspins))
     354           76 :          DO ispin = 1, nspins
     355           76 :             CALL auxbas_pw_pool%create_pw(vxc(ispin))
     356              :          END DO
     357           36 :          IF (needs%tau .OR. needs%tau_spin) THEN
     358           36 :             ALLOCATE (vtau(nspins))
     359           24 :             DO ispin = 1, nspins
     360           48 :                CALL auxbas_pw_pool%create_pw(vtau(ispin))
     361              :             END DO
     362              :          END IF
     363              : 
     364           36 :          IF (gapw_xc) THEN
     365            4 :             CALL get_qs_env(qs_env, rho_xc=rho_struct, dispersion_env=dispersion_env)
     366              :          ELSE
     367           32 :             CALL get_qs_env(qs_env, rho=rho_struct, dispersion_env=dispersion_env)
     368              :          END IF
     369           36 :          IF (needs%tau .OR. needs%tau_spin) THEN
     370              :             CALL qs_xc_density(ks_env, rho_struct, xc_section, dispersion_env=dispersion_env, &
     371           12 :                                xc_den=xc_den, vxc=vxc, vtau=vtau)
     372              :          ELSE
     373              :             CALL qs_xc_density(ks_env, rho_struct, xc_section, dispersion_env=dispersion_env, &
     374           24 :                                xc_den=xc_den, vxc=vxc)
     375              :          END IF
     376           36 :          CALL get_qs_env(qs_env, rho=rho_struct)
     377           36 :          CALL qs_rho_get(rho_struct, rho_ao=rho_ao)
     378           36 :          CALL get_qs_env(qs_env, natom=natom, matrix_s=matrix_s)
     379           36 :          CALL atprop_array_init(atprop%atexc, natom)
     380          148 :          ALLOCATE (xcmat(nspins))
     381           76 :          DO ispin = 1, nspins
     382           40 :             ALLOCATE (xcmat(ispin)%matrix)
     383           40 :             CALL dbcsr_create(xcmat(ispin)%matrix, template=matrix_s(1)%matrix)
     384           40 :             CALL dbcsr_copy(xcmat(ispin)%matrix, matrix_s(1)%matrix)
     385           40 :             CALL dbcsr_set(xcmat(ispin)%matrix, 0.0_dp)
     386           40 :             CALL pw_scale(vxc(ispin), -0.5_dp)
     387           40 :             CALL pw_axpy(xc_den, vxc(ispin))
     388           40 :             CALL pw_scale(vxc(ispin), vxc(ispin)%pw_grid%dvol)
     389              :             CALL integrate_v_rspace(qs_env=qs_env, v_rspace=vxc(ispin), hmat=xcmat(ispin), &
     390           40 :                                     calculate_forces=.FALSE., gapw=(gapw .OR. gapw_xc))
     391           76 :             IF (needs%tau .OR. needs%tau_spin) THEN
     392           12 :                CALL pw_scale(vtau(ispin), -0.5_dp*vtau(ispin)%pw_grid%dvol)
     393              :                CALL integrate_v_rspace(qs_env=qs_env, v_rspace=vtau(ispin), &
     394              :                                        hmat=xcmat(ispin), calculate_forces=.FALSE., &
     395           12 :                                        gapw=(gapw .OR. gapw_xc), compute_tau=.TRUE.)
     396              :             END IF
     397              :          END DO
     398           36 :          IF (gapw .OR. gapw_xc) THEN
     399              :             ! remove one-center potential matrix part
     400           12 :             CALL qs_rho_get(rho_struct, rho_ao_kp=matrix_p)
     401           12 :             CALL update_ks_atom(qs_env, xcmat, matrix_p, forces=.FALSE., kscale=-0.5_dp)
     402           12 :             CALL get_qs_env(qs_env=qs_env, rho_atom_set=rho_atom_set)
     403           12 :             CALL atprop_array_init(atprop%ate1c, natom)
     404           48 :             atprop%ate1c = 0.0_dp
     405           48 :             DO iatom = 1, natom
     406              :                atprop%ate1c(iatom) = atprop%ate1c(iatom) + &
     407           48 :                                      rho_atom_set(iatom)%exc_h - rho_atom_set(iatom)%exc_s
     408              :             END DO
     409           12 :             IF (gapw) THEN
     410            8 :                CALL get_qs_env(qs_env=qs_env, ecoul_1c=ecoul_1c)
     411           32 :                DO iatom = 1, natom
     412              :                   atprop%ate1c(iatom) = atprop%ate1c(iatom) + &
     413              :                                         ecoul_1c(iatom)%ecoul_1_h - ecoul_1c(iatom)%ecoul_1_s + &
     414           32 :                                         ecoul_1c(iatom)%ecoul_1_z - ecoul_1c(iatom)%ecoul_1_0
     415              :                END DO
     416              :             END IF
     417              :          END IF
     418           76 :          DO ispin = 1, nspins
     419           40 :             CALL atom_trace(xcmat(ispin)%matrix, rho_ao(ispin)%matrix, 1.0_dp, atprop%atexc)
     420           40 :             CALL dbcsr_release(xcmat(ispin)%matrix)
     421           76 :             DEALLOCATE (xcmat(ispin)%matrix)
     422              :          END DO
     423           36 :          DEALLOCATE (xcmat)
     424              : 
     425           36 :          CALL auxbas_pw_pool%give_back_pw(xc_den)
     426           76 :          DO ispin = 1, nspins
     427           76 :             CALL auxbas_pw_pool%give_back_pw(vxc(ispin))
     428              :          END DO
     429           36 :          IF (needs%tau .OR. needs%tau_spin) THEN
     430           24 :             DO ispin = 1, nspins
     431           48 :                CALL auxbas_pw_pool%give_back_pw(vtau(ispin))
     432              :             END DO
     433              :          END IF
     434              : 
     435              :       END IF
     436              : 
     437           36 :       CALL timestop(handle)
     438              : 
     439           72 :    END SUBROUTINE ks_xc_correction
     440              : 
     441              : END MODULE qs_energy_utils
        

Generated by: LCOV version 2.0-1