LCOV - code coverage report
Current view: top level - src - qs_ks_utils.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:21ef868) Lines: 78.3 % 868 680
Test Date: 2026-08-14 07:04:57 Functions: 80.0 % 10 8

            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              : !> \par History
      12              : !>      05.2002 moved from qs_scf (see there the history) [fawzi]
      13              : !>      JGH [30.08.02] multi-grid arrays independent from density and potential
      14              : !>      10.2002 introduced pools, uses updated rho as input,
      15              : !>              removed most temporary variables, renamed may vars,
      16              : !>              began conversion to LSD [fawzi]
      17              : !>      10.2004 moved calculate_w_matrix here [Joost VandeVondele]
      18              : !>              introduced energy derivative wrt MOs [Joost VandeVondele]
      19              : !> \author Fawzi Mohamed
      20              : ! **************************************************************************************************
      21              : 
      22              : MODULE qs_ks_utils
      23              :    USE admm_types,                      ONLY: admm_type,&
      24              :                                               get_admm_env
      25              :    USE atomic_kind_types,               ONLY: atomic_kind_type
      26              :    USE cell_types,                      ONLY: cell_type
      27              :    USE cp_control_types,                ONLY: dft_control_type
      28              :    USE cp_dbcsr_api,                    ONLY: &
      29              :         dbcsr_add, dbcsr_copy, dbcsr_deallocate_matrix, dbcsr_get_info, dbcsr_init_p, &
      30              :         dbcsr_multiply, dbcsr_p_type, dbcsr_release_p, dbcsr_scale, dbcsr_set, dbcsr_type
      31              :    USE cp_dbcsr_contrib,                ONLY: dbcsr_dot,&
      32              :                                               dbcsr_scale_by_vector
      33              :    USE cp_dbcsr_operations,             ONLY: copy_dbcsr_to_fm,&
      34              :                                               copy_fm_to_dbcsr,&
      35              :                                               cp_dbcsr_plus_fm_fm_t,&
      36              :                                               cp_dbcsr_sm_fm_multiply,&
      37              :                                               dbcsr_allocate_matrix_set,&
      38              :                                               dbcsr_deallocate_matrix_set
      39              :    USE cp_ddapc,                        ONLY: cp_ddapc_apply_CD
      40              :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      41              :                                               cp_fm_struct_release,&
      42              :                                               cp_fm_struct_type
      43              :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      44              :                                               cp_fm_get_info,&
      45              :                                               cp_fm_release,&
      46              :                                               cp_fm_set_all,&
      47              :                                               cp_fm_to_fm,&
      48              :                                               cp_fm_type
      49              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      50              :                                               cp_logger_type,&
      51              :                                               cp_to_string
      52              :    USE cp_output_handling,              ONLY: cp_p_file,&
      53              :                                               cp_print_key_finished_output,&
      54              :                                               cp_print_key_should_output,&
      55              :                                               cp_print_key_unit_nr
      56              :    USE hfx_admm_utils,                  ONLY: tddft_hfx_matrix
      57              :    USE hfx_derivatives,                 ONLY: derivatives_four_center
      58              :    USE hfx_types,                       ONLY: hfx_type
      59              :    USE input_constants,                 ONLY: &
      60              :         cdft_alpha_constraint, cdft_beta_constraint, cdft_charge_constraint, &
      61              :         cdft_magnetization_constraint, do_admm_aux_exch_func_none, do_ppl_grid, sic_ad, sic_eo, &
      62              :         sic_list_all, sic_list_unpaired, sic_mauri_spz, sic_mauri_us, sic_none
      63              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      64              :                                               section_vals_type,&
      65              :                                               section_vals_val_get
      66              :    USE kahan_sum,                       ONLY: accurate_dot_product,&
      67              :                                               accurate_sum
      68              :    USE kinds,                           ONLY: default_string_length,&
      69              :                                               dp
      70              :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      71              :                                               kpoint_type
      72              :    USE lri_environment_methods,         ONLY: v_int_ppl_update
      73              :    USE lri_environment_types,           ONLY: lri_density_type,&
      74              :                                               lri_environment_type,&
      75              :                                               lri_kind_type
      76              :    USE lri_forces,                      ONLY: calculate_lri_forces,&
      77              :                                               calculate_ri_forces
      78              :    USE lri_ks_methods,                  ONLY: calculate_lri_ks_matrix,&
      79              :                                               calculate_ri_ks_matrix
      80              :    USE message_passing,                 ONLY: mp_para_env_type
      81              :    USE ps_implicit_types,               ONLY: MIXED_BC,&
      82              :                                               MIXED_PERIODIC_BC,&
      83              :                                               NEUMANN_BC,&
      84              :                                               PERIODIC_BC
      85              :    USE pw_env_types,                    ONLY: pw_env_get,&
      86              :                                               pw_env_type
      87              :    USE pw_methods,                      ONLY: pw_axpy,&
      88              :                                               pw_copy,&
      89              :                                               pw_integral_ab,&
      90              :                                               pw_integrate_function,&
      91              :                                               pw_scale,&
      92              :                                               pw_transfer,&
      93              :                                               pw_zero
      94              :    USE pw_poisson_methods,              ONLY: pw_poisson_solve
      95              :    USE pw_poisson_types,                ONLY: pw_poisson_implicit,&
      96              :                                               pw_poisson_type
      97              :    USE pw_pool_types,                   ONLY: pw_pool_type
      98              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      99              :                                               pw_r3d_rs_type
     100              :    USE qs_cdft_types,                   ONLY: cdft_control_type
     101              :    USE qs_charges_types,                ONLY: qs_charges_type
     102              :    USE qs_collocate_density,            ONLY: calculate_rho_elec
     103              :    USE qs_energy_types,                 ONLY: qs_energy_type
     104              :    USE qs_environment_types,            ONLY: get_qs_env,&
     105              :                                               qs_environment_type
     106              :    USE qs_force_types,                  ONLY: qs_force_type
     107              :    USE qs_integrate_potential,          ONLY: integrate_v_rspace,&
     108              :                                               integrate_v_rspace_diagonal,&
     109              :                                               integrate_v_rspace_one_center
     110              :    USE qs_kind_types,                   ONLY: get_qs_kind_set,&
     111              :                                               qs_kind_type
     112              :    USE qs_ks_qmmm_methods,              ONLY: qmmm_modify_hartree_pot
     113              :    USE qs_ks_types,                     ONLY: get_ks_env,&
     114              :                                               qs_ks_env_type
     115              :    USE qs_mo_types,                     ONLY: get_mo_set,&
     116              :                                               mo_set_type
     117              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
     118              :                                               qs_rho_type
     119              :    USE skala_gpw_functional,            ONLY: native_skala_gapw_composite_direct_ao,&
     120              :                                               native_skala_gapw_composite_reference
     121              :    USE task_list_types,                 ONLY: task_list_type
     122              :    USE virial_types,                    ONLY: virial_type
     123              :    USE xc,                              ONLY: xc_exc_calc,&
     124              :                                               xc_vxc_pw_create
     125              : #include "./base/base_uses.f90"
     126              : 
     127              :    IMPLICIT NONE
     128              : 
     129              :    PRIVATE
     130              : 
     131              :    LOGICAL, PARAMETER :: debug_this_module = .TRUE.
     132              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_ks_utils'
     133              : 
     134              :    PUBLIC :: low_spin_roks, sic_explicit_orbitals, calc_v_sic_rspace, print_densities, &
     135              :              print_detailed_energy, compute_matrix_vxc, compute_matrix_vxc_kp, sum_up_and_integrate, &
     136              :              calculate_zmp_potential, get_embed_potential_energy
     137              : 
     138              : CONTAINS
     139              : 
     140              : ! **************************************************************************************************
     141              : !> \brief do ROKS calculations yielding low spin states
     142              : !> \param energy ...
     143              : !> \param qs_env ...
     144              : !> \param dft_control ...
     145              : !> \param do_hfx ...
     146              : !> \param just_energy ...
     147              : !> \param calculate_forces ...
     148              : !> \param auxbas_pw_pool ...
     149              : ! **************************************************************************************************
     150       124119 :    SUBROUTINE low_spin_roks(energy, qs_env, dft_control, do_hfx, just_energy, &
     151              :                             calculate_forces, auxbas_pw_pool)
     152              : 
     153              :       TYPE(qs_energy_type), POINTER                      :: energy
     154              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     155              :       TYPE(dft_control_type), POINTER                    :: dft_control
     156              :       LOGICAL, INTENT(IN)                                :: do_hfx, just_energy, calculate_forces
     157              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     158              : 
     159              :       CHARACTER(*), PARAMETER                            :: routineN = 'low_spin_roks'
     160              : 
     161              :       INTEGER                                            :: handle, irep, ispin, iterm, k, k_alpha, &
     162              :                                                             k_beta, n_rep, Nelectron, Nspin, Nterms
     163       124119 :       INTEGER, DIMENSION(:), POINTER                     :: ivec
     164       124119 :       INTEGER, DIMENSION(:, :, :), POINTER               :: occupations
     165              :       LOGICAL                                            :: compute_virial, in_range, &
     166              :                                                             uniform_occupation
     167              :       REAL(KIND=dp)                                      :: ehfx, exc
     168              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: virial_xc_tmp
     169       124119 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: energy_scaling, rvec, scaling
     170              :       TYPE(cell_type), POINTER                           :: cell
     171       124119 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_h, matrix_hfx, matrix_p, mdummy, &
     172       124119 :                                                             mo_derivs, rho_ao
     173       124119 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p2
     174              :       TYPE(dbcsr_type), POINTER                          :: dbcsr_deriv, fm_deriv, fm_scaled, &
     175              :                                                             mo_coeff
     176       124119 :       TYPE(hfx_type), DIMENSION(:, :), POINTER           :: x_data
     177       124119 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mo_array
     178              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     179       124119 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g
     180              :       TYPE(pw_env_type), POINTER                         :: pw_env
     181              :       TYPE(pw_pool_type), POINTER                        :: xc_pw_pool
     182              :       TYPE(pw_r3d_rs_type)                               :: work_v_rspace
     183       124119 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, tau, vxc, vxc_tau
     184              :       TYPE(pw_r3d_rs_type), POINTER                      :: weights
     185              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     186              :       TYPE(qs_rho_type), POINTER                         :: rho
     187              :       TYPE(section_vals_type), POINTER                   :: hfx_section, input, &
     188              :                                                             low_spin_roks_section, xc_section
     189              :       TYPE(virial_type), POINTER                         :: virial
     190              : 
     191       123757 :       IF (.NOT. dft_control%low_spin_roks) RETURN
     192              : 
     193          362 :       CALL timeset(routineN, handle)
     194              : 
     195          362 :       NULLIFY (ks_env, rho_ao)
     196              : 
     197              :       ! Test for not compatible options
     198          362 :       IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
     199            0 :          CALL cp_abort(__LOCATION__, "GAPW/GAPW_XC are not compatible with low spin ROKS method.")
     200              :       END IF
     201          362 :       IF (dft_control%do_admm) THEN
     202            0 :          CALL cp_abort(__LOCATION__, "ADMM not compatible with low spin ROKS method.")
     203              :       END IF
     204          362 :       IF (dft_control%do_admm) THEN
     205            0 :          IF (qs_env%admm_env%aux_exch_func /= do_admm_aux_exch_func_none) THEN
     206              :             CALL cp_abort(__LOCATION__, "ADMM with XC correction functional "// &
     207            0 :                           "not compatible with low spin ROKS method.")
     208              :          END IF
     209              :       END IF
     210          362 :       IF (dft_control%qs_control%semi_empirical .OR. dft_control%qs_control%dftb .OR. &
     211              :           dft_control%qs_control%xtb) THEN
     212            0 :          CALL cp_abort(__LOCATION__, "SE/xTB/DFTB are not compatible with low spin ROKS method.")
     213              :       END IF
     214              : 
     215              :       CALL get_qs_env(qs_env, &
     216              :                       ks_env=ks_env, &
     217              :                       mo_derivs=mo_derivs, &
     218              :                       mos=mo_array, &
     219              :                       rho=rho, &
     220              :                       pw_env=pw_env, &
     221              :                       xcint_weights=weights, &
     222              :                       input=input, &
     223              :                       cell=cell, &
     224          362 :                       virial=virial)
     225              : 
     226          362 :       CALL qs_rho_get(rho, rho_ao=rho_ao)
     227              : 
     228          362 :       compute_virial = virial%pv_calculate .AND. (.NOT. virial%pv_numer)
     229          362 :       xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     230          362 :       hfx_section => section_vals_get_subs_vals(input, "DFT%XC%HF")
     231              : 
     232              :       ! No accurate integration possible (as there is no GAPW)
     233          362 :       IF (ASSOCIATED(weights)) THEN
     234            0 :          CALL cp_abort(__LOCATION__, "No accurate xc integration possible.")
     235              :       END IF
     236              :       ! some assumptions need to be checked
     237              :       ! we have two spins
     238          362 :       CPASSERT(SIZE(mo_array, 1) == 2)
     239          362 :       Nspin = 2
     240              :       ! we want uniform occupations
     241          362 :       CALL get_mo_set(mo_set=mo_array(1), uniform_occupation=uniform_occupation)
     242          362 :       CPASSERT(uniform_occupation)
     243          362 :       CALL get_mo_set(mo_set=mo_array(2), mo_coeff_b=mo_coeff, uniform_occupation=uniform_occupation)
     244          362 :       CPASSERT(uniform_occupation)
     245          362 :       IF (do_hfx .AND. calculate_forces .AND. compute_virial) THEN
     246            0 :          CALL cp_abort(__LOCATION__, "ROKS virial with HFX not available.")
     247              :       END IF
     248              : 
     249          362 :       NULLIFY (dbcsr_deriv)
     250          362 :       CALL dbcsr_init_p(dbcsr_deriv)
     251          362 :       CALL dbcsr_copy(dbcsr_deriv, mo_derivs(1)%matrix)
     252          362 :       CALL dbcsr_set(dbcsr_deriv, 0.0_dp)
     253              : 
     254              :       ! basic info
     255          362 :       CALL get_mo_set(mo_set=mo_array(1), mo_coeff_b=mo_coeff)
     256          362 :       CALL dbcsr_get_info(mo_coeff, nfullcols_total=k_alpha)
     257          362 :       CALL get_mo_set(mo_set=mo_array(2), mo_coeff_b=mo_coeff)
     258          362 :       CALL dbcsr_get_info(mo_coeff, nfullcols_total=k_beta)
     259              : 
     260              :       ! read the input
     261          362 :       low_spin_roks_section => section_vals_get_subs_vals(input, "DFT%LOW_SPIN_ROKS")
     262              : 
     263          362 :       CALL section_vals_val_get(low_spin_roks_section, "ENERGY_SCALING", r_vals=rvec)
     264          362 :       Nterms = SIZE(rvec)
     265         1086 :       ALLOCATE (energy_scaling(Nterms))
     266         1810 :       energy_scaling = rvec !? just wondering, should this add up to 1, in which case we should cpp?
     267              : 
     268          362 :       CALL section_vals_val_get(low_spin_roks_section, "SPIN_CONFIGURATION", n_rep_val=n_rep)
     269          362 :       CPASSERT(n_rep == Nterms)
     270          362 :       CALL section_vals_val_get(low_spin_roks_section, "SPIN_CONFIGURATION", i_rep_val=1, i_vals=ivec)
     271          362 :       Nelectron = SIZE(ivec)
     272          362 :       CPASSERT(Nelectron == k_alpha - k_beta)
     273         1448 :       ALLOCATE (occupations(2, Nelectron, Nterms))
     274         5430 :       occupations = 0
     275         1086 :       DO iterm = 1, Nterms
     276          724 :          CALL section_vals_val_get(low_spin_roks_section, "SPIN_CONFIGURATION", i_rep_val=iterm, i_vals=ivec)
     277          724 :          CPASSERT(Nelectron == SIZE(ivec))
     278         4344 :          in_range = ALL(ivec >= 1) .AND. ALL(ivec <= 2)
     279          724 :          CPASSERT(in_range)
     280         2534 :          DO k = 1, Nelectron
     281         2172 :             occupations(ivec(k), k, iterm) = 1
     282              :          END DO
     283              :       END DO
     284              : 
     285              :       ! set up general data structures
     286              :       ! density matrices, kohn-sham matrices
     287              : 
     288          362 :       NULLIFY (matrix_p)
     289          362 :       CALL dbcsr_allocate_matrix_set(matrix_p, Nspin)
     290         1086 :       DO ispin = 1, Nspin
     291          724 :          ALLOCATE (matrix_p(ispin)%matrix)
     292              :          CALL dbcsr_copy(matrix_p(ispin)%matrix, rho_ao(1)%matrix, &
     293          724 :                          name="density matrix low spin roks")
     294         1086 :          CALL dbcsr_set(matrix_p(ispin)%matrix, 0.0_dp)
     295              :       END DO
     296              : 
     297          362 :       NULLIFY (matrix_h)
     298          362 :       CALL dbcsr_allocate_matrix_set(matrix_h, Nspin)
     299         1086 :       DO ispin = 1, Nspin
     300          724 :          ALLOCATE (matrix_h(ispin)%matrix)
     301              :          CALL dbcsr_copy(matrix_h(ispin)%matrix, rho_ao(1)%matrix, &
     302          724 :                          name="KS matrix low spin roks")
     303         1086 :          CALL dbcsr_set(matrix_h(ispin)%matrix, 0.0_dp)
     304              :       END DO
     305              : 
     306          362 :       IF (do_hfx) THEN
     307          220 :          NULLIFY (matrix_hfx)
     308          220 :          CALL dbcsr_allocate_matrix_set(matrix_hfx, Nspin)
     309          660 :          DO ispin = 1, Nspin
     310          440 :             ALLOCATE (matrix_hfx(ispin)%matrix)
     311              :             CALL dbcsr_copy(matrix_hfx(ispin)%matrix, rho_ao(1)%matrix, &
     312          660 :                             name="HFX matrix low spin roks")
     313              :          END DO
     314              :       END IF
     315              : 
     316              :       ! grids in real and g space for rho and vxc
     317              :       ! tau functionals are not supported
     318          362 :       NULLIFY (tau, vxc_tau, vxc)
     319          362 :       CALL pw_env_get(pw_env, xc_pw_pool=xc_pw_pool)
     320              : 
     321         1086 :       ALLOCATE (rho_r(Nspin))
     322         1086 :       ALLOCATE (rho_g(Nspin))
     323         1086 :       DO ispin = 1, Nspin
     324          724 :          CALL auxbas_pw_pool%create_pw(rho_r(ispin))
     325         1086 :          CALL auxbas_pw_pool%create_pw(rho_g(ispin))
     326              :       END DO
     327          362 :       CALL auxbas_pw_pool%create_pw(work_v_rspace)
     328              : 
     329              :       ! get mo matrices needed to construct the density matrices
     330              :       ! we will base all on the alpha spin matrix, obviously possible in ROKS
     331          362 :       CALL get_mo_set(mo_set=mo_array(1), mo_coeff_b=mo_coeff)
     332          362 :       NULLIFY (fm_scaled, fm_deriv)
     333          362 :       CALL dbcsr_init_p(fm_scaled)
     334          362 :       CALL dbcsr_init_p(fm_deriv)
     335          362 :       CALL dbcsr_copy(fm_scaled, mo_coeff)
     336          362 :       CALL dbcsr_copy(fm_deriv, mo_coeff)
     337              : 
     338         1086 :       ALLOCATE (scaling(k_alpha))
     339              : 
     340              :       ! for each term, add it with the given scaling factor to the energy, and compute the required derivatives
     341         1086 :       DO iterm = 1, Nterms
     342              : 
     343         2172 :          DO ispin = 1, Nspin
     344              :             ! compute the proper density matrices with the required occupations
     345         1448 :             CALL dbcsr_set(matrix_p(ispin)%matrix, 0.0_dp)
     346        11584 :             scaling = 1.0_dp
     347         4344 :             scaling(k_alpha - Nelectron + 1:k_alpha) = occupations(ispin, :, iterm)
     348         1448 :             CALL dbcsr_copy(fm_scaled, mo_coeff)
     349         1448 :             CALL dbcsr_scale_by_vector(fm_scaled, scaling, side='right')
     350              :             CALL dbcsr_multiply('n', 't', 1.0_dp, mo_coeff, fm_scaled, &
     351         1448 :                                 0.0_dp, matrix_p(ispin)%matrix, retain_sparsity=.TRUE.)
     352              :             ! compute the densities on the grid
     353              :             CALL calculate_rho_elec(matrix_p=matrix_p(ispin)%matrix, &
     354              :                                     rho=rho_r(ispin), rho_gspace=rho_g(ispin), &
     355         2172 :                                     ks_env=ks_env)
     356              :          END DO
     357              : 
     358              :          ! compute the exchange energies / potential if needed
     359          724 :          IF (just_energy) THEN
     360              :             exc = xc_exc_calc(rho_r=rho_r, rho_g=rho_g, tau=tau, xc_section=xc_section, &
     361           88 :                               weights=weights, pw_pool=xc_pw_pool)
     362              :          ELSE
     363          636 :             CPASSERT(.NOT. compute_virial)
     364              :             CALL xc_vxc_pw_create(vxc_rho=vxc, rho_r=rho_r, &
     365              :                                   rho_g=rho_g, tau=tau, vxc_tau=vxc_tau, exc=exc, xc_section=xc_section, &
     366              :                                   weights=weights, pw_pool=xc_pw_pool, &
     367          636 :                                   compute_virial=.FALSE., virial_xc=virial_xc_tmp)
     368              :          END IF
     369              : 
     370          724 :          energy%exc = energy%exc + energy_scaling(iterm)*exc
     371              : 
     372          724 :          IF (do_hfx) THEN
     373              :             ! Add Hartree-Fock contribution
     374         1320 :             DO ispin = 1, Nspin
     375         1320 :                CALL dbcsr_set(matrix_hfx(ispin)%matrix, 0.0_dp)
     376              :             END DO
     377          440 :             ehfx = energy%ex
     378              :             CALL tddft_hfx_matrix(matrix_hfx, matrix_p, qs_env, &
     379          440 :                                   recalc_integrals=.FALSE., update_energy=.TRUE.)
     380          440 :             energy%ex = ehfx + energy_scaling(iterm)*energy%ex
     381              :          END IF
     382              : 
     383              :          ! add the corresponding derivatives to the MO derivatives
     384         1086 :          IF (.NOT. just_energy) THEN
     385              :             ! get the potential in matrix form
     386         1908 :             DO ispin = 1, Nspin
     387         1272 :                CALL dbcsr_set(matrix_h(ispin)%matrix, 0.0_dp)
     388              :                ! use a work_v_rspace
     389         1272 :                CALL pw_axpy(vxc(ispin), work_v_rspace, energy_scaling(iterm)*vxc(ispin)%pw_grid%dvol, 0.0_dp)
     390              :                CALL integrate_v_rspace(v_rspace=work_v_rspace, pmat=matrix_p(ispin), hmat=matrix_h(ispin), &
     391         1272 :                                        qs_env=qs_env, calculate_forces=calculate_forces)
     392         1908 :                CALL auxbas_pw_pool%give_back_pw(vxc(ispin))
     393              :             END DO
     394          636 :             DEALLOCATE (vxc)
     395              : 
     396          636 :             IF (do_hfx) THEN
     397              :                ! add HFX contribution
     398         1104 :                DO ispin = 1, Nspin
     399              :                   CALL dbcsr_add(matrix_h(ispin)%matrix, matrix_hfx(ispin)%matrix, &
     400         1104 :                                  1.0_dp, energy_scaling(iterm))
     401              :                END DO
     402          368 :                IF (calculate_forces) THEN
     403            8 :                   CALL get_qs_env(qs_env, x_data=x_data, para_env=para_env)
     404            8 :                   IF (x_data(1, 1)%n_rep_hf /= 1) THEN
     405              :                      CALL cp_abort(__LOCATION__, "Multiple HFX section forces not compatible "// &
     406            0 :                                    "with low spin ROKS method.")
     407              :                   END IF
     408            8 :                   IF (x_data(1, 1)%do_hfx_ri) THEN
     409            0 :                      CALL cp_abort(__LOCATION__, "HFX_RI forces not compatible with low spin ROKS method.")
     410              :                   ELSE
     411            8 :                      irep = 1
     412            8 :                      NULLIFY (mdummy)
     413            8 :                      matrix_p2(1:Nspin, 1:1) => matrix_p(1:Nspin)
     414              :                      CALL derivatives_four_center(qs_env, matrix_p2, mdummy, hfx_section, para_env, &
     415              :                                                   irep, compute_virial, &
     416            8 :                                                   adiabatic_rescale_factor=energy_scaling(iterm))
     417              :                   END IF
     418              :                END IF
     419              : 
     420              :             END IF
     421              : 
     422              :             ! add this to the mo_derivs, again based on the alpha mo_coeff
     423         1908 :             DO ispin = 1, Nspin
     424              :                CALL dbcsr_multiply('n', 'n', 1.0_dp, matrix_h(ispin)%matrix, mo_coeff, &
     425         1272 :                                    0.0_dp, dbcsr_deriv, last_column=k_alpha)
     426              : 
     427        10176 :                scaling = 1.0_dp
     428         3816 :                scaling(k_alpha - Nelectron + 1:k_alpha) = occupations(ispin, :, iterm)
     429         1272 :                CALL dbcsr_scale_by_vector(dbcsr_deriv, scaling, side='right')
     430         1908 :                CALL dbcsr_add(mo_derivs(1)%matrix, dbcsr_deriv, 1.0_dp, 1.0_dp)
     431              :             END DO
     432              : 
     433              :          END IF
     434              : 
     435              :       END DO
     436              : 
     437              :       ! release allocated memory
     438         1086 :       DO ispin = 1, Nspin
     439          724 :          CALL auxbas_pw_pool%give_back_pw(rho_r(ispin))
     440         1086 :          CALL auxbas_pw_pool%give_back_pw(rho_g(ispin))
     441              :       END DO
     442          362 :       DEALLOCATE (rho_r, rho_g)
     443          362 :       CALL dbcsr_deallocate_matrix_set(matrix_p)
     444          362 :       CALL dbcsr_deallocate_matrix_set(matrix_h)
     445          362 :       IF (do_hfx) THEN
     446          220 :          CALL dbcsr_deallocate_matrix_set(matrix_hfx)
     447              :       END IF
     448              : 
     449          362 :       CALL auxbas_pw_pool%give_back_pw(work_v_rspace)
     450              : 
     451          362 :       CALL dbcsr_release_p(fm_deriv)
     452          362 :       CALL dbcsr_release_p(fm_scaled)
     453              : 
     454          362 :       DEALLOCATE (occupations)
     455          362 :       DEALLOCATE (energy_scaling)
     456          362 :       DEALLOCATE (scaling)
     457              : 
     458          362 :       CALL dbcsr_release_p(dbcsr_deriv)
     459              : 
     460          362 :       CALL timestop(handle)
     461              : 
     462       125929 :    END SUBROUTINE low_spin_roks
     463              : ! **************************************************************************************************
     464              : !> \brief do sic calculations on explicit orbitals
     465              : !> \param energy ...
     466              : !> \param qs_env ...
     467              : !> \param dft_control ...
     468              : !> \param poisson_env ...
     469              : !> \param just_energy ...
     470              : !> \param calculate_forces ...
     471              : !> \param auxbas_pw_pool ...
     472              : ! **************************************************************************************************
     473       124119 :    SUBROUTINE sic_explicit_orbitals(energy, qs_env, dft_control, poisson_env, just_energy, &
     474              :                                     calculate_forces, auxbas_pw_pool)
     475              : 
     476              :       TYPE(qs_energy_type), POINTER                      :: energy
     477              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     478              :       TYPE(dft_control_type), POINTER                    :: dft_control
     479              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
     480              :       LOGICAL, INTENT(IN)                                :: just_energy, calculate_forces
     481              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     482              : 
     483              :       CHARACTER(*), PARAMETER :: routineN = 'sic_explicit_orbitals'
     484              : 
     485              :       INTEGER                                            :: handle, i, Iorb, k_alpha, k_beta, Norb
     486       124119 :       INTEGER, ALLOCATABLE, DIMENSION(:, :)              :: sic_orbital_list
     487              :       LOGICAL                                            :: compute_virial, uniform_occupation
     488              :       REAL(KIND=dp)                                      :: ener, exc
     489              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: virial_xc_tmp
     490              :       TYPE(cell_type), POINTER                           :: cell
     491              :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct_tmp
     492              :       TYPE(cp_fm_type)                                   :: matrix_hv, matrix_v
     493       124119 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: mo_derivs_local
     494              :       TYPE(cp_fm_type), POINTER                          :: mo_coeff
     495              :       TYPE(dbcsr_p_type)                                 :: orb_density_matrix_p, orb_h_p
     496       124119 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: mo_derivs, rho_ao, tmp_dbcsr
     497              :       TYPE(dbcsr_type), POINTER                          :: orb_density_matrix, orb_h
     498       124119 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mo_array
     499              :       TYPE(pw_c1d_gs_type)                               :: work_v_gspace
     500       124119 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g
     501              :       TYPE(pw_c1d_gs_type), TARGET                       :: orb_rho_g, tmp_g
     502              :       TYPE(pw_env_type), POINTER                         :: pw_env
     503              :       TYPE(pw_pool_type), POINTER                        :: xc_pw_pool
     504              :       TYPE(pw_r3d_rs_type)                               :: work_v_rspace
     505       124119 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, tau, vxc, vxc_tau
     506              :       TYPE(pw_r3d_rs_type), POINTER                      :: weights
     507              :       TYPE(pw_r3d_rs_type), TARGET                       :: orb_rho_r, tmp_r
     508              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     509              :       TYPE(qs_rho_type), POINTER                         :: rho
     510              :       TYPE(section_vals_type), POINTER                   :: input, xc_section
     511              :       TYPE(virial_type), POINTER                         :: virial
     512              : 
     513       124119 :       IF (dft_control%sic_method_id /= sic_eo) RETURN
     514              : 
     515           40 :       CALL timeset(routineN, handle)
     516              : 
     517           40 :       NULLIFY (tau, vxc_tau, mo_derivs, ks_env, rho_ao)
     518              : 
     519              :       ! generate the lists of orbitals that need sic treatment
     520              :       CALL get_qs_env(qs_env, &
     521              :                       ks_env=ks_env, &
     522              :                       mo_derivs=mo_derivs, &
     523              :                       mos=mo_array, &
     524              :                       rho=rho, &
     525              :                       xcint_weights=weights, &
     526              :                       pw_env=pw_env, &
     527              :                       input=input, &
     528              :                       cell=cell, &
     529           40 :                       virial=virial)
     530              : 
     531           40 :       CALL qs_rho_get(rho, rho_ao=rho_ao)
     532              : 
     533           40 :       compute_virial = virial%pv_calculate .AND. (.NOT. virial%pv_numer)
     534           40 :       xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     535              : 
     536          120 :       DO i = 1, SIZE(mo_array) !fm->dbcsr
     537          120 :          IF (mo_array(i)%use_mo_coeff_b) THEN !fm->dbcsr
     538              :             CALL copy_dbcsr_to_fm(mo_array(i)%mo_coeff_b, &
     539           80 :                                   mo_array(i)%mo_coeff) !fm->dbcsr
     540              :          END IF !fm->dbcsr
     541              :       END DO !fm->dbcsr
     542              : 
     543           40 :       CALL pw_env_get(pw_env, xc_pw_pool=xc_pw_pool)
     544              : 
     545              :       ! we have two spins
     546           40 :       CPASSERT(SIZE(mo_array, 1) == 2)
     547              :       ! we want uniform occupations
     548           40 :       CALL get_mo_set(mo_set=mo_array(1), uniform_occupation=uniform_occupation)
     549           40 :       CPASSERT(uniform_occupation)
     550           40 :       CALL get_mo_set(mo_set=mo_array(2), mo_coeff=mo_coeff, uniform_occupation=uniform_occupation)
     551           40 :       CPASSERT(uniform_occupation)
     552              : 
     553           40 :       NULLIFY (tmp_dbcsr)
     554           40 :       CALL dbcsr_allocate_matrix_set(tmp_dbcsr, SIZE(mo_derivs, 1))
     555          100 :       DO i = 1, SIZE(mo_derivs, 1) !fm->dbcsr
     556              :          !
     557           60 :          NULLIFY (tmp_dbcsr(i)%matrix)
     558           60 :          CALL dbcsr_init_p(tmp_dbcsr(i)%matrix)
     559           60 :          CALL dbcsr_copy(tmp_dbcsr(i)%matrix, mo_derivs(i)%matrix)
     560          100 :          CALL dbcsr_set(tmp_dbcsr(i)%matrix, 0.0_dp)
     561              :       END DO !fm->dbcsr
     562              : 
     563           40 :       k_alpha = 0; k_beta = 0
     564           60 :       SELECT CASE (dft_control%sic_list_id)
     565              :       CASE (sic_list_all)
     566              : 
     567           20 :          CALL get_mo_set(mo_set=mo_array(1), mo_coeff=mo_coeff)
     568           20 :          CALL cp_fm_get_info(mo_coeff, ncol_global=k_alpha)
     569              : 
     570           20 :          IF (SIZE(mo_array, 1) > 1) THEN
     571           20 :             CALL get_mo_set(mo_set=mo_array(2), mo_coeff=mo_coeff)
     572           20 :             CALL cp_fm_get_info(mo_coeff, ncol_global=k_beta)
     573              :          END IF
     574              : 
     575           20 :          Norb = k_alpha + k_beta
     576           60 :          ALLOCATE (sic_orbital_list(3, Norb))
     577              : 
     578           80 :          iorb = 0
     579           80 :          DO i = 1, k_alpha
     580           60 :             iorb = iorb + 1
     581           60 :             sic_orbital_list(1, iorb) = 1
     582           60 :             sic_orbital_list(2, iorb) = i
     583           80 :             sic_orbital_list(3, iorb) = 1
     584              :          END DO
     585           60 :          DO i = 1, k_beta
     586           20 :             iorb = iorb + 1
     587           20 :             sic_orbital_list(1, iorb) = 2
     588           20 :             sic_orbital_list(2, iorb) = i
     589           40 :             IF (SIZE(mo_derivs, 1) == 1) THEN
     590            0 :                sic_orbital_list(3, iorb) = 1
     591              :             ELSE
     592           20 :                sic_orbital_list(3, iorb) = 2
     593              :             END IF
     594              :          END DO
     595              : 
     596              :       CASE (sic_list_unpaired)
     597              :          ! we have two spins
     598           20 :          CPASSERT(SIZE(mo_array, 1) == 2)
     599              :          ! we have them restricted
     600           20 :          CPASSERT(SIZE(mo_derivs, 1) == 1)
     601           20 :          CPASSERT(dft_control%restricted)
     602              : 
     603           20 :          CALL get_mo_set(mo_set=mo_array(1), mo_coeff=mo_coeff)
     604           20 :          CALL cp_fm_get_info(mo_coeff, ncol_global=k_alpha)
     605              : 
     606           20 :          CALL get_mo_set(mo_set=mo_array(2), mo_coeff=mo_coeff)
     607           20 :          CALL cp_fm_get_info(mo_coeff, ncol_global=k_beta)
     608              : 
     609           20 :          Norb = k_alpha - k_beta
     610           60 :          ALLOCATE (sic_orbital_list(3, Norb))
     611              : 
     612           20 :          iorb = 0
     613          100 :          DO i = k_beta + 1, k_alpha
     614           40 :             iorb = iorb + 1
     615           40 :             sic_orbital_list(1, iorb) = 1
     616           40 :             sic_orbital_list(2, iorb) = i
     617              :             ! we are guaranteed to be restricted
     618           60 :             sic_orbital_list(3, iorb) = 1
     619              :          END DO
     620              : 
     621              :       CASE DEFAULT
     622           40 :          CPABORT("Unknown dft_control%sic_list_id")
     623              :       END SELECT
     624              : 
     625              :       ! data needed for each of the orbs
     626           40 :       CALL auxbas_pw_pool%create_pw(orb_rho_r)
     627           40 :       CALL auxbas_pw_pool%create_pw(tmp_r)
     628           40 :       CALL auxbas_pw_pool%create_pw(orb_rho_g)
     629           40 :       CALL auxbas_pw_pool%create_pw(tmp_g)
     630           40 :       CALL auxbas_pw_pool%create_pw(work_v_gspace)
     631           40 :       CALL auxbas_pw_pool%create_pw(work_v_rspace)
     632              : 
     633           40 :       ALLOCATE (orb_density_matrix)
     634              :       CALL dbcsr_copy(orb_density_matrix, rho_ao(1)%matrix, &
     635           40 :                       name="orb_density_matrix")
     636           40 :       CALL dbcsr_set(orb_density_matrix, 0.0_dp)
     637           40 :       orb_density_matrix_p%matrix => orb_density_matrix
     638              : 
     639           40 :       ALLOCATE (orb_h)
     640              :       CALL dbcsr_copy(orb_h, rho_ao(1)%matrix, &
     641           40 :                       name="orb_density_matrix")
     642           40 :       CALL dbcsr_set(orb_h, 0.0_dp)
     643           40 :       orb_h_p%matrix => orb_h
     644              : 
     645           40 :       CALL get_mo_set(mo_set=mo_array(1), mo_coeff=mo_coeff)
     646              : 
     647              :       CALL cp_fm_struct_create(fm_struct_tmp, ncol_global=1, &
     648           40 :                                template_fmstruct=mo_coeff%matrix_struct)
     649           40 :       CALL cp_fm_create(matrix_v, fm_struct_tmp, name="matrix_v")
     650           40 :       CALL cp_fm_create(matrix_hv, fm_struct_tmp, name="matrix_hv")
     651           40 :       CALL cp_fm_struct_release(fm_struct_tmp)
     652              : 
     653          200 :       ALLOCATE (mo_derivs_local(SIZE(mo_array, 1)))
     654          120 :       DO I = 1, SIZE(mo_array, 1)
     655           80 :          CALL get_mo_set(mo_set=mo_array(i), mo_coeff=mo_coeff)
     656          120 :          CALL cp_fm_create(mo_derivs_local(I), mo_coeff%matrix_struct)
     657              :       END DO
     658              : 
     659          120 :       ALLOCATE (rho_r(2))
     660           40 :       rho_r(1) = orb_rho_r
     661           40 :       rho_r(2) = tmp_r
     662           40 :       CALL pw_zero(tmp_r)
     663              : 
     664          120 :       ALLOCATE (rho_g(2))
     665           40 :       rho_g(1) = orb_rho_g
     666           40 :       rho_g(2) = tmp_g
     667           40 :       CALL pw_zero(tmp_g)
     668              : 
     669           40 :       NULLIFY (vxc)
     670              :       ! now apply to SIC correction to each selected orbital
     671          160 :       DO iorb = 1, Norb
     672              :          ! extract the proper orbital from the mo_coeff
     673          120 :          CALL get_mo_set(mo_set=mo_array(sic_orbital_list(1, iorb)), mo_coeff=mo_coeff)
     674          120 :          CALL cp_fm_to_fm(mo_coeff, matrix_v, 1, sic_orbital_list(2, iorb), 1)
     675              : 
     676              :          ! construct the density matrix and the corresponding density
     677          120 :          CALL dbcsr_set(orb_density_matrix, 0.0_dp)
     678              :          CALL cp_dbcsr_plus_fm_fm_t(orb_density_matrix, matrix_v=matrix_v, ncol=1, &
     679          120 :                                     alpha=1.0_dp)
     680              : 
     681              :          CALL calculate_rho_elec(matrix_p=orb_density_matrix, &
     682              :                                  rho=orb_rho_r, rho_gspace=orb_rho_g, &
     683          120 :                                  ks_env=ks_env)
     684              : 
     685              :          ! compute the energy functional for this orbital and its derivative
     686              : 
     687          120 :          CALL pw_poisson_solve(poisson_env, orb_rho_g, ener, work_v_gspace)
     688              :          ! no PBC correction is done here, see "calc_v_sic_rspace" for SIC methods
     689              :          ! with PBC aware corrections
     690          120 :          energy%hartree = energy%hartree - dft_control%sic_scaling_a*ener
     691          120 :          IF (.NOT. just_energy) THEN
     692           72 :             CALL pw_transfer(work_v_gspace, work_v_rspace)
     693           72 :             CALL pw_scale(work_v_rspace, -dft_control%sic_scaling_a*work_v_rspace%pw_grid%dvol)
     694           72 :             CALL dbcsr_set(orb_h, 0.0_dp)
     695              :          END IF
     696              : 
     697          120 :          IF (just_energy) THEN
     698              :             exc = xc_exc_calc(rho_r=rho_r, rho_g=rho_g, tau=tau, xc_section=xc_section, &
     699           48 :                               weights=weights, pw_pool=xc_pw_pool)
     700              :          ELSE
     701           72 :             CPASSERT(.NOT. compute_virial)
     702              :             CALL xc_vxc_pw_create(vxc_rho=vxc, rho_r=rho_r, &
     703              :                                   rho_g=rho_g, tau=tau, vxc_tau=vxc_tau, exc=exc, xc_section=xc_section, &
     704              :                                   weights=weights, pw_pool=xc_pw_pool, &
     705           72 :                                   compute_virial=compute_virial, virial_xc=virial_xc_tmp)
     706              :             ! add to the existing work_v_rspace
     707           72 :             CALL pw_axpy(vxc(1), work_v_rspace, -dft_control%sic_scaling_b*vxc(1)%pw_grid%dvol)
     708              :          END IF
     709          120 :          energy%exc = energy%exc - dft_control%sic_scaling_b*exc
     710              : 
     711          280 :          IF (.NOT. just_energy) THEN
     712              :             ! note, orb_h (which is being pointed to with orb_h_p) is zeroed above
     713              :             CALL integrate_v_rspace(v_rspace=work_v_rspace, pmat=orb_density_matrix_p, hmat=orb_h_p, &
     714           72 :                                     qs_env=qs_env, calculate_forces=calculate_forces)
     715              : 
     716              :             ! add this to the mo_derivs
     717           72 :             CALL cp_dbcsr_sm_fm_multiply(orb_h, matrix_v, matrix_hv, 1)
     718              :             ! silly trick, copy to an array of the right size and add to mo_derivs
     719           72 :             CALL cp_fm_set_all(mo_derivs_local(sic_orbital_list(3, iorb)), 0.0_dp)
     720           72 :             CALL cp_fm_to_fm(matrix_hv, mo_derivs_local(sic_orbital_list(3, iorb)), 1, 1, sic_orbital_list(2, iorb))
     721              :             CALL copy_fm_to_dbcsr(mo_derivs_local(sic_orbital_list(3, iorb)), &
     722           72 :                                   tmp_dbcsr(sic_orbital_list(3, iorb))%matrix)
     723              :             CALL dbcsr_add(mo_derivs(sic_orbital_list(3, iorb))%matrix, &
     724           72 :                            tmp_dbcsr(sic_orbital_list(3, iorb))%matrix, 1.0_dp, 1.0_dp)
     725              :             !
     726              :             ! need to deallocate vxc
     727           72 :             CALL xc_pw_pool%give_back_pw(vxc(1))
     728           72 :             CALL xc_pw_pool%give_back_pw(vxc(2))
     729           72 :             DEALLOCATE (vxc)
     730              : 
     731              :          END IF
     732              : 
     733              :       END DO
     734              : 
     735           40 :       CALL auxbas_pw_pool%give_back_pw(orb_rho_r)
     736           40 :       CALL auxbas_pw_pool%give_back_pw(tmp_r)
     737           40 :       CALL auxbas_pw_pool%give_back_pw(orb_rho_g)
     738           40 :       CALL auxbas_pw_pool%give_back_pw(tmp_g)
     739           40 :       CALL auxbas_pw_pool%give_back_pw(work_v_gspace)
     740           40 :       CALL auxbas_pw_pool%give_back_pw(work_v_rspace)
     741              : 
     742           40 :       CALL dbcsr_deallocate_matrix(orb_density_matrix)
     743           40 :       CALL dbcsr_deallocate_matrix(orb_h)
     744           40 :       CALL cp_fm_release(matrix_v)
     745           40 :       CALL cp_fm_release(matrix_hv)
     746           40 :       CALL cp_fm_release(mo_derivs_local)
     747           40 :       DEALLOCATE (rho_r)
     748           40 :       DEALLOCATE (rho_g)
     749              : 
     750           40 :       CALL dbcsr_deallocate_matrix_set(tmp_dbcsr) !fm->dbcsr
     751              : 
     752           40 :       CALL timestop(handle)
     753              : 
     754       124279 :    END SUBROUTINE sic_explicit_orbitals
     755              : 
     756              : ! **************************************************************************************************
     757              : !> \brief do sic calculations on the spin density
     758              : !> \param v_sic_rspace ...
     759              : !> \param energy ...
     760              : !> \param qs_env ...
     761              : !> \param dft_control ...
     762              : !> \param rho ...
     763              : !> \param poisson_env ...
     764              : !> \param just_energy ...
     765              : !> \param calculate_forces ...
     766              : !> \param auxbas_pw_pool ...
     767              : ! **************************************************************************************************
     768       124119 :    SUBROUTINE calc_v_sic_rspace(v_sic_rspace, energy, &
     769              :                                 qs_env, dft_control, rho, poisson_env, just_energy, &
     770              :                                 calculate_forces, auxbas_pw_pool)
     771              : 
     772              :       TYPE(pw_r3d_rs_type), POINTER                      :: v_sic_rspace
     773              :       TYPE(qs_energy_type), POINTER                      :: energy
     774              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     775              :       TYPE(dft_control_type), POINTER                    :: dft_control
     776              :       TYPE(qs_rho_type), POINTER                         :: rho
     777              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
     778              :       LOGICAL, INTENT(IN)                                :: just_energy, calculate_forces
     779              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     780              : 
     781              :       INTEGER                                            :: i, nelec, nelec_a, nelec_b, nforce
     782              :       REAL(kind=dp)                                      :: ener, full_scaling, scaling
     783       124119 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: store_forces
     784       124119 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mo_array
     785              :       TYPE(pw_c1d_gs_type)                               :: work_rho, work_v
     786       124119 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g
     787       124119 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     788              : 
     789       124119 :       NULLIFY (mo_array, rho_g)
     790              : 
     791       124119 :       IF (dft_control%sic_method_id == sic_none) RETURN
     792          336 :       IF (dft_control%sic_method_id == sic_eo) RETURN
     793              : 
     794          296 :       IF (dft_control%qs_control%gapw) THEN
     795            0 :          CPABORT("sic and GAPW not yet compatible")
     796              :       END IF
     797              : 
     798              :       ! OK, right now we like two spins to do sic, could be relaxed for AD
     799          296 :       CPASSERT(dft_control%nspins == 2)
     800              : 
     801          296 :       CALL auxbas_pw_pool%create_pw(work_rho)
     802          296 :       CALL auxbas_pw_pool%create_pw(work_v)
     803              : 
     804          296 :       CALL qs_rho_get(rho, rho_g=rho_g)
     805              : 
     806              :       ! Hartree sic corrections
     807          566 :       SELECT CASE (dft_control%sic_method_id)
     808              :       CASE (sic_mauri_us, sic_mauri_spz)
     809          270 :          CALL pw_copy(rho_g(1), work_rho)
     810          270 :          CALL pw_axpy(rho_g(2), work_rho, alpha=-1._dp)
     811          296 :          CALL pw_poisson_solve(poisson_env, work_rho, ener, work_v)
     812              :       CASE (sic_ad)
     813              :          ! find out how many elecs we have
     814           26 :          CALL get_qs_env(qs_env, mos=mo_array)
     815           26 :          CALL get_mo_set(mo_set=mo_array(1), nelectron=nelec_a)
     816           26 :          CALL get_mo_set(mo_set=mo_array(2), nelectron=nelec_b)
     817           26 :          nelec = nelec_a + nelec_b
     818           26 :          CALL pw_copy(rho_g(1), work_rho)
     819           26 :          CALL pw_axpy(rho_g(2), work_rho)
     820           26 :          scaling = 1.0_dp/REAL(nelec, KIND=dp)
     821           26 :          CALL pw_scale(work_rho, scaling)
     822           26 :          CALL pw_poisson_solve(poisson_env, work_rho, ener, work_v)
     823              :       CASE DEFAULT
     824          618 :          CPABORT("Unknown sic method id")
     825              :       END SELECT
     826              : 
     827              :       ! Correct for  DDAP charges (if any)
     828              :       ! storing whatever force might be there from previous decoupling
     829          296 :       IF (calculate_forces) THEN
     830           48 :          CALL get_qs_env(qs_env=qs_env, force=force)
     831           48 :          nforce = 0
     832          112 :          DO i = 1, SIZE(force)
     833          112 :             nforce = nforce + SIZE(force(i)%ch_pulay, 2)
     834              :          END DO
     835          144 :          ALLOCATE (store_forces(3, nforce))
     836          112 :          nforce = 0
     837          112 :          DO i = 1, SIZE(force)
     838          784 :             store_forces(1:3, nforce + 1:nforce + SIZE(force(i)%ch_pulay, 2)) = force(i)%ch_pulay(:, :)
     839          784 :             force(i)%ch_pulay(:, :) = 0.0_dp
     840          112 :             nforce = nforce + SIZE(force(i)%ch_pulay, 2)
     841              :          END DO
     842              :       END IF
     843              : 
     844              :       CALL cp_ddapc_apply_CD(qs_env, &
     845              :                              work_rho, &
     846              :                              ener, &
     847              :                              v_hartree_gspace=work_v, &
     848              :                              calculate_forces=calculate_forces, &
     849          296 :                              Itype_of_density="SPIN")
     850              : 
     851          566 :       SELECT CASE (dft_control%sic_method_id)
     852              :       CASE (sic_mauri_us, sic_mauri_spz)
     853          270 :          full_scaling = -dft_control%sic_scaling_a
     854              :       CASE (sic_ad)
     855           26 :          full_scaling = -dft_control%sic_scaling_a*nelec
     856              :       CASE DEFAULT
     857          296 :          CPABORT("Unknown sic method id")
     858              :       END SELECT
     859          296 :       energy%hartree = energy%hartree + full_scaling*ener
     860              : 
     861              :       ! add scaled forces, restoring the old
     862          296 :       IF (calculate_forces) THEN
     863           48 :          nforce = 0
     864          112 :          DO i = 1, SIZE(force)
     865              :             force(i)%ch_pulay(:, :) = force(i)%ch_pulay(:, :)*full_scaling + &
     866          784 :                                       store_forces(1:3, nforce + 1:nforce + SIZE(force(i)%ch_pulay, 2))
     867          112 :             nforce = nforce + SIZE(force(i)%ch_pulay, 2)
     868              :          END DO
     869              :       END IF
     870              : 
     871          296 :       IF (.NOT. just_energy) THEN
     872          200 :          ALLOCATE (v_sic_rspace)
     873          200 :          CALL auxbas_pw_pool%create_pw(v_sic_rspace)
     874          200 :          CALL pw_transfer(work_v, v_sic_rspace)
     875              :          ! also take into account the scaling (in addition to the volume element)
     876              :          CALL pw_scale(v_sic_rspace, &
     877          200 :                        dft_control%sic_scaling_a*v_sic_rspace%pw_grid%dvol)
     878              :       END IF
     879              : 
     880          296 :       CALL auxbas_pw_pool%give_back_pw(work_rho)
     881          296 :       CALL auxbas_pw_pool%give_back_pw(work_v)
     882              : 
     883       124415 :    END SUBROUTINE calc_v_sic_rspace
     884              : 
     885              : ! **************************************************************************************************
     886              : !> \brief ...
     887              : !> \param qs_env ...
     888              : !> \param rho ...
     889              : ! **************************************************************************************************
     890       248194 :    SUBROUTINE print_densities(qs_env, rho)
     891              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     892              :       TYPE(qs_rho_type), POINTER                         :: rho
     893              : 
     894              :       INTEGER                                            :: img, ispin, n_electrons, output_unit
     895              :       REAL(dp)                                           :: tot1_h, tot1_s, tot_rho_r, trace, &
     896              :                                                             trace_tmp
     897       124097 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: tot_rho_r_arr
     898              :       TYPE(cell_type), POINTER                           :: cell
     899              :       TYPE(cp_logger_type), POINTER                      :: logger
     900       124097 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_s, rho_ao
     901              :       TYPE(dft_control_type), POINTER                    :: dft_control
     902              :       TYPE(qs_charges_type), POINTER                     :: qs_charges
     903       124097 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     904              :       TYPE(section_vals_type), POINTER                   :: input, scf_section
     905              : 
     906       124097 :       NULLIFY (qs_charges, qs_kind_set, cell, input, logger, scf_section, matrix_s, &
     907       124097 :                dft_control, tot_rho_r_arr, rho_ao)
     908              : 
     909       248194 :       logger => cp_get_default_logger()
     910              : 
     911              :       CALL get_qs_env(qs_env, &
     912              :                       qs_kind_set=qs_kind_set, &
     913              :                       cell=cell, qs_charges=qs_charges, &
     914              :                       input=input, &
     915              :                       matrix_s_kp=matrix_s, &
     916       124097 :                       dft_control=dft_control)
     917              : 
     918       124097 :       CALL get_qs_kind_set(qs_kind_set, nelectron=n_electrons)
     919              : 
     920       124097 :       scf_section => section_vals_get_subs_vals(input, "DFT%SCF")
     921              :       output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%TOTAL_DENSITIES", &
     922       124097 :                                          extension=".scfLog")
     923              : 
     924       124097 :       CALL qs_rho_get(rho, tot_rho_r=tot_rho_r_arr, rho_ao_kp=rho_ao)
     925       124097 :       n_electrons = n_electrons - dft_control%charge
     926       124097 :       tot_rho_r = accurate_sum(tot_rho_r_arr)
     927              : 
     928       124097 :       trace = 0
     929       124097 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, scf_section, "PRINT%TOTAL_DENSITIES"), cp_p_file)) THEN
     930         4140 :          DO ispin = 1, dft_control%nspins
     931         7504 :             DO img = 1, dft_control%nimages
     932         3364 :                CALL dbcsr_dot(rho_ao(ispin, img)%matrix, matrix_s(1, img)%matrix, trace_tmp)
     933         5832 :                trace = trace + trace_tmp
     934              :             END DO
     935              :          END DO
     936              :       END IF
     937              : 
     938       124097 :       IF (output_unit > 0) THEN
     939          836 :          WRITE (UNIT=output_unit, FMT="(/,T3,A,T41,F20.10)") "Trace(PS):", trace
     940              :          WRITE (UNIT=output_unit, FMT="((T3,A,T41,2F20.10))") &
     941          836 :             "Electronic density on regular grids: ", &
     942          836 :             tot_rho_r, &
     943              :             tot_rho_r + &
     944          836 :             REAL(n_electrons, dp), &
     945          836 :             "Core density on regular grids:", &
     946          836 :             qs_charges%total_rho_core_rspace, &
     947              :             qs_charges%total_rho_core_rspace + &
     948              :             qs_charges%total_rho1_hard_nuc - &
     949         1672 :             REAL(n_electrons + dft_control%charge, dp)
     950              :       END IF
     951       124097 :       IF (dft_control%qs_control%gapw) THEN
     952        22362 :          tot1_h = qs_charges%total_rho1_hard(1)
     953        22362 :          tot1_s = qs_charges%total_rho1_soft(1)
     954        26450 :          DO ispin = 2, dft_control%nspins
     955         4088 :             tot1_h = tot1_h + qs_charges%total_rho1_hard(ispin)
     956        26450 :             tot1_s = tot1_s + qs_charges%total_rho1_soft(ispin)
     957              :          END DO
     958        22362 :          IF (output_unit > 0) THEN
     959              :             WRITE (UNIT=output_unit, FMT="((T3,A,T41,2F20.10))") &
     960          398 :                "Hard and soft densities (Lebedev):", &
     961          796 :                tot1_h, tot1_s
     962              :             WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
     963          398 :                "Total Rho_soft + Rho1_hard - Rho1_soft (r-space): ", &
     964          398 :                tot_rho_r + tot1_h - tot1_s, &
     965          398 :                "Total charge density (r-space):      ", &
     966              :                tot_rho_r + tot1_h - tot1_s &
     967              :                + qs_charges%total_rho_core_rspace &
     968          796 :                + qs_charges%total_rho1_hard_nuc
     969          398 :             IF (qs_charges%total_rho1_hard_nuc /= 0.0_dp) THEN
     970              :                WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
     971            0 :                   "Total CNEO nuc. char. den. (Lebedev): ", &
     972            0 :                   qs_charges%total_rho1_hard_nuc, &
     973            0 :                   "Total CNEO soft char. den. (Lebedev): ", &
     974            0 :                   qs_charges%total_rho1_soft_nuc_lebedev, &
     975            0 :                   "Total CNEO soft char. den. (r-space): ", &
     976            0 :                   qs_charges%total_rho1_soft_nuc_rspace, &
     977            0 :                   "Total soft Rho_e+n+0 (g-space):", &
     978            0 :                   qs_charges%total_rho_gspace
     979              :             ELSE
     980              :                WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
     981          398 :                   "Total Rho_soft + Rho0_soft (g-space):", &
     982          796 :                   qs_charges%total_rho_gspace
     983              :             END IF
     984              :          END IF
     985              :          qs_charges%background = tot_rho_r + tot1_h - tot1_s + &
     986              :                                  qs_charges%total_rho_core_rspace + &
     987        22362 :                                  qs_charges%total_rho1_hard_nuc
     988              :          ! only add total_rho1_hard_nuc for gapw as cneo requires gapw
     989       101735 :       ELSE IF (dft_control%qs_control%gapw_xc) THEN
     990         4336 :          tot1_h = qs_charges%total_rho1_hard(1)
     991         4336 :          tot1_s = qs_charges%total_rho1_soft(1)
     992         4714 :          DO ispin = 2, dft_control%nspins
     993          378 :             tot1_h = tot1_h + qs_charges%total_rho1_hard(ispin)
     994         4714 :             tot1_s = tot1_s + qs_charges%total_rho1_soft(ispin)
     995              :          END DO
     996         4336 :          IF (output_unit > 0) THEN
     997              :             WRITE (UNIT=output_unit, FMT="(/,(T3,A,T41,2F20.10))") &
     998            0 :                "Hard and soft densities (Lebedev):", &
     999            0 :                tot1_h, tot1_s
    1000              :             WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
    1001            0 :                "Total Rho_soft + Rho1_hard - Rho1_soft (r-space): ", &
    1002            0 :                accurate_sum(tot_rho_r_arr) + tot1_h - tot1_s
    1003              :          END IF
    1004              :          qs_charges%background = tot_rho_r + &
    1005         4336 :                                  qs_charges%total_rho_core_rspace
    1006              :       ELSE
    1007        97399 :          IF (output_unit > 0) THEN
    1008              :             WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
    1009          438 :                "Total charge density on r-space grids:     ", &
    1010              :                tot_rho_r + &
    1011          438 :                qs_charges%total_rho_core_rspace, &
    1012          438 :                "Total charge density g-space grids:     ", &
    1013          876 :                qs_charges%total_rho_gspace
    1014              :          END IF
    1015              :          qs_charges%background = tot_rho_r + &
    1016        97399 :                                  qs_charges%total_rho_core_rspace
    1017              :       END IF
    1018       124097 :       IF (output_unit > 0) WRITE (UNIT=output_unit, FMT="()")
    1019       124097 :       qs_charges%background = qs_charges%background/cell%deth
    1020              : 
    1021              :       CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
    1022       124097 :                                         "PRINT%TOTAL_DENSITIES")
    1023              : 
    1024       124097 :    END SUBROUTINE print_densities
    1025              : 
    1026              : ! **************************************************************************************************
    1027              : !> \brief Print detailed energies
    1028              : !>
    1029              : !> \param qs_env ...
    1030              : !> \param dft_control ...
    1031              : !> \param input ...
    1032              : !> \param energy ...
    1033              : !> \param mulliken_order_p ...
    1034              : !> \par History
    1035              : !>    refactoring 04.03.2011 [MI]
    1036              : !> \author
    1037              : ! **************************************************************************************************
    1038       124097 :    SUBROUTINE print_detailed_energy(qs_env, dft_control, input, energy, mulliken_order_p)
    1039              : 
    1040              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1041              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1042              :       TYPE(section_vals_type), POINTER                   :: input
    1043              :       TYPE(qs_energy_type), POINTER                      :: energy
    1044              :       REAL(KIND=dp), INTENT(IN)                          :: mulliken_order_p
    1045              : 
    1046              :       INTEGER                                            :: bc, n, output_unit, psolver
    1047              :       REAL(KIND=dp)                                      :: ddapc_order_p, implicit_ps_ehartree, &
    1048              :                                                             s2_order_p
    1049              :       TYPE(cp_logger_type), POINTER                      :: logger
    1050              :       TYPE(pw_env_type), POINTER                         :: pw_env
    1051              : 
    1052       124097 :       logger => cp_get_default_logger()
    1053              : 
    1054       124097 :       NULLIFY (pw_env)
    1055       124097 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
    1056       124097 :       psolver = pw_env%poisson_env%parameters%solver
    1057              : 
    1058              :       output_unit = cp_print_key_unit_nr(logger, input, "DFT%SCF%PRINT%DETAILED_ENERGY", &
    1059       124097 :                                          extension=".scfLog")
    1060       124097 :       IF (output_unit > 0) THEN
    1061          490 :          IF (dft_control%do_admm) THEN
    1062              :             WRITE (UNIT=output_unit, FMT="((T3,A,T60,F20.10))") &
    1063            0 :                "Wfn fit exchange-correlation energy:            ", energy%exc_aux_fit
    1064            0 :             IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
    1065              :                WRITE (UNIT=output_unit, FMT="((T3,A,T60,F20.10))") &
    1066            0 :                   "Wfn fit soft/hard atomic rho1 Exc contribution: ", energy%exc1_aux_fit
    1067              :             END IF
    1068              :          END IF
    1069          490 :          IF (dft_control%do_admm) THEN
    1070            0 :             IF (psolver == pw_poisson_implicit) THEN
    1071            0 :                implicit_ps_ehartree = pw_env%poisson_env%implicit_env%ehartree
    1072            0 :                bc = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
    1073            0 :                SELECT CASE (bc)
    1074              :                CASE (MIXED_PERIODIC_BC, MIXED_BC)
    1075              :                   WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1076            0 :                      "Core Hamiltonian energy:                       ", energy%core, &
    1077            0 :                      "Hartree energy:                                ", implicit_ps_ehartree, &
    1078            0 :                      "Electric enthalpy:                             ", energy%hartree, &
    1079            0 :                      "Exchange-correlation energy:                   ", energy%exc + energy%exc_aux_fit
    1080              :                CASE (PERIODIC_BC, NEUMANN_BC)
    1081              :                   WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1082            0 :                      "Core Hamiltonian energy:                       ", energy%core, &
    1083            0 :                      "Hartree energy:                                ", energy%hartree, &
    1084            0 :                      "Exchange-correlation energy:                   ", energy%exc + energy%exc_aux_fit
    1085              :                END SELECT
    1086              :             ELSE
    1087              :                WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1088            0 :                   "Core Hamiltonian energy:                       ", energy%core, &
    1089            0 :                   "Hartree energy:                                ", energy%hartree, &
    1090            0 :                   "Exchange-correlation energy:                   ", energy%exc + energy%exc_aux_fit
    1091              :             END IF
    1092              :          ELSE
    1093              :             !ZMP to print some variables at each step
    1094          490 :             IF (dft_control%apply_external_density) THEN
    1095              :                WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1096            0 :                   "DOING ZMP CALCULATION FROM EXTERNAL DENSITY    "
    1097              :                WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1098            0 :                   "Core Hamiltonian energy:                       ", energy%core, &
    1099            0 :                   "Hartree energy:                                ", energy%hartree
    1100          490 :             ELSE IF (dft_control%apply_external_vxc) THEN
    1101              :                WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1102            0 :                   "DOING ZMP READING EXTERNAL VXC                 "
    1103              :                WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1104            0 :                   "Core Hamiltonian energy:                       ", energy%core, &
    1105            0 :                   "Hartree energy:                                ", energy%hartree
    1106              :             ELSE
    1107          490 :                IF (psolver == pw_poisson_implicit) THEN
    1108            0 :                   implicit_ps_ehartree = pw_env%poisson_env%implicit_env%ehartree
    1109            0 :                   bc = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
    1110            0 :                   SELECT CASE (bc)
    1111              :                   CASE (MIXED_PERIODIC_BC, MIXED_BC)
    1112              :                      WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1113            0 :                         "Core Hamiltonian energy:                       ", energy%core, &
    1114            0 :                         "Hartree energy:                                ", implicit_ps_ehartree, &
    1115            0 :                         "Electric enthalpy:                             ", energy%hartree, &
    1116            0 :                         "Exchange-correlation energy:                   ", energy%exc
    1117              :                   CASE (PERIODIC_BC, NEUMANN_BC)
    1118              :                      WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1119            0 :                         "Core Hamiltonian energy:                       ", energy%core, &
    1120            0 :                         "Hartree energy:                                ", energy%hartree, &
    1121            0 :                         "Exchange-correlation energy:                   ", energy%exc
    1122              :                   END SELECT
    1123              :                ELSE
    1124              :                   WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1125          490 :                      "Core Hamiltonian energy:                       ", energy%core, &
    1126          490 :                      "Hartree energy:                                ", energy%hartree, &
    1127          980 :                      "Exchange-correlation energy:                   ", energy%exc
    1128              :                END IF
    1129              :             END IF
    1130              :          END IF
    1131              : 
    1132          490 :          IF (dft_control%apply_external_density) THEN
    1133              :             WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1134            0 :                "Integral of the (density * v_xc):              ", energy%exc
    1135              :          END IF
    1136              : 
    1137          490 :          IF (energy%e_hartree /= 0.0_dp) THEN
    1138              :             WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
    1139          458 :                "Coulomb (electron-electron) energy:            ", energy%e_hartree
    1140              :          END IF
    1141          490 :          IF (energy%dispersion /= 0.0_dp) THEN
    1142              :             WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
    1143            0 :                "Dispersion energy:                             ", energy%dispersion
    1144              :          END IF
    1145          490 :          IF (energy%efield /= 0.0_dp) THEN
    1146              :             WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
    1147            0 :                "Electric field interaction energy:             ", energy%efield
    1148              :          END IF
    1149          490 :          IF (energy%gcp /= 0.0_dp) THEN
    1150              :             WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
    1151            0 :                "gCP energy:                                    ", energy%gcp
    1152              :          END IF
    1153          490 :          IF (dft_control%qs_control%gapw) THEN
    1154              :             WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1155           32 :                "GAPW| Exc from hard and soft atomic rho1:      ", energy%exc1 + energy%exc1_aux_fit, &
    1156           64 :                "GAPW| local Eh = 1 center integrals:           ", energy%hartree_1c
    1157              :          END IF
    1158          490 :          IF (dft_control%qs_control%gapw_xc) THEN
    1159              :             WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
    1160            0 :                "GAPW| Exc from hard and soft atomic rho1:      ", energy%exc1 + energy%exc1_aux_fit
    1161              :          END IF
    1162          490 :          IF (dft_control%dft_plus_u) THEN
    1163              :             WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
    1164            0 :                "DFT+U energy:", energy%dft_plus_u
    1165              :          END IF
    1166          490 :          IF (qs_env%qmmm) THEN
    1167              :             WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
    1168            0 :                "QM/MM Electrostatic energy:                    ", energy%qmmm_el
    1169            0 :             IF (qs_env%qmmm_env_qm%image_charge) THEN
    1170              :                WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
    1171            0 :                   "QM/MM image charge energy:                ", energy%image_charge
    1172              :             END IF
    1173              :          END IF
    1174          490 :          IF (dft_control%qs_control%mulliken_restraint) THEN
    1175              :             WRITE (UNIT=output_unit, FMT="(T3,A,T41,2F20.10)") &
    1176            0 :                "Mulliken restraint (order_p,energy) : ", mulliken_order_p, energy%mulliken
    1177              :          END IF
    1178          490 :          IF (dft_control%qs_control%ddapc_restraint) THEN
    1179           40 :             DO n = 1, SIZE(dft_control%qs_control%ddapc_restraint_control)
    1180              :                ddapc_order_p = &
    1181           20 :                   dft_control%qs_control%ddapc_restraint_control(n)%ddapc_order_p
    1182              :                WRITE (UNIT=output_unit, FMT="(T3,A,T41,2F20.10)") &
    1183           40 :                   "DDAPC restraint (order_p,energy) : ", ddapc_order_p, energy%ddapc_restraint(n)
    1184              :             END DO
    1185              :          END IF
    1186          490 :          IF (dft_control%qs_control%s2_restraint) THEN
    1187            0 :             s2_order_p = dft_control%qs_control%s2_restraint_control%s2_order_p
    1188              :             WRITE (UNIT=output_unit, FMT="(T3,A,T41,2F20.10)") &
    1189            0 :                "S2 restraint (order_p,energy) : ", s2_order_p, energy%s2_restraint
    1190              :          END IF
    1191          490 :          IF (energy%core_cneo /= 0.0_dp) THEN
    1192              :             WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
    1193            0 :                "CNEO| quantum nuclear core energy: ", energy%core_cneo
    1194              :          END IF
    1195              : 
    1196              :       END IF ! output_unit
    1197              :       CALL cp_print_key_finished_output(output_unit, logger, input, &
    1198       124097 :                                         "DFT%SCF%PRINT%DETAILED_ENERGY")
    1199              : 
    1200       124097 :    END SUBROUTINE print_detailed_energy
    1201              : 
    1202              : ! **************************************************************************************************
    1203              : !> \brief compute matrix_vxc, defined via the potential created by qs_vxc_create
    1204              : !>        ignores things like tau functional, gapw, sic, ...
    1205              : !>         so only OK for GGA & GPW right now
    1206              : !> \param qs_env ...
    1207              : !> \param v_rspace ...
    1208              : !> \param matrix_vxc ...
    1209              : !> \param gapw_full_basis ...
    1210              : !> \par History
    1211              : !>    created 23.10.2012 [Joost VandeVondele]
    1212              : !> \author
    1213              : ! **************************************************************************************************
    1214            8 :    SUBROUTINE compute_matrix_vxc(qs_env, v_rspace, matrix_vxc, gapw_full_basis)
    1215              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1216              :       TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN)     :: v_rspace
    1217              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_vxc
    1218              :       LOGICAL, INTENT(IN), OPTIONAL                      :: gapw_full_basis
    1219              : 
    1220              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_matrix_vxc'
    1221              : 
    1222              :       INTEGER                                            :: handle, ispin
    1223              :       LOGICAL                                            :: gapw
    1224            8 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks
    1225              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1226              : 
    1227            8 :       CALL timeset(routineN, handle)
    1228              : 
    1229              :       ! create the matrix using matrix_ks as a template
    1230            8 :       IF (ASSOCIATED(matrix_vxc)) THEN
    1231            0 :          CALL dbcsr_deallocate_matrix_set(matrix_vxc)
    1232              :       END IF
    1233            8 :       CALL get_qs_env(qs_env, matrix_ks=matrix_ks)
    1234           36 :       ALLOCATE (matrix_vxc(SIZE(matrix_ks)))
    1235           20 :       DO ispin = 1, SIZE(matrix_ks)
    1236           12 :          NULLIFY (matrix_vxc(ispin)%matrix)
    1237           12 :          CALL dbcsr_init_p(matrix_vxc(ispin)%matrix)
    1238              :          CALL dbcsr_copy(matrix_vxc(ispin)%matrix, matrix_ks(ispin)%matrix, &
    1239           12 :                          name="Matrix VXC of spin "//cp_to_string(ispin))
    1240           20 :          CALL dbcsr_set(matrix_vxc(ispin)%matrix, 0.0_dp)
    1241              :       END DO
    1242              : 
    1243              :       ! and integrate
    1244            8 :       CALL get_qs_env(qs_env, dft_control=dft_control)
    1245            8 :       gapw = dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc
    1246            8 :       IF (PRESENT(gapw_full_basis)) THEN
    1247            0 :          IF (gapw_full_basis) gapw = .FALSE.
    1248              :       END IF
    1249           20 :       DO ispin = 1, SIZE(matrix_ks)
    1250              :          CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
    1251              :                                  hmat=matrix_vxc(ispin), &
    1252              :                                  qs_env=qs_env, &
    1253              :                                  calculate_forces=.FALSE., &
    1254           12 :                                  gapw=gapw)
    1255              :          ! scale by the volume element... should really become part of integrate_v_rspace
    1256           20 :          CALL dbcsr_scale(matrix_vxc(ispin)%matrix, v_rspace(ispin)%pw_grid%dvol)
    1257              :       END DO
    1258              : 
    1259            8 :       CALL timestop(handle)
    1260              : 
    1261            8 :    END SUBROUTINE compute_matrix_vxc
    1262              : 
    1263              : ! **************************************************************************************************
    1264              : !> \brief Build the XC potential matrix for k-point/image-resolved KS matrices.
    1265              : !> \param qs_env Quickstep environment
    1266              : !> \param v_rspace XC potential on the real-space grid
    1267              : !> \param matrix_vxc_kp k-point/image-resolved XC potential matrix
    1268              : !> \param gapw_full_basis ...
    1269              : !> \author
    1270              : ! **************************************************************************************************
    1271            0 :    SUBROUTINE compute_matrix_vxc_kp(qs_env, v_rspace, matrix_vxc_kp, gapw_full_basis)
    1272              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1273              :       TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN)     :: v_rspace
    1274              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_vxc_kp
    1275              :       LOGICAL, INTENT(IN), OPTIONAL                      :: gapw_full_basis
    1276              : 
    1277              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_matrix_vxc_kp'
    1278              : 
    1279              :       INTEGER                                            :: handle, img, ispin
    1280              :       LOGICAL                                            :: gapw
    1281            0 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ksmat
    1282            0 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks_kp
    1283              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1284              : 
    1285            0 :       CALL timeset(routineN, handle)
    1286              : 
    1287              :       ! create the matrix using matrix_ks as a template
    1288            0 :       IF (ASSOCIATED(matrix_vxc_kp)) THEN
    1289            0 :          CALL dbcsr_deallocate_matrix_set(matrix_vxc_kp)
    1290              :       END IF
    1291            0 :       CALL get_qs_env(qs_env, dft_control=dft_control, matrix_ks_kp=matrix_ks_kp)
    1292            0 :       ALLOCATE (matrix_vxc_kp(SIZE(matrix_ks_kp, 1), SIZE(matrix_ks_kp, 2)))
    1293            0 :       DO img = 1, SIZE(matrix_ks_kp, 2)
    1294            0 :          DO ispin = 1, SIZE(matrix_ks_kp, 1)
    1295            0 :             NULLIFY (matrix_vxc_kp(ispin, img)%matrix)
    1296            0 :             CALL dbcsr_init_p(matrix_vxc_kp(ispin, img)%matrix)
    1297              :             CALL dbcsr_copy(matrix_vxc_kp(ispin, img)%matrix, matrix_ks_kp(ispin, img)%matrix, &
    1298            0 :                             name="Matrix VXC of spin "//cp_to_string(ispin)//" image "//cp_to_string(img))
    1299            0 :             CALL dbcsr_set(matrix_vxc_kp(ispin, img)%matrix, 0.0_dp)
    1300              :          END DO
    1301              :       END DO
    1302              : 
    1303              :       ! and integrate
    1304            0 :       gapw = dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc
    1305            0 :       IF (PRESENT(gapw_full_basis)) THEN
    1306            0 :          IF (gapw_full_basis) gapw = .FALSE.
    1307              :       END IF
    1308            0 :       DO ispin = 1, SIZE(matrix_ks_kp, 1)
    1309            0 :          ksmat => matrix_vxc_kp(ispin, :)
    1310              :          CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
    1311              :                                  hmat_kp=ksmat, &
    1312              :                                  qs_env=qs_env, &
    1313              :                                  calculate_forces=.FALSE., &
    1314            0 :                                  gapw=gapw)
    1315              :          ! scale by the volume element... should really become part of integrate_v_rspace
    1316            0 :          DO img = 1, SIZE(matrix_ks_kp, 2)
    1317            0 :             CALL dbcsr_scale(matrix_vxc_kp(ispin, img)%matrix, v_rspace(ispin)%pw_grid%dvol)
    1318              :          END DO
    1319              :       END DO
    1320              : 
    1321            0 :       CALL timestop(handle)
    1322              : 
    1323            0 :    END SUBROUTINE compute_matrix_vxc_kp
    1324              : 
    1325              : ! **************************************************************************************************
    1326              : !> \brief Sum up all potentials defined  on the grid and integrate
    1327              : !>
    1328              : !> \param qs_env ...
    1329              : !> \param ks_matrix ...
    1330              : !> \param rho ...
    1331              : !> \param my_rho ...
    1332              : !> \param vppl_rspace ...
    1333              : !> \param v_rspace_new ...
    1334              : !> \param v_rspace_new_aux_fit ...
    1335              : !> \param v_tau_rspace ...
    1336              : !> \param v_tau_rspace_aux_fit ...
    1337              : !> \param v_sic_rspace ...
    1338              : !> \param v_spin_ddapc_rest_r ...
    1339              : !> \param v_sccs_rspace ...
    1340              : !> \param v_rspace_embed ...
    1341              : !> \param cdft_control ...
    1342              : !> \param calculate_forces ...
    1343              : !> \par History
    1344              : !>      - refactoring 04.03.2011 [MI]
    1345              : !>      - SCCS implementation (16.10.2013,MK)
    1346              : !> \author
    1347              : ! **************************************************************************************************
    1348       114313 :    SUBROUTINE sum_up_and_integrate(qs_env, ks_matrix, rho, my_rho, &
    1349              :                                    vppl_rspace, v_rspace_new, &
    1350              :                                    v_rspace_new_aux_fit, v_tau_rspace, &
    1351              :                                    v_tau_rspace_aux_fit, &
    1352              :                                    v_sic_rspace, v_spin_ddapc_rest_r, &
    1353              :                                    v_sccs_rspace, v_rspace_embed, cdft_control, &
    1354              :                                    calculate_forces)
    1355              : 
    1356              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1357              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix
    1358              :       TYPE(qs_rho_type), POINTER                         :: rho
    1359              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: my_rho
    1360              :       TYPE(pw_r3d_rs_type), POINTER                      :: vppl_rspace
    1361              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_rspace_new, v_rspace_new_aux_fit, &
    1362              :                                                             v_tau_rspace, v_tau_rspace_aux_fit
    1363              :       TYPE(pw_r3d_rs_type), POINTER                      :: v_sic_rspace, v_spin_ddapc_rest_r, &
    1364              :                                                             v_sccs_rspace
    1365              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_rspace_embed
    1366              :       TYPE(cdft_control_type), POINTER                   :: cdft_control
    1367              :       LOGICAL, INTENT(in)                                :: calculate_forces
    1368              : 
    1369              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'sum_up_and_integrate'
    1370              : 
    1371              :       CHARACTER(LEN=default_string_length)               :: basis_type
    1372              :       INTEGER                                            :: handle, igroup, ikind, img, ispin, &
    1373              :                                                             nkind, nspins
    1374       114313 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
    1375              :       LOGICAL                                            :: do_ppl, gapw, gapw_composite_direct_ao, &
    1376              :                                                             gapw_composite_reference, gapw_xc, &
    1377              :                                                             lrigpw, rigpw, use_work_v_rspace
    1378              :       REAL(KIND=dp)                                      :: csign, dvol, fadm
    1379              :       TYPE(admm_type), POINTER                           :: admm_env
    1380       114313 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1381       114313 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ksmat, rho_ao, rho_ao_nokp, smat
    1382       114313 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks_aux_fit, &
    1383       114313 :                                                             matrix_ks_aux_fit_dft, rho_ao_aux, &
    1384       114313 :                                                             rho_ao_kp
    1385              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1386              :       TYPE(kpoint_type), POINTER                         :: kpoints
    1387              :       TYPE(lri_density_type), POINTER                    :: lri_density
    1388              :       TYPE(lri_environment_type), POINTER                :: lri_env
    1389       114313 :       TYPE(lri_kind_type), DIMENSION(:), POINTER         :: lri_v_int
    1390              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1391              :       TYPE(pw_env_type), POINTER                         :: pw_env
    1392              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
    1393              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1394              :       TYPE(pw_r3d_rs_type), POINTER                      :: v_rspace, v_rspace_used, vee
    1395              :       TYPE(pw_r3d_rs_type), TARGET                       :: v_rspace_work
    1396              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1397              :       TYPE(qs_rho_type), POINTER                         :: rho_aux_fit
    1398              :       TYPE(section_vals_type), POINTER                   :: input, xc_section
    1399              :       TYPE(task_list_type), POINTER                      :: task_list
    1400              : 
    1401       114313 :       CALL timeset(routineN, handle)
    1402              : 
    1403       114313 :       NULLIFY (auxbas_pw_pool, dft_control, pw_env, matrix_ks_aux_fit, &
    1404       114313 :                v_rspace, rho_aux_fit, vee, rho_ao, rho_ao_kp, rho_ao_aux, &
    1405       114313 :                ksmat, matrix_ks_aux_fit_dft, lri_env, lri_density, atomic_kind_set, &
    1406       114313 :                rho_ao_nokp, ks_env, admm_env, task_list, v_rspace_used, input, xc_section)
    1407              : 
    1408              :       CALL get_qs_env(qs_env, &
    1409              :                       dft_control=dft_control, &
    1410              :                       input=input, &
    1411              :                       pw_env=pw_env, &
    1412              :                       v_hartree_rspace=v_rspace, &
    1413       114313 :                       vee=vee)
    1414              : 
    1415       114313 :       CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
    1416       114313 :       CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
    1417       114313 :       gapw = dft_control%qs_control%gapw
    1418       114313 :       gapw_xc = dft_control%qs_control%gapw_xc
    1419       114313 :       xc_section => section_vals_get_subs_vals(input, "DFT%XC")
    1420              :       gapw_composite_reference = native_skala_gapw_composite_reference(xc_section) .AND. &
    1421       114313 :                                  (gapw .OR. gapw_xc)
    1422              :       gapw_composite_direct_ao = gapw_composite_reference .AND. &
    1423            0 :                                  native_skala_gapw_composite_direct_ao(xc_section)
    1424       114313 :       do_ppl = dft_control%qs_control%do_ppl_method == do_ppl_grid
    1425              : 
    1426       114313 :       rigpw = dft_control%qs_control%rigpw
    1427       114313 :       lrigpw = dft_control%qs_control%lrigpw
    1428       114313 :       IF (lrigpw .OR. rigpw) THEN
    1429              :          CALL get_qs_env(qs_env, &
    1430              :                          lri_env=lri_env, &
    1431              :                          lri_density=lri_density, &
    1432          488 :                          atomic_kind_set=atomic_kind_set)
    1433              :       END IF
    1434              : 
    1435       114313 :       nspins = dft_control%nspins
    1436              : 
    1437              :       ! sum up potentials and integrate
    1438       114313 :       IF (ASSOCIATED(v_rspace_new)) THEN
    1439       226983 :          DO ispin = 1, nspins
    1440       122970 :             IF (gapw_composite_reference) THEN
    1441              :                ! The direct AO diagnostic uses the full ORB basis. The reconstructed path uses
    1442              :                ! the soft basis here and adds the hard-minus-soft adjoint through update_ks_atom.
    1443            0 :                CALL pw_scale(v_rspace_new(ispin), v_rspace_new(ispin)%pw_grid%dvol)
    1444            0 :                rho_ao => rho_ao_kp(ispin, :)
    1445            0 :                ksmat => ks_matrix(ispin, :)
    1446              :                CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
    1447              :                                        pmat_kp=rho_ao, hmat_kp=ksmat, &
    1448              :                                        qs_env=qs_env, &
    1449              :                                        calculate_forces=calculate_forces, &
    1450            0 :                                        gapw=gapw .AND. .NOT. gapw_composite_direct_ao)
    1451            0 :                CALL pw_copy(v_rspace, v_rspace_new(ispin))
    1452       122970 :             ELSE IF (gapw_xc) THEN
    1453              :                ! SIC not implemented (or at least not tested)
    1454         4336 :                CPASSERT(dft_control%sic_method_id == sic_none)
    1455              :                !Only the xc potential, because it has to be integrated with the soft basis
    1456         4336 :                CALL pw_scale(v_rspace_new(ispin), v_rspace_new(ispin)%pw_grid%dvol)
    1457              : 
    1458              :                ! add the xc  part due to v_rspace soft
    1459         4336 :                rho_ao => rho_ao_kp(ispin, :)
    1460         4336 :                ksmat => ks_matrix(ispin, :)
    1461              :                CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
    1462              :                                        pmat_kp=rho_ao, hmat_kp=ksmat, &
    1463              :                                        qs_env=qs_env, &
    1464              :                                        calculate_forces=calculate_forces, &
    1465         4336 :                                        gapw=gapw_xc)
    1466              : 
    1467              :                ! Now the Hartree potential to be integrated with the full basis
    1468         4336 :                CALL pw_copy(v_rspace, v_rspace_new(ispin))
    1469              :             ELSE
    1470              :                ! Add v_hartree + v_xc = v_rspace_new
    1471       118634 :                CALL pw_axpy(v_rspace, v_rspace_new(ispin), 1.0_dp, v_rspace_new(ispin)%pw_grid%dvol)
    1472              :             END IF ! gapw_xc
    1473       122970 :             IF (dft_control%qs_control%ddapc_explicit_potential) THEN
    1474          184 :                IF (dft_control%qs_control%ddapc_restraint_is_spin) THEN
    1475          184 :                   IF (ispin == 1) THEN
    1476           92 :                      CALL pw_axpy(v_spin_ddapc_rest_r, v_rspace_new(ispin), 1.0_dp)
    1477              :                   ELSE
    1478           92 :                      CALL pw_axpy(v_spin_ddapc_rest_r, v_rspace_new(ispin), -1.0_dp)
    1479              :                   END IF
    1480              :                ELSE
    1481            0 :                   CALL pw_axpy(v_spin_ddapc_rest_r, v_rspace_new(ispin), 1.0_dp)
    1482              :                END IF
    1483              :             END IF
    1484              :             ! CDFT constraint contribution
    1485       122970 :             IF (dft_control%qs_control%cdft) THEN
    1486        12484 :                DO igroup = 1, SIZE(cdft_control%group)
    1487         7256 :                   SELECT CASE (cdft_control%group(igroup)%constraint_type)
    1488              :                   CASE (cdft_charge_constraint)
    1489           16 :                      csign = 1.0_dp
    1490              :                   CASE (cdft_magnetization_constraint)
    1491           16 :                      IF (ispin == 1) THEN
    1492              :                         csign = 1.0_dp
    1493              :                      ELSE
    1494            8 :                         csign = -1.0_dp
    1495              :                      END IF
    1496              :                   CASE (cdft_alpha_constraint)
    1497         2020 :                      csign = 1.0_dp
    1498         2020 :                      IF (ispin == 2) CYCLE
    1499              :                   CASE (cdft_beta_constraint)
    1500         2020 :                      csign = 1.0_dp
    1501         2020 :                      IF (ispin == 1) CYCLE
    1502              :                   CASE DEFAULT
    1503         7256 :                      CPABORT("Unknown constraint type.")
    1504              :                   END SELECT
    1505              :                   CALL pw_axpy(cdft_control%group(igroup)%weight, v_rspace_new(ispin), &
    1506        12484 :                                csign*cdft_control%strength(igroup))
    1507              :                END DO
    1508              :             END IF
    1509              :             ! functional derivative of the Hartree energy wrt the density in the presence of dielectric
    1510              :             ! (vhartree + v_eps); v_eps is nonzero only if the dielectric constant is defind as a function
    1511              :             ! of the charge density
    1512       122970 :             IF (poisson_env%parameters%solver == pw_poisson_implicit) THEN
    1513          440 :                dvol = poisson_env%implicit_env%v_eps%pw_grid%dvol
    1514          440 :                CALL pw_axpy(poisson_env%implicit_env%v_eps, v_rspace_new(ispin), dvol)
    1515              :             END IF
    1516              :             ! Add SCCS contribution
    1517       122970 :             IF (dft_control%do_sccs) THEN
    1518          188 :                CALL pw_axpy(v_sccs_rspace, v_rspace_new(ispin))
    1519              :             END IF
    1520              :             ! External electrostatic potential
    1521       122970 :             IF (dft_control%apply_external_potential) THEN
    1522              :                CALL qmmm_modify_hartree_pot(v_hartree=v_rspace_new(ispin), &
    1523          364 :                                             v_qmmm=vee, scale=-1.0_dp)
    1524              :             END IF
    1525       122970 :             IF (do_ppl) THEN
    1526           66 :                CPASSERT(.NOT. gapw)
    1527           66 :                CALL pw_axpy(vppl_rspace, v_rspace_new(ispin), vppl_rspace%pw_grid%dvol)
    1528              :             END IF
    1529              :             ! the electrostatic sic contribution
    1530       123330 :             SELECT CASE (dft_control%sic_method_id)
    1531              :             CASE (sic_none)
    1532              :                !
    1533              :             CASE (sic_mauri_us, sic_mauri_spz)
    1534          360 :                IF (ispin == 1) THEN
    1535          180 :                   CALL pw_axpy(v_sic_rspace, v_rspace_new(ispin), -1.0_dp)
    1536              :                ELSE
    1537          180 :                   CALL pw_axpy(v_sic_rspace, v_rspace_new(ispin), 1.0_dp)
    1538              :                END IF
    1539              :             CASE (sic_ad)
    1540       122970 :                CALL pw_axpy(v_sic_rspace, v_rspace_new(ispin), -1.0_dp)
    1541              :             CASE (sic_eo)
    1542              :                ! NOTHING TO BE DONE
    1543              :             END SELECT
    1544              :             ! DFT embedding
    1545       122970 :             IF (dft_control%apply_embed_pot) THEN
    1546          930 :                CALL pw_axpy(v_rspace_embed(ispin), v_rspace_new(ispin), v_rspace_embed(ispin)%pw_grid%dvol)
    1547          930 :                CALL auxbas_pw_pool%give_back_pw(v_rspace_embed(ispin))
    1548              :             END IF
    1549       122970 :             IF (lrigpw) THEN
    1550          474 :                lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
    1551          474 :                CALL get_qs_env(qs_env, nkind=nkind, para_env=para_env)
    1552         1418 :                DO ikind = 1, nkind
    1553       304584 :                   lri_v_int(ikind)%v_int = 0.0_dp
    1554              :                END DO
    1555              :                CALL integrate_v_rspace_one_center(v_rspace_new(ispin), qs_env, &
    1556          474 :                                                   lri_v_int, calculate_forces, "LRI_AUX")
    1557         1418 :                DO ikind = 1, nkind
    1558       607750 :                   CALL para_env%sum(lri_v_int(ikind)%v_int)
    1559              :                END DO
    1560          474 :                IF (lri_env%exact_1c_terms) THEN
    1561           36 :                   rho_ao => my_rho(ispin, :)
    1562           36 :                   ksmat => ks_matrix(ispin, :)
    1563              :                   CALL integrate_v_rspace_diagonal(v_rspace_new(ispin), ksmat(1)%matrix, &
    1564              :                                                    rho_ao(1)%matrix, qs_env, &
    1565           36 :                                                    calculate_forces, "ORB")
    1566              :                END IF
    1567          474 :                IF (lri_env%ppl_ri) THEN
    1568            8 :                   CALL v_int_ppl_update(qs_env, lri_v_int, calculate_forces)
    1569              :                END IF
    1570       122496 :             ELSE IF (rigpw) THEN
    1571           26 :                lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
    1572           26 :                CALL get_qs_env(qs_env, nkind=nkind, para_env=para_env)
    1573           52 :                DO ikind = 1, nkind
    1574         1144 :                   lri_v_int(ikind)%v_int = 0.0_dp
    1575              :                END DO
    1576              :                CALL integrate_v_rspace_one_center(v_rspace_new(ispin), qs_env, &
    1577           26 :                                                   lri_v_int, calculate_forces, "RI_HXC")
    1578           52 :                DO ikind = 1, nkind
    1579         2236 :                   CALL para_env%sum(lri_v_int(ikind)%v_int)
    1580              :                END DO
    1581              :             ELSE
    1582       122470 :                rho_ao => my_rho(ispin, :)
    1583       122470 :                ksmat => ks_matrix(ispin, :)
    1584              :                CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
    1585              :                                        pmat_kp=rho_ao, hmat_kp=ksmat, &
    1586              :                                        qs_env=qs_env, &
    1587              :                                        calculate_forces=calculate_forces, &
    1588       122470 :                                        gapw=gapw .AND. .NOT. gapw_composite_direct_ao)
    1589              :             END IF
    1590       226983 :             CALL auxbas_pw_pool%give_back_pw(v_rspace_new(ispin))
    1591              :          END DO ! ispin
    1592              : 
    1593       104213 :          SELECT CASE (dft_control%sic_method_id)
    1594              :          CASE (sic_none)
    1595              :          CASE (sic_mauri_us, sic_mauri_spz, sic_ad)
    1596          200 :             CALL auxbas_pw_pool%give_back_pw(v_sic_rspace)
    1597       104213 :             DEALLOCATE (v_sic_rspace)
    1598              :          END SELECT
    1599       104013 :          DEALLOCATE (v_rspace_new)
    1600              : 
    1601              :       ELSE
    1602              :          ! not implemented (or at least not tested)
    1603        10300 :          CPASSERT(dft_control%sic_method_id == sic_none)
    1604        10300 :          CPASSERT(.NOT. dft_control%qs_control%ddapc_restraint_is_spin)
    1605        22804 :          DO ispin = 1, nspins
    1606        12504 :             use_work_v_rspace = dft_control%qs_control%cdft
    1607        12504 :             IF (use_work_v_rspace) THEN
    1608          168 :                CALL auxbas_pw_pool%create_pw(v_rspace_work)
    1609          168 :                CALL pw_copy(v_rspace, v_rspace_work)
    1610          168 :                v_rspace_used => v_rspace_work
    1611              :             ELSE
    1612        12336 :                v_rspace_used => v_rspace
    1613              :             END IF
    1614              :             ! CDFT constraint contribution
    1615        12504 :             IF (dft_control%qs_control%cdft) THEN
    1616          336 :                DO igroup = 1, SIZE(cdft_control%group)
    1617          168 :                   SELECT CASE (cdft_control%group(igroup)%constraint_type)
    1618              :                   CASE (cdft_charge_constraint)
    1619            0 :                      csign = 1.0_dp
    1620              :                   CASE (cdft_magnetization_constraint)
    1621            0 :                      IF (ispin == 1) THEN
    1622              :                         csign = 1.0_dp
    1623              :                      ELSE
    1624            0 :                         csign = -1.0_dp
    1625              :                      END IF
    1626              :                   CASE (cdft_alpha_constraint)
    1627            0 :                      csign = 1.0_dp
    1628            0 :                      IF (ispin == 2) CYCLE
    1629              :                   CASE (cdft_beta_constraint)
    1630            0 :                      csign = 1.0_dp
    1631            0 :                      IF (ispin == 1) CYCLE
    1632              :                   CASE DEFAULT
    1633          168 :                      CPABORT("Unknown constraint type.")
    1634              :                   END SELECT
    1635              :                   CALL pw_axpy(cdft_control%group(igroup)%weight, v_rspace_used, &
    1636          336 :                                csign*cdft_control%strength(igroup))
    1637              :                END DO
    1638              :             END IF
    1639              :             ! extra contribution attributed to the dependency of the dielectric constant to the charge density
    1640        12504 :             IF (poisson_env%parameters%solver == pw_poisson_implicit) THEN
    1641            0 :                dvol = poisson_env%implicit_env%v_eps%pw_grid%dvol
    1642            0 :                CALL pw_axpy(poisson_env%implicit_env%v_eps, v_rspace_used, dvol)
    1643              :             END IF
    1644              :             ! Add SCCS contribution
    1645        12504 :             IF (dft_control%do_sccs) THEN
    1646            0 :                CALL pw_axpy(v_sccs_rspace, v_rspace_used)
    1647              :             END IF
    1648              :             ! DFT embedding
    1649        12504 :             IF (dft_control%apply_embed_pot) THEN
    1650           12 :                CALL pw_axpy(v_rspace_embed(ispin), v_rspace_used, v_rspace_embed(ispin)%pw_grid%dvol)
    1651           12 :                CALL auxbas_pw_pool%give_back_pw(v_rspace_embed(ispin))
    1652              :             END IF
    1653        12504 :             IF (lrigpw) THEN
    1654            0 :                lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
    1655            0 :                CALL get_qs_env(qs_env, nkind=nkind, para_env=para_env)
    1656            0 :                DO ikind = 1, nkind
    1657            0 :                   lri_v_int(ikind)%v_int = 0.0_dp
    1658              :                END DO
    1659              :                CALL integrate_v_rspace_one_center(v_rspace_used, qs_env, &
    1660            0 :                                                   lri_v_int, calculate_forces, "LRI_AUX")
    1661            0 :                DO ikind = 1, nkind
    1662            0 :                   CALL para_env%sum(lri_v_int(ikind)%v_int)
    1663              :                END DO
    1664            0 :                IF (lri_env%exact_1c_terms) THEN
    1665            0 :                   rho_ao => my_rho(ispin, :)
    1666            0 :                   ksmat => ks_matrix(ispin, :)
    1667              :                   CALL integrate_v_rspace_diagonal(v_rspace_used, ksmat(1)%matrix, &
    1668              :                                                    rho_ao(1)%matrix, qs_env, &
    1669            0 :                                                    calculate_forces, "ORB")
    1670              :                END IF
    1671            0 :                IF (lri_env%ppl_ri) THEN
    1672            0 :                   CALL v_int_ppl_update(qs_env, lri_v_int, calculate_forces)
    1673              :                END IF
    1674        12504 :             ELSE IF (rigpw) THEN
    1675            0 :                lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
    1676            0 :                CALL get_qs_env(qs_env, nkind=nkind, para_env=para_env)
    1677            0 :                DO ikind = 1, nkind
    1678            0 :                   lri_v_int(ikind)%v_int = 0.0_dp
    1679              :                END DO
    1680              :                CALL integrate_v_rspace_one_center(v_rspace_used, qs_env, &
    1681            0 :                                                   lri_v_int, calculate_forces, "RI_HXC")
    1682            0 :                DO ikind = 1, nkind
    1683            0 :                   CALL para_env%sum(lri_v_int(ikind)%v_int)
    1684              :                END DO
    1685              :             ELSE
    1686        12504 :                rho_ao => my_rho(ispin, :)
    1687        12504 :                ksmat => ks_matrix(ispin, :)
    1688              :                CALL integrate_v_rspace(v_rspace=v_rspace_used, &
    1689              :                                        pmat_kp=rho_ao, &
    1690              :                                        hmat_kp=ksmat, &
    1691              :                                        qs_env=qs_env, &
    1692              :                                        calculate_forces=calculate_forces, &
    1693        12504 :                                        gapw=gapw)
    1694              :             END IF
    1695        22804 :             IF (use_work_v_rspace) CALL auxbas_pw_pool%give_back_pw(v_rspace_work)
    1696              :          END DO
    1697              :       END IF ! ASSOCIATED(v_rspace_new)
    1698              : 
    1699              :       ! **** LRIGPW: KS matrix from integrated potential
    1700       114313 :       IF (lrigpw) THEN
    1701          462 :          CALL get_qs_env(qs_env, ks_env=ks_env)
    1702          462 :          CALL get_ks_env(ks_env=ks_env, kpoints=kpoints)
    1703          462 :          CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
    1704          936 :          DO ispin = 1, nspins
    1705          474 :             ksmat => ks_matrix(ispin, :)
    1706              :             CALL calculate_lri_ks_matrix(lri_env, lri_v_int, ksmat, atomic_kind_set, &
    1707          936 :                                          cell_to_index=cell_to_index)
    1708              :          END DO
    1709          462 :          IF (calculate_forces) THEN
    1710           24 :             CALL calculate_lri_forces(lri_env, lri_density, qs_env, rho_ao_kp, atomic_kind_set)
    1711              :          END IF
    1712       113851 :       ELSE IF (rigpw) THEN
    1713           26 :          CALL get_qs_env(qs_env, matrix_s=smat)
    1714           52 :          DO ispin = 1, nspins
    1715              :             CALL calculate_ri_ks_matrix(lri_env, lri_v_int, ks_matrix(ispin, 1)%matrix, &
    1716           52 :                                         smat(1)%matrix, atomic_kind_set, ispin)
    1717              :          END DO
    1718           26 :          IF (calculate_forces) THEN
    1719            2 :             rho_ao_nokp => rho_ao_kp(:, 1)
    1720            2 :             CALL calculate_ri_forces(lri_env, lri_density, qs_env, rho_ao_nokp, atomic_kind_set)
    1721              :          END IF
    1722              :       END IF
    1723              : 
    1724       114313 :       IF (ASSOCIATED(v_tau_rspace)) THEN
    1725         2828 :          IF (lrigpw .OR. rigpw) THEN
    1726            0 :             CPABORT("LRIGPW/RIGPW not implemented for meta-GGAs")
    1727              :          END IF
    1728         6090 :          DO ispin = 1, nspins
    1729         3262 :             CALL pw_scale(v_tau_rspace(ispin), v_tau_rspace(ispin)%pw_grid%dvol)
    1730              : 
    1731         3262 :             rho_ao => rho_ao_kp(ispin, :)
    1732         3262 :             ksmat => ks_matrix(ispin, :)
    1733              :             CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
    1734              :                                     pmat_kp=rho_ao, hmat_kp=ksmat, &
    1735              :                                     qs_env=qs_env, &
    1736              :                                     calculate_forces=calculate_forces, compute_tau=.TRUE., &
    1737         5816 :                                     gapw=gapw .AND. .NOT. gapw_composite_direct_ao)
    1738         6090 :             CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
    1739              :          END DO
    1740         2828 :          DEALLOCATE (v_tau_rspace)
    1741              :       END IF
    1742              : 
    1743              :       ! Add contributions from ADMM if requested
    1744       114313 :       IF (dft_control%do_admm) THEN
    1745        11982 :          CALL get_qs_env(qs_env, admm_env=admm_env)
    1746              :          CALL get_admm_env(admm_env, matrix_ks_aux_fit_kp=matrix_ks_aux_fit, rho_aux_fit=rho_aux_fit, &
    1747        11982 :                            matrix_ks_aux_fit_dft_kp=matrix_ks_aux_fit_dft)
    1748        11982 :          CALL qs_rho_get(rho_aux_fit, rho_ao_kp=rho_ao_aux)
    1749        11982 :          IF (ASSOCIATED(v_rspace_new_aux_fit)) THEN
    1750        18100 :             DO ispin = 1, nspins
    1751              :                ! Calculate the xc potential
    1752         9888 :                CALL pw_scale(v_rspace_new_aux_fit(ispin), v_rspace_new_aux_fit(ispin)%pw_grid%dvol)
    1753              : 
    1754              :                ! set matrix_ks_aux_fit_dft = matrix_ks_aux_fit(k_HF)
    1755        24796 :                DO img = 1, dft_control%nimages
    1756              :                   CALL dbcsr_copy(matrix_ks_aux_fit_dft(ispin, img)%matrix, matrix_ks_aux_fit(ispin, img)%matrix, &
    1757        24796 :                                   name="DFT exch. part of matrix_ks_aux_fit")
    1758              :                END DO
    1759              : 
    1760              :                ! Add potential to ks_matrix aux_fit, skip integration if no DFT correction
    1761              : 
    1762         9888 :                IF (admm_env%aux_exch_func /= do_admm_aux_exch_func_none) THEN
    1763              : 
    1764              :                   !GPW by default. IF GAPW, then take relevant task list and basis
    1765         9888 :                   CALL get_admm_env(admm_env, task_list_aux_fit=task_list)
    1766         9888 :                   basis_type = "AUX_FIT"
    1767         9888 :                   IF (admm_env%do_gapw) THEN
    1768         3490 :                      task_list => admm_env%admm_gapw_env%task_list
    1769         3490 :                      basis_type = "AUX_FIT_SOFT"
    1770              :                   END IF
    1771         9888 :                   fadm = 1.0_dp
    1772              :                   ! Calculate bare scaling of force according to Merlot, 1. IF: ADMMP, 2. IF: ADMMS,
    1773         9888 :                   IF (admm_env%do_admmp) THEN
    1774          442 :                      fadm = admm_env%gsi(ispin)**2
    1775         9446 :                   ELSE IF (admm_env%do_admms) THEN
    1776          478 :                      fadm = (admm_env%gsi(ispin))**(2.0_dp/3.0_dp)
    1777              :                   END IF
    1778              : 
    1779         9888 :                   rho_ao => rho_ao_aux(ispin, :)
    1780         9888 :                   ksmat => matrix_ks_aux_fit(ispin, :)
    1781              : 
    1782              :                   CALL integrate_v_rspace(v_rspace=v_rspace_new_aux_fit(ispin), &
    1783              :                                           pmat_kp=rho_ao, &
    1784              :                                           hmat_kp=ksmat, &
    1785              :                                           qs_env=qs_env, &
    1786              :                                           calculate_forces=calculate_forces, &
    1787              :                                           force_adm=fadm, &
    1788              :                                           gapw=.FALSE., & !even if actual GAPW calculation, want to use AUX_FIT_SOFT
    1789              :                                           basis_type=basis_type, &
    1790         9888 :                                           task_list_external=task_list)
    1791              :                END IF
    1792              : 
    1793              :                ! matrix_ks_aux_fit_dft(x_DFT)=matrix_ks_aux_fit_dft(old,k_HF)-matrix_ks_aux_fit(k_HF-x_DFT)
    1794        24796 :                DO img = 1, dft_control%nimages
    1795              :                   CALL dbcsr_add(matrix_ks_aux_fit_dft(ispin, img)%matrix, &
    1796        24796 :                                  matrix_ks_aux_fit(ispin, img)%matrix, 1.0_dp, -1.0_dp)
    1797              :                END DO
    1798              : 
    1799        18100 :                CALL auxbas_pw_pool%give_back_pw(v_rspace_new_aux_fit(ispin))
    1800              :             END DO
    1801         8212 :             DEALLOCATE (v_rspace_new_aux_fit)
    1802              :          END IF
    1803              :          ! Clean up v_tau_rspace_aux_fit, which is actually not needed
    1804        11982 :          IF (ASSOCIATED(v_tau_rspace_aux_fit)) THEN
    1805            0 :             DO ispin = 1, nspins
    1806            0 :                CALL auxbas_pw_pool%give_back_pw(v_tau_rspace_aux_fit(ispin))
    1807              :             END DO
    1808            0 :             DEALLOCATE (v_tau_rspace_aux_fit)
    1809              :          END IF
    1810              :       END IF
    1811              : 
    1812       114313 :       IF (dft_control%apply_embed_pot) DEALLOCATE (v_rspace_embed)
    1813              : 
    1814       114313 :       CALL timestop(handle)
    1815              : 
    1816       114313 :    END SUBROUTINE sum_up_and_integrate
    1817              : 
    1818              : !**************************************************************************
    1819              : !> \brief Calculate the ZMP potential and energy as in Zhao, Morrison Parr
    1820              : !> PRA 50i, 2138 (1994)
    1821              : !> V_c^\lambda defined as int_rho-rho_0/r-r' or rho-rho_0 times a Lagrange
    1822              : !> multiplier, plus Fermi-Amaldi potential that should give the V_xc in the
    1823              : !> limit \lambda --> \infty
    1824              : !>
    1825              : !> \param qs_env ...
    1826              : !> \param v_rspace_new ...
    1827              : !> \param rho ...
    1828              : !> \param exc ...
    1829              : !> \author D. Varsano  [daniele.varsano@nano.cnr.it]
    1830              : ! **************************************************************************************************
    1831            0 :    SUBROUTINE calculate_zmp_potential(qs_env, v_rspace_new, rho, exc)
    1832              : 
    1833              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1834              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_rspace_new
    1835              :       TYPE(qs_rho_type), POINTER                         :: rho
    1836              :       REAL(KIND=dp)                                      :: exc
    1837              : 
    1838              :       CHARACTER(*), PARAMETER :: routineN = 'calculate_zmp_potential'
    1839              : 
    1840              :       INTEGER                                            :: handle, my_val, nelectron, nspins
    1841              :       INTEGER, DIMENSION(2)                              :: nelectron_spin
    1842              :       LOGICAL                                            :: do_zmp_read, fermi_amaldi
    1843              :       REAL(KIND=dp)                                      :: lambda
    1844            0 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: tot_rho_ext_r
    1845              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1846            0 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_ext_g, rho_g
    1847              :       TYPE(pw_env_type), POINTER                         :: pw_env
    1848              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
    1849              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1850              :       TYPE(pw_r3d_rs_type)                               :: v_xc_rspace
    1851            0 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r
    1852              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1853              :       TYPE(section_vals_type), POINTER                   :: ext_den_section, input
    1854              : 
    1855              : !, v_h_gspace, &
    1856              : 
    1857            0 :       CALL timeset(routineN, handle)
    1858            0 :       NULLIFY (auxbas_pw_pool)
    1859            0 :       NULLIFY (pw_env)
    1860            0 :       NULLIFY (poisson_env)
    1861            0 :       NULLIFY (v_rspace_new)
    1862            0 :       NULLIFY (dft_control)
    1863            0 :       NULLIFY (rho_r, rho_g, tot_rho_ext_r, rho_ext_g)
    1864              :       CALL get_qs_env(qs_env=qs_env, &
    1865              :                       pw_env=pw_env, &
    1866              :                       ks_env=ks_env, &
    1867              :                       rho=rho, &
    1868              :                       input=input, &
    1869              :                       nelectron_spin=nelectron_spin, &
    1870            0 :                       dft_control=dft_control)
    1871              :       CALL pw_env_get(pw_env=pw_env, &
    1872              :                       auxbas_pw_pool=auxbas_pw_pool, &
    1873            0 :                       poisson_env=poisson_env)
    1874            0 :       CALL qs_rho_get(rho, rho_r=rho_r, rho_g=rho_g)
    1875            0 :       nspins = 1
    1876            0 :       ALLOCATE (v_rspace_new(nspins))
    1877            0 :       CALL auxbas_pw_pool%create_pw(pw=v_rspace_new(1))
    1878            0 :       CALL auxbas_pw_pool%create_pw(pw=v_xc_rspace)
    1879              : 
    1880            0 :       CALL pw_zero(v_rspace_new(1))
    1881            0 :       do_zmp_read = dft_control%apply_external_vxc
    1882            0 :       IF (do_zmp_read) THEN
    1883            0 :          CALL pw_copy(qs_env%external_vxc, v_rspace_new(1))
    1884              :          exc = accurate_dot_product(v_rspace_new(1)%array, rho_r(1)%array)* &
    1885            0 :                v_rspace_new(1)%pw_grid%dvol
    1886              :       ELSE
    1887            0 :          BLOCK
    1888              :             REAL(KIND=dp)                                      :: factor
    1889              :             TYPE(pw_c1d_gs_type) :: rho_eff_gspace, v_xc_gspace
    1890            0 :             CALL auxbas_pw_pool%create_pw(pw=rho_eff_gspace)
    1891            0 :             CALL auxbas_pw_pool%create_pw(pw=v_xc_gspace)
    1892            0 :             CALL pw_zero(rho_eff_gspace)
    1893            0 :             CALL pw_zero(v_xc_gspace)
    1894            0 :             CALL pw_zero(v_xc_rspace)
    1895            0 :             factor = pw_integrate_function(rho_g(1))
    1896              :             CALL qs_rho_get(qs_env%rho_external, &
    1897              :                             rho_g=rho_ext_g, &
    1898            0 :                             tot_rho_r=tot_rho_ext_r)
    1899            0 :             factor = tot_rho_ext_r(1)/factor
    1900              : 
    1901            0 :             CALL pw_axpy(rho_g(1), rho_eff_gspace, alpha=factor)
    1902            0 :             CALL pw_axpy(rho_ext_g(1), rho_eff_gspace, alpha=-1.0_dp)
    1903            0 :             ext_den_section => section_vals_get_subs_vals(input, "DFT%EXTERNAL_DENSITY")
    1904            0 :             CALL section_vals_val_get(ext_den_section, "LAMBDA", r_val=lambda)
    1905            0 :             CALL section_vals_val_get(ext_den_section, "ZMP_CONSTRAINT", i_val=my_val)
    1906            0 :             CALL section_vals_val_get(ext_den_section, "FERMI_AMALDI", l_val=fermi_amaldi)
    1907              : 
    1908            0 :             CALL pw_scale(rho_eff_gspace, a=lambda)
    1909            0 :             nelectron = nelectron_spin(1)
    1910            0 :             factor = -1.0_dp/nelectron
    1911            0 :             CALL pw_axpy(rho_g(1), rho_eff_gspace, alpha=factor)
    1912              : 
    1913            0 :             CALL pw_poisson_solve(poisson_env, rho_eff_gspace, vhartree=v_xc_gspace)
    1914            0 :             CALL pw_transfer(v_xc_gspace, v_rspace_new(1))
    1915            0 :             CALL pw_copy(v_rspace_new(1), v_xc_rspace)
    1916              : 
    1917            0 :             exc = 0.0_dp
    1918            0 :             exc = pw_integral_ab(v_rspace_new(1), rho_r(1))
    1919              : 
    1920              : !Note that this is not the xc energy but \int(\rho*v_xc)
    1921              : !Vxc---> v_rspace_new
    1922              : !Exc---> energy%exc
    1923            0 :             CALL auxbas_pw_pool%give_back_pw(rho_eff_gspace)
    1924            0 :             CALL auxbas_pw_pool%give_back_pw(v_xc_gspace)
    1925              :          END BLOCK
    1926              :       END IF
    1927              : 
    1928            0 :       CALL auxbas_pw_pool%give_back_pw(v_xc_rspace)
    1929              : 
    1930            0 :       CALL timestop(handle)
    1931              : 
    1932            0 :    END SUBROUTINE calculate_zmp_potential
    1933              : 
    1934              : ! **************************************************************************************************
    1935              : !> \brief ...
    1936              : !> \param qs_env ...
    1937              : !> \param rho ...
    1938              : !> \param v_rspace_embed ...
    1939              : !> \param dft_control ...
    1940              : !> \param embed_corr ...
    1941              : !> \param just_energy ...
    1942              : ! **************************************************************************************************
    1943          868 :    SUBROUTINE get_embed_potential_energy(qs_env, rho, v_rspace_embed, dft_control, embed_corr, &
    1944              :                                          just_energy)
    1945              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1946              :       TYPE(qs_rho_type), POINTER                         :: rho
    1947              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_rspace_embed
    1948              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1949              :       REAL(KIND=dp)                                      :: embed_corr
    1950              :       LOGICAL                                            :: just_energy
    1951              : 
    1952              :       CHARACTER(*), PARAMETER :: routineN = 'get_embed_potential_energy'
    1953              : 
    1954              :       INTEGER                                            :: handle, ispin
    1955              :       REAL(KIND=dp)                                      :: embed_corr_local
    1956              :       TYPE(pw_env_type), POINTER                         :: pw_env
    1957              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1958          868 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r
    1959              : 
    1960          868 :       CALL timeset(routineN, handle)
    1961              : 
    1962          868 :       NULLIFY (auxbas_pw_pool)
    1963          868 :       NULLIFY (pw_env)
    1964          868 :       NULLIFY (rho_r)
    1965              :       CALL get_qs_env(qs_env=qs_env, &
    1966              :                       pw_env=pw_env, &
    1967          868 :                       rho=rho)
    1968              :       CALL pw_env_get(pw_env=pw_env, &
    1969          868 :                       auxbas_pw_pool=auxbas_pw_pool)
    1970          868 :       CALL qs_rho_get(rho, rho_r=rho_r)
    1971         3952 :       ALLOCATE (v_rspace_embed(dft_control%nspins))
    1972              : 
    1973          868 :       embed_corr = 0.0_dp
    1974              : 
    1975         2216 :       DO ispin = 1, dft_control%nspins
    1976         1348 :          CALL auxbas_pw_pool%create_pw(pw=v_rspace_embed(ispin))
    1977         1348 :          CALL pw_zero(v_rspace_embed(ispin))
    1978              : 
    1979         1348 :          CALL pw_copy(qs_env%embed_pot, v_rspace_embed(ispin))
    1980         1348 :          embed_corr_local = 0.0_dp
    1981              : 
    1982              :          ! Spin embedding potential in open-shell case
    1983         1348 :          IF (dft_control%nspins == 2) THEN
    1984          960 :             IF (ispin == 1) CALL pw_axpy(qs_env%spin_embed_pot, v_rspace_embed(ispin), 1.0_dp)
    1985          960 :             IF (ispin == 2) CALL pw_axpy(qs_env%spin_embed_pot, v_rspace_embed(ispin), -1.0_dp)
    1986              :          END IF
    1987              :          ! Integrate the density*potential
    1988         1348 :          embed_corr_local = pw_integral_ab(v_rspace_embed(ispin), rho_r(ispin))
    1989              : 
    1990         2216 :          embed_corr = embed_corr + embed_corr_local
    1991              : 
    1992              :       END DO
    1993              : 
    1994              :       ! If only energy requiested we delete the potential
    1995          868 :       IF (just_energy) THEN
    1996          692 :          DO ispin = 1, dft_control%nspins
    1997          692 :             CALL auxbas_pw_pool%give_back_pw(v_rspace_embed(ispin))
    1998              :          END DO
    1999          286 :          DEALLOCATE (v_rspace_embed)
    2000              :       END IF
    2001              : 
    2002          868 :       CALL timestop(handle)
    2003              : 
    2004          868 :    END SUBROUTINE get_embed_potential_energy
    2005              : 
    2006              : END MODULE qs_ks_utils
        

Generated by: LCOV version 2.0-1