LCOV - code coverage report
Current view: top level - src - qs_vxc.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:cccd2f3) Lines: 84.4 % 463 391
Test Date: 2026-05-06 07:07:47 Functions: 83.3 % 6 5

            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
      10              : !>
      11              : !>
      12              : !> \par History
      13              : !>     refactoring 03-2011 [MI]
      14              : !> \author MI
      15              : ! **************************************************************************************************
      16              : MODULE qs_vxc
      17              : 
      18              :    USE cell_types,                      ONLY: cell_type
      19              :    USE cp_control_types,                ONLY: dft_control_type
      20              :    USE input_constants,                 ONLY: sic_ad,&
      21              :                                               sic_eo,&
      22              :                                               sic_mauri_spz,&
      23              :                                               sic_mauri_us,&
      24              :                                               sic_none,&
      25              :                                               xc_none,&
      26              :                                               xc_vdw_fun_nonloc
      27              :    USE input_section_types,             ONLY: section_vals_type,&
      28              :                                               section_vals_val_get
      29              :    USE kinds,                           ONLY: dp
      30              :    USE message_passing,                 ONLY: mp_para_env_type
      31              :    USE pw_env_types,                    ONLY: pw_env_get,&
      32              :                                               pw_env_type
      33              :    USE pw_grids,                        ONLY: pw_grid_compare
      34              :    USE pw_methods,                      ONLY: pw_axpy,&
      35              :                                               pw_copy,&
      36              :                                               pw_multiply,&
      37              :                                               pw_scale,&
      38              :                                               pw_transfer,&
      39              :                                               pw_zero
      40              :    USE pw_pool_types,                   ONLY: pw_pool_type
      41              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      42              :                                               pw_r3d_rs_type
      43              :    USE qs_dispersion_nonloc,            ONLY: calculate_dispersion_nonloc
      44              :    USE qs_dispersion_types,             ONLY: qs_dispersion_type
      45              :    USE qs_ks_types,                     ONLY: get_ks_env,&
      46              :                                               qs_ks_env_type
      47              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      48              :                                               qs_rho_type
      49              :    USE virial_types,                    ONLY: virial_type
      50              :    USE xc,                              ONLY: calc_xc_density,&
      51              :                                               xc_exc_calc,&
      52              :                                               xc_vxc_pw_create
      53              : #include "./base/base_uses.f90"
      54              : 
      55              :    IMPLICIT NONE
      56              : 
      57              :    PRIVATE
      58              : 
      59              :    ! *** Public subroutines ***
      60              :    PUBLIC :: qs_vxc_create, qs_xc_density
      61              : 
      62              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_vxc'
      63              : 
      64              : CONTAINS
      65              : 
      66              : ! **************************************************************************************************
      67              : !> \brief calculates and allocates the xc potential, already reducing it to
      68              : !>      the dependence on rho and the one on tau
      69              : !> \param ks_env to get all the needed things
      70              : !> \param rho_struct density for which v_xc is calculated
      71              : !> \param xc_section ...
      72              : !> \param vxc_rho will contain the v_xc part that depend on rho
      73              : !>        (if one of the chosen xc functionals has it it is allocated and you
      74              : !>        are responsible for it)
      75              : !> \param vxc_tau will contain the kinetic tau part of v_xc
      76              : !>        (if one of the chosen xc functionals has it it is allocated and you
      77              : !>        are responsible for it)
      78              : !> \param exc ...
      79              : !> \param just_energy if true calculates just the energy, and does not
      80              : !>        allocate v_*_rspace
      81              : !> \param edisp ...
      82              : !> \param dispersion_env ...
      83              : !> \param adiabatic_rescale_factor ...
      84              : !> \param pw_env_external    external plane wave environment
      85              : !> \par History
      86              : !>      - 05.2002 modified to use the mp_allgather function each pe
      87              : !>        computes only part of the grid and this is broadcasted to all
      88              : !>        instead of summed.
      89              : !>        This scales significantly better (e.g. factor 3 on 12 cpus
      90              : !>        32 H2O) [Joost VdV]
      91              : !>      - moved to qs_ks_methods [fawzi]
      92              : !>      - sic alterations [Joost VandeVondele]
      93              : !> \author Fawzi Mohamed
      94              : ! **************************************************************************************************
      95       594188 :    SUBROUTINE qs_vxc_create(ks_env, rho_struct, xc_section, vxc_rho, vxc_tau, exc, &
      96              :                             just_energy, edisp, dispersion_env, adiabatic_rescale_factor, &
      97              :                             pw_env_external)
      98              : 
      99              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     100              :       TYPE(qs_rho_type), POINTER                         :: rho_struct
     101              :       TYPE(section_vals_type), POINTER                   :: xc_section
     102              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: vxc_rho, vxc_tau
     103              :       REAL(KIND=dp), INTENT(out)                         :: exc
     104              :       LOGICAL, INTENT(in), OPTIONAL                      :: just_energy
     105              :       REAL(KIND=dp), INTENT(out), OPTIONAL               :: edisp
     106              :       TYPE(qs_dispersion_type), OPTIONAL, POINTER        :: dispersion_env
     107              :       REAL(KIND=dp), INTENT(in), OPTIONAL                :: adiabatic_rescale_factor
     108              :       TYPE(pw_env_type), OPTIONAL, POINTER               :: pw_env_external
     109              : 
     110              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_vxc_create'
     111              : 
     112              :       INTEGER                                            :: handle, ispin, mspin, myfun, &
     113              :                                                             nelec_spin(2), vdw
     114              :       LOGICAL :: compute_virial, do_adiabatic_rescaling, my_just_energy, rho_g_valid, &
     115              :          sic_scaling_b_zero, tau_g_valid, tau_r_valid, uf_grid, vdW_nl
     116              :       REAL(KIND=dp)                                      :: exc_m, factor, &
     117              :                                                             my_adiabatic_rescale_factor, &
     118              :                                                             my_scaling, nelec_s_inv
     119              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: virial_xc_tmp
     120              :       TYPE(cell_type), POINTER                           :: cell
     121              :       TYPE(dft_control_type), POINTER                    :: dft_control
     122              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     123       148547 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g, rho_m_gspace, rho_struct_g, &
     124       148547 :                                                             tau_struct_g
     125              :       TYPE(pw_c1d_gs_type), POINTER                      :: rho_nlcc_g, rho_nlcc_g_use, &
     126              :                                                             rho_nlcc_g_xc, tmp_g, tmp_g2
     127              :       TYPE(pw_env_type), POINTER                         :: pw_env
     128              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, vdw_pw_pool, xc_pw_pool
     129       148547 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: my_vxc_rho, my_vxc_tau, rho_m_rspace, &
     130       148547 :                                                             rho_r, rho_struct_r, tau, tau_struct_r
     131              :       TYPE(pw_r3d_rs_type), POINTER                      :: rho_nlcc, rho_nlcc_use, rho_nlcc_xc, &
     132              :                                                             tmp_pw, weights, weights_use, &
     133              :                                                             weights_xc
     134              :       TYPE(virial_type), POINTER                         :: virial
     135              : 
     136       148547 :       CALL timeset(routineN, handle)
     137              : 
     138       148547 :       CPASSERT(.NOT. ASSOCIATED(vxc_rho))
     139       148547 :       CPASSERT(.NOT. ASSOCIATED(vxc_tau))
     140       148547 :       NULLIFY (dft_control, pw_env, auxbas_pw_pool, xc_pw_pool, vdw_pw_pool, cell, my_vxc_rho, &
     141       148547 :                tmp_pw, tmp_g, tmp_g2, my_vxc_tau, rho_g, rho_r, tau, rho_m_rspace, &
     142       148547 :                rho_m_gspace, rho_nlcc, rho_nlcc_g, rho_nlcc_g_use, rho_nlcc_g_xc, &
     143       148547 :                rho_nlcc_use, rho_nlcc_xc, rho_struct_r, rho_struct_g, tau_struct_g, tau_struct_r, &
     144       148547 :                weights_use, weights_xc)
     145              : 
     146       148547 :       exc = 0.0_dp
     147       148547 :       my_just_energy = .FALSE.
     148       148547 :       IF (PRESENT(just_energy)) my_just_energy = just_energy
     149       148547 :       my_adiabatic_rescale_factor = 1.0_dp
     150       148547 :       do_adiabatic_rescaling = .FALSE.
     151       148547 :       IF (PRESENT(adiabatic_rescale_factor)) THEN
     152           44 :          my_adiabatic_rescale_factor = adiabatic_rescale_factor
     153           44 :          do_adiabatic_rescaling = .TRUE.
     154              :       END IF
     155              : 
     156              :       CALL get_ks_env(ks_env, &
     157              :                       dft_control=dft_control, &
     158              :                       pw_env=pw_env, &
     159              :                       cell=cell, &
     160              :                       xcint_weights=weights, &
     161              :                       virial=virial, &
     162              :                       rho_nlcc=rho_nlcc, &
     163       148547 :                       rho_nlcc_g=rho_nlcc_g)
     164       148547 :       rho_nlcc_use => rho_nlcc
     165       148547 :       rho_nlcc_g_use => rho_nlcc_g
     166       148547 :       weights_use => weights
     167              : 
     168              :       CALL qs_rho_get(rho_struct, &
     169              :                       tau_r_valid=tau_r_valid, &
     170              :                       tau_g_valid=tau_g_valid, &
     171              :                       rho_g_valid=rho_g_valid, &
     172              :                       rho_r=rho_struct_r, &
     173              :                       rho_g=rho_struct_g, &
     174              :                       tau_g=tau_struct_g, &
     175       148547 :                       tau_r=tau_struct_r)
     176              : 
     177       148547 :       compute_virial = virial%pv_calculate .AND. (.NOT. virial%pv_numer)
     178       148547 :       IF (compute_virial) THEN
     179        37362 :          virial%pv_xc = 0.0_dp
     180              :       END IF
     181              : 
     182              :       CALL section_vals_val_get(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", &
     183       148547 :                                 i_val=myfun)
     184              :       CALL section_vals_val_get(xc_section, "VDW_POTENTIAL%POTENTIAL_TYPE", &
     185       148547 :                                 i_val=vdw)
     186              : 
     187       148547 :       vdW_nl = (vdw == xc_vdw_fun_nonloc)
     188              :       ! this combination has not been investigated
     189       148547 :       CPASSERT(.NOT. (do_adiabatic_rescaling .AND. vdW_nl))
     190              :       ! are the necessary inputs available
     191       148547 :       IF (.NOT. (PRESENT(dispersion_env) .AND. PRESENT(edisp))) THEN
     192              :          vdW_nl = .FALSE.
     193              :       END IF
     194       148547 :       IF (PRESENT(edisp)) edisp = 0.0_dp
     195              : 
     196       148547 :       IF (myfun /= xc_none .OR. vdW_nl) THEN
     197              : 
     198              :          ! test if the real space density is available
     199       133923 :          CPASSERT(ASSOCIATED(rho_struct))
     200       133923 :          IF (dft_control%nspins /= 1 .AND. dft_control%nspins /= 2) &
     201            0 :             CPABORT("nspins must be 1 or 2")
     202       133923 :          mspin = SIZE(rho_struct_r)
     203       133923 :          IF (dft_control%nspins == 2 .AND. mspin == 1) &
     204            0 :             CPABORT("Spin count mismatch")
     205              : 
     206              :          ! there are some options related to SIC here.
     207              :          ! Normal DFT computes E(rho_alpha,rho_beta) (or its variant E(2*rho_alpha) for non-LSD)
     208              :          ! SIC can             E(rho_alpha,rho_beta)-b*(E(rho_alpha,rho_beta)-E(rho_beta,rho_beta))
     209              :          ! or compute          E(rho_alpha,rho_beta)-b*E(rho_alpha-rho_beta,0)
     210              : 
     211              :          ! my_scaling is the scaling needed of the standard E(rho_alpha,rho_beta) term
     212       133923 :          my_scaling = 1.0_dp
     213       134127 :          SELECT CASE (dft_control%sic_method_id)
     214              :          CASE (sic_none)
     215              :             ! all fine
     216              :          CASE (sic_mauri_spz, sic_ad)
     217              :             ! no idea yet what to do here in that case
     218          204 :             CPASSERT(.NOT. tau_r_valid)
     219              :          CASE (sic_mauri_us)
     220           92 :             my_scaling = 1.0_dp - dft_control%sic_scaling_b
     221              :             ! no idea yet what to do here in that case
     222           92 :             CPASSERT(.NOT. tau_r_valid)
     223              :          CASE (sic_eo)
     224              :             ! NOTHING TO BE DONE
     225              :          CASE DEFAULT
     226              :             ! this case has not yet been treated here
     227       133923 :             CPABORT("NYI")
     228              :          END SELECT
     229              : 
     230       133923 :          IF (dft_control%sic_scaling_b == 0.0_dp) THEN
     231              :             sic_scaling_b_zero = .TRUE.
     232              :          ELSE
     233       133823 :             sic_scaling_b_zero = .FALSE.
     234              :          END IF
     235              : 
     236       133923 :          IF (PRESENT(pw_env_external)) &
     237            0 :             pw_env => pw_env_external
     238       133923 :          CALL pw_env_get(pw_env, xc_pw_pool=xc_pw_pool, auxbas_pw_pool=auxbas_pw_pool)
     239       133923 :          uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
     240              : 
     241       133923 :          IF (.NOT. uf_grid) THEN
     242       132905 :             rho_r => rho_struct_r
     243              : 
     244       132905 :             IF (tau_r_valid) THEN
     245         3398 :                tau => tau_struct_r
     246              :             END IF
     247              : 
     248              :             ! for gradient corrected functional the density in g space might
     249              :             ! be useful so if we have it, we pass it in
     250       132905 :             IF (rho_g_valid) THEN
     251       132805 :                rho_g => rho_struct_g
     252              :             END IF
     253              :          ELSE
     254         1018 :             CPASSERT(rho_g_valid)
     255         4072 :             ALLOCATE (rho_r(mspin))
     256         4072 :             ALLOCATE (rho_g(mspin))
     257         2036 :             DO ispin = 1, mspin
     258         1018 :                CALL xc_pw_pool%create_pw(rho_g(ispin))
     259         2036 :                CALL pw_transfer(rho_struct_g(ispin), rho_g(ispin))
     260              :             END DO
     261         2036 :             DO ispin = 1, mspin
     262         1018 :                CALL xc_pw_pool%create_pw(rho_r(ispin))
     263         2036 :                CALL pw_transfer(rho_g(ispin), rho_r(ispin))
     264              :             END DO
     265         1018 :             IF (tau_r_valid) THEN
     266          750 :                ALLOCATE (tau(mspin))
     267          500 :                DO ispin = 1, mspin
     268          250 :                   CALL xc_pw_pool%create_pw(tau(ispin))
     269          250 :                   BLOCK
     270              :                      TYPE(pw_c1d_gs_type) :: tau_g_aux, tau_g_xc
     271          250 :                      CALL xc_pw_pool%create_pw(tau_g_xc)
     272          250 :                      IF (tau_g_valid) THEN
     273          250 :                         CALL pw_transfer(tau_struct_g(ispin), tau_g_xc)
     274              :                      ELSE
     275            0 :                         CALL auxbas_pw_pool%create_pw(tau_g_aux)
     276            0 :                         CALL pw_transfer(tau_struct_r(ispin), tau_g_aux)
     277            0 :                         CALL pw_transfer(tau_g_aux, tau_g_xc)
     278            0 :                         CALL auxbas_pw_pool%give_back_pw(tau_g_aux)
     279              :                      END IF
     280          250 :                      CALL pw_transfer(tau_g_xc, tau(ispin))
     281          500 :                      CALL xc_pw_pool%give_back_pw(tau_g_xc)
     282              :                   END BLOCK
     283              :                END DO
     284              :             END IF
     285         1018 :             IF (ASSOCIATED(weights)) THEN
     286         1004 :                ALLOCATE (weights_xc)
     287         1004 :                CALL xc_pw_pool%create_pw(weights_xc)
     288              :                BLOCK
     289              :                   TYPE(pw_c1d_gs_type) :: weights_g_aux, weights_g_xc
     290         1004 :                   CALL auxbas_pw_pool%create_pw(weights_g_aux)
     291         1004 :                   CALL xc_pw_pool%create_pw(weights_g_xc)
     292         1004 :                   CALL pw_transfer(weights, weights_g_aux)
     293         1004 :                   CALL pw_transfer(weights_g_aux, weights_g_xc)
     294         1004 :                   CALL pw_transfer(weights_g_xc, weights_xc)
     295         1004 :                   CALL xc_pw_pool%give_back_pw(weights_g_xc)
     296         2008 :                   CALL auxbas_pw_pool%give_back_pw(weights_g_aux)
     297              :                END BLOCK
     298         1004 :                weights_use => weights_xc
     299              :             END IF
     300         1018 :             IF (ASSOCIATED(rho_nlcc)) THEN
     301           28 :                CPASSERT(ASSOCIATED(rho_nlcc_g))
     302           28 :                ALLOCATE (rho_nlcc_g_xc, rho_nlcc_xc)
     303           28 :                CALL xc_pw_pool%create_pw(rho_nlcc_g_xc)
     304           28 :                CALL xc_pw_pool%create_pw(rho_nlcc_xc)
     305           28 :                CALL pw_transfer(rho_nlcc_g, rho_nlcc_g_xc)
     306           28 :                CALL pw_transfer(rho_nlcc_g_xc, rho_nlcc_xc)
     307           28 :                rho_nlcc_use => rho_nlcc_xc
     308           28 :                rho_nlcc_g_use => rho_nlcc_g_xc
     309              :             END IF
     310              :          END IF
     311              : 
     312              :          ! add the nlcc densities
     313       133923 :          IF (ASSOCIATED(rho_nlcc_use)) THEN
     314          596 :             factor = 1.0_dp
     315         1192 :             DO ispin = 1, mspin
     316          596 :                CALL pw_axpy(rho_nlcc_use, rho_r(ispin), factor)
     317         1192 :                CALL pw_axpy(rho_nlcc_g_use, rho_g(ispin), factor)
     318              :             END DO
     319              :          END IF
     320              : 
     321              :          !
     322              :          ! here the rho_r, rho_g, tau is what it should be
     323              :          ! we get back the right my_vxc_rho and my_vxc_tau as required
     324              :          !
     325       133923 :          IF (my_just_energy) THEN
     326              :             exc = xc_exc_calc(rho_r=rho_r, tau=tau, &
     327              :                               rho_g=rho_g, xc_section=xc_section, &
     328        10440 :                               weights=weights_use, pw_pool=xc_pw_pool)
     329              : 
     330              :          ELSE
     331              :             CALL xc_vxc_pw_create(vxc_rho=my_vxc_rho, vxc_tau=my_vxc_tau, rho_r=rho_r, &
     332              :                                   rho_g=rho_g, tau=tau, exc=exc, &
     333              :                                   xc_section=xc_section, &
     334              :                                   weights=weights_use, pw_pool=xc_pw_pool, &
     335              :                                   compute_virial=compute_virial, &
     336       123483 :                                   virial_xc=virial%pv_xc)
     337              :          END IF
     338              : 
     339              :          ! remove the nlcc densities (keep stuff in original state)
     340       133923 :          IF (ASSOCIATED(rho_nlcc_use)) THEN
     341          596 :             factor = -1.0_dp
     342         1192 :             DO ispin = 1, mspin
     343          596 :                CALL pw_axpy(rho_nlcc_use, rho_r(ispin), factor)
     344         1192 :                CALL pw_axpy(rho_nlcc_g_use, rho_g(ispin), factor)
     345              :             END DO
     346              :          END IF
     347              : 
     348              :          ! calclulate non-local vdW functional
     349              :          ! only if this XC_SECTION has it
     350              :          ! if yes, we use the dispersion_env from ks_env
     351              :          ! this is dangerous, as it assumes a special connection xc_section -> qs_env
     352       133923 :          IF (vdW_nl) THEN
     353          422 :             CALL get_ks_env(ks_env=ks_env, para_env=para_env)
     354              :             ! no SIC functionals allowed
     355          422 :             CPASSERT(dft_control%sic_method_id == sic_none)
     356              :             !
     357          422 :             CALL pw_env_get(pw_env, vdw_pw_pool=vdw_pw_pool)
     358          422 :             IF (my_just_energy) THEN
     359              :                CALL calculate_dispersion_nonloc(my_vxc_rho, rho_r, rho_g, edisp, dispersion_env, &
     360            6 :                                                 my_just_energy, vdw_pw_pool, xc_pw_pool, para_env)
     361              :             ELSE
     362              :                CALL calculate_dispersion_nonloc(my_vxc_rho, rho_r, rho_g, edisp, dispersion_env, &
     363          416 :                                                 my_just_energy, vdw_pw_pool, xc_pw_pool, para_env, virial=virial)
     364              :             END IF
     365              :          END IF
     366              : 
     367              :          !! Apply rescaling to the potential if requested
     368       133923 :          IF (.NOT. my_just_energy) THEN
     369       123483 :             IF (do_adiabatic_rescaling) THEN
     370           24 :                IF (ASSOCIATED(my_vxc_rho)) THEN
     371           62 :                   DO ispin = 1, SIZE(my_vxc_rho)
     372           62 :                      CALL pw_scale(my_vxc_rho(ispin), my_adiabatic_rescale_factor)
     373              :                   END DO
     374              :                END IF
     375              :             END IF
     376              :          END IF
     377              : 
     378       133923 :          IF (my_scaling /= 1.0_dp) THEN
     379           92 :             exc = exc*my_scaling
     380           92 :             IF (ASSOCIATED(my_vxc_rho)) THEN
     381          180 :                DO ispin = 1, SIZE(my_vxc_rho)
     382          180 :                   CALL pw_scale(my_vxc_rho(ispin), my_scaling)
     383              :                END DO
     384              :             END IF
     385           92 :             IF (ASSOCIATED(my_vxc_tau)) THEN
     386            0 :                DO ispin = 1, SIZE(my_vxc_tau)
     387            0 :                   CALL pw_scale(my_vxc_tau(ispin), my_scaling)
     388              :                END DO
     389              :             END IF
     390              :          END IF
     391              : 
     392              :          ! we have pw data for the xc, qs_ks requests coeff structure, here we transfer
     393              :          ! pw -> coeff
     394       133923 :          IF (ASSOCIATED(my_vxc_rho)) THEN
     395       123483 :             vxc_rho => my_vxc_rho
     396       123483 :             NULLIFY (my_vxc_rho)
     397              :          END IF
     398       133923 :          IF (ASSOCIATED(my_vxc_tau)) THEN
     399         2570 :             vxc_tau => my_vxc_tau
     400         2570 :             NULLIFY (my_vxc_tau)
     401              :          END IF
     402       133923 :          IF (uf_grid) THEN
     403         2036 :             DO ispin = 1, SIZE(rho_r)
     404         2036 :                CALL xc_pw_pool%give_back_pw(rho_r(ispin))
     405              :             END DO
     406         1018 :             DEALLOCATE (rho_r)
     407         1018 :             IF (ASSOCIATED(rho_g)) THEN
     408         2036 :                DO ispin = 1, SIZE(rho_g)
     409         2036 :                   CALL xc_pw_pool%give_back_pw(rho_g(ispin))
     410              :                END DO
     411         1018 :                DEALLOCATE (rho_g)
     412              :             END IF
     413              :          END IF
     414              : 
     415              :          ! compute again the xc but now for Exc(m,o) and the opposite sign
     416       133923 :          IF (dft_control%sic_method_id == sic_mauri_spz .AND. .NOT. sic_scaling_b_zero) THEN
     417          390 :             ALLOCATE (rho_m_rspace(2), rho_m_gspace(2))
     418           78 :             CALL xc_pw_pool%create_pw(rho_m_gspace(1))
     419           78 :             CALL xc_pw_pool%create_pw(rho_m_rspace(1))
     420           78 :             CALL pw_copy(rho_struct_r(1), rho_m_rspace(1))
     421           78 :             CALL pw_axpy(rho_struct_r(2), rho_m_rspace(1), alpha=-1._dp)
     422           78 :             CALL pw_copy(rho_struct_g(1), rho_m_gspace(1))
     423           78 :             CALL pw_axpy(rho_struct_g(2), rho_m_gspace(1), alpha=-1._dp)
     424              :             ! bit sad, these will be just zero...
     425           78 :             CALL xc_pw_pool%create_pw(rho_m_gspace(2))
     426           78 :             CALL xc_pw_pool%create_pw(rho_m_rspace(2))
     427           78 :             CALL pw_zero(rho_m_rspace(2))
     428           78 :             CALL pw_zero(rho_m_gspace(2))
     429              : 
     430           78 :             IF (my_just_energy) THEN
     431              :                exc_m = xc_exc_calc(rho_r=rho_m_rspace, tau=tau, &
     432              :                                    rho_g=rho_m_gspace, xc_section=xc_section, &
     433           24 :                                    weights=weights_use, pw_pool=xc_pw_pool)
     434              :             ELSE
     435              :                ! virial untested
     436           54 :                CPASSERT(.NOT. compute_virial)
     437              :                CALL xc_vxc_pw_create(vxc_rho=my_vxc_rho, vxc_tau=my_vxc_tau, rho_r=rho_m_rspace, &
     438              :                                      rho_g=rho_m_gspace, tau=tau, exc=exc_m, &
     439              :                                      xc_section=xc_section, &
     440              :                                      weights=weights_use, pw_pool=xc_pw_pool, &
     441              :                                      compute_virial=.FALSE., &
     442           54 :                                      virial_xc=virial_xc_tmp)
     443              :             END IF
     444              : 
     445           78 :             exc = exc - dft_control%sic_scaling_b*exc_m
     446              : 
     447              :             ! and take care of the potential only vxc_rho is taken into account
     448           78 :             IF (.NOT. my_just_energy) THEN
     449           54 :                CALL pw_axpy(my_vxc_rho(1), vxc_rho(1), -dft_control%sic_scaling_b)
     450           54 :                CALL pw_axpy(my_vxc_rho(1), vxc_rho(2), dft_control%sic_scaling_b)
     451           54 :                CALL my_vxc_rho(1)%release()
     452           54 :                CALL my_vxc_rho(2)%release()
     453           54 :                DEALLOCATE (my_vxc_rho)
     454              :             END IF
     455              : 
     456          234 :             DO ispin = 1, 2
     457          156 :                CALL xc_pw_pool%give_back_pw(rho_m_rspace(ispin))
     458          234 :                CALL xc_pw_pool%give_back_pw(rho_m_gspace(ispin))
     459              :             END DO
     460           78 :             DEALLOCATE (rho_m_rspace)
     461           78 :             DEALLOCATE (rho_m_gspace)
     462              : 
     463              :          END IF
     464              : 
     465              :          ! now we have - sum_s N_s * Exc(rho_s/N_s,0)
     466       133923 :          IF (dft_control%sic_method_id == sic_ad .AND. .NOT. sic_scaling_b_zero) THEN
     467              : 
     468              :             ! find out how many elecs we have
     469           26 :             CALL get_ks_env(ks_env, nelectron_spin=nelec_spin)
     470              : 
     471          130 :             ALLOCATE (rho_m_rspace(2), rho_m_gspace(2))
     472           78 :             DO ispin = 1, 2
     473           52 :                CALL xc_pw_pool%create_pw(rho_m_gspace(ispin))
     474           78 :                CALL xc_pw_pool%create_pw(rho_m_rspace(ispin))
     475              :             END DO
     476              : 
     477           78 :             DO ispin = 1, 2
     478           52 :                IF (nelec_spin(ispin) > 0.0_dp) THEN
     479           52 :                   nelec_s_inv = 1.0_dp/nelec_spin(ispin)
     480              :                ELSE
     481              :                   ! does it matter if there are no electrons with this spin (H) ?
     482            0 :                   nelec_s_inv = 0.0_dp
     483              :                END IF
     484           52 :                CALL pw_copy(rho_struct_r(ispin), rho_m_rspace(1))
     485           52 :                CALL pw_copy(rho_struct_g(ispin), rho_m_gspace(1))
     486           52 :                CALL pw_scale(rho_m_rspace(1), nelec_s_inv)
     487           52 :                CALL pw_scale(rho_m_gspace(1), nelec_s_inv)
     488           52 :                CALL pw_zero(rho_m_rspace(2))
     489           52 :                CALL pw_zero(rho_m_gspace(2))
     490              : 
     491           52 :                IF (my_just_energy) THEN
     492              :                   exc_m = xc_exc_calc(rho_r=rho_m_rspace, tau=tau, &
     493              :                                       rho_g=rho_m_gspace, xc_section=xc_section, &
     494           12 :                                       weights=weights_use, pw_pool=xc_pw_pool)
     495              :                ELSE
     496              :                   ! virial untested
     497           40 :                   CPASSERT(.NOT. compute_virial)
     498              :                   CALL xc_vxc_pw_create(vxc_rho=my_vxc_rho, vxc_tau=my_vxc_tau, rho_r=rho_m_rspace, &
     499              :                                         rho_g=rho_m_gspace, tau=tau, exc=exc_m, &
     500              :                                         xc_section=xc_section, &
     501              :                                         weights=weights_use, pw_pool=xc_pw_pool, &
     502              :                                         compute_virial=.FALSE., &
     503           40 :                                         virial_xc=virial_xc_tmp)
     504              :                END IF
     505              : 
     506           52 :                exc = exc - dft_control%sic_scaling_b*nelec_spin(ispin)*exc_m
     507              : 
     508              :                ! and take care of the potential only vxc_rho is taken into account
     509           78 :                IF (.NOT. my_just_energy) THEN
     510           40 :                   CALL pw_axpy(my_vxc_rho(1), vxc_rho(ispin), -dft_control%sic_scaling_b)
     511           40 :                   CALL my_vxc_rho(1)%release()
     512           40 :                   CALL my_vxc_rho(2)%release()
     513           40 :                   DEALLOCATE (my_vxc_rho)
     514              :                END IF
     515              :             END DO
     516              : 
     517           78 :             DO ispin = 1, 2
     518           52 :                CALL xc_pw_pool%give_back_pw(rho_m_rspace(ispin))
     519           78 :                CALL xc_pw_pool%give_back_pw(rho_m_gspace(ispin))
     520              :             END DO
     521           26 :             DEALLOCATE (rho_m_rspace)
     522           26 :             DEALLOCATE (rho_m_gspace)
     523              : 
     524              :          END IF
     525              : 
     526              :          ! compute again the xc but now for Exc(n_down,n_down)
     527       133923 :          IF (dft_control%sic_method_id == sic_mauri_us .AND. .NOT. sic_scaling_b_zero) THEN
     528          276 :             ALLOCATE (rho_r(2))
     529           92 :             rho_r(1) = rho_struct_r(2)
     530           92 :             rho_r(2) = rho_struct_r(2)
     531           92 :             IF (rho_g_valid) THEN
     532          276 :                ALLOCATE (rho_g(2))
     533           92 :                rho_g(1) = rho_struct_g(2)
     534           92 :                rho_g(2) = rho_struct_g(2)
     535              :             END IF
     536              : 
     537           92 :             IF (my_just_energy) THEN
     538              :                exc_m = xc_exc_calc(rho_r=rho_r, tau=tau, &
     539              :                                    rho_g=rho_g, xc_section=xc_section, &
     540           32 :                                    weights=weights_use, pw_pool=xc_pw_pool)
     541              :             ELSE
     542              :                ! virial untested
     543           60 :                CPASSERT(.NOT. compute_virial)
     544              :                CALL xc_vxc_pw_create(vxc_rho=my_vxc_rho, vxc_tau=my_vxc_tau, rho_r=rho_r, &
     545              :                                      rho_g=rho_g, tau=tau, exc=exc_m, &
     546              :                                      xc_section=xc_section, &
     547              :                                      weights=weights_use, pw_pool=xc_pw_pool, &
     548              :                                      compute_virial=.FALSE., &
     549           60 :                                      virial_xc=virial_xc_tmp)
     550              :             END IF
     551              : 
     552           92 :             exc = exc + dft_control%sic_scaling_b*exc_m
     553              : 
     554              :             ! and take care of the potential
     555           92 :             IF (.NOT. my_just_energy) THEN
     556              :                ! both go to minority spin
     557           60 :                CALL pw_axpy(my_vxc_rho(1), vxc_rho(2), 2.0_dp*dft_control%sic_scaling_b)
     558           60 :                CALL my_vxc_rho(1)%release()
     559           60 :                CALL my_vxc_rho(2)%release()
     560           60 :                DEALLOCATE (my_vxc_rho)
     561              :             END IF
     562           92 :             DEALLOCATE (rho_r, rho_g)
     563              : 
     564              :          END IF
     565              : 
     566              :          !
     567              :          ! cleanups
     568              :          !
     569       133923 :          IF (uf_grid .AND. (ASSOCIATED(vxc_rho) .OR. ASSOCIATED(vxc_tau))) THEN
     570              :             BLOCK
     571              :                TYPE(pw_r3d_rs_type) :: tmp_pw
     572              :                TYPE(pw_c1d_gs_type) :: tmp_g, tmp_g2
     573         1018 :                CALL xc_pw_pool%create_pw(tmp_g)
     574         1018 :                CALL auxbas_pw_pool%create_pw(tmp_g2)
     575         1018 :                IF (ASSOCIATED(vxc_rho)) THEN
     576         2036 :                   DO ispin = 1, SIZE(vxc_rho)
     577         1018 :                      CALL auxbas_pw_pool%create_pw(tmp_pw)
     578         1018 :                      CALL pw_transfer(vxc_rho(ispin), tmp_g)
     579         1018 :                      CALL pw_transfer(tmp_g, tmp_g2)
     580         1018 :                      CALL pw_transfer(tmp_g2, tmp_pw)
     581         1018 :                      CALL xc_pw_pool%give_back_pw(vxc_rho(ispin))
     582         2036 :                      vxc_rho(ispin) = tmp_pw
     583              :                   END DO
     584              :                END IF
     585         1018 :                IF (ASSOCIATED(vxc_tau)) THEN
     586          500 :                   DO ispin = 1, SIZE(vxc_tau)
     587          250 :                      CALL auxbas_pw_pool%create_pw(tmp_pw)
     588          250 :                      CALL pw_transfer(vxc_tau(ispin), tmp_g)
     589          250 :                      CALL pw_transfer(tmp_g, tmp_g2)
     590          250 :                      CALL pw_transfer(tmp_g2, tmp_pw)
     591          250 :                      CALL xc_pw_pool%give_back_pw(vxc_tau(ispin))
     592          500 :                      vxc_tau(ispin) = tmp_pw
     593              :                   END DO
     594              :                END IF
     595         1018 :                CALL auxbas_pw_pool%give_back_pw(tmp_g2)
     596         2036 :                CALL xc_pw_pool%give_back_pw(tmp_g)
     597              :             END BLOCK
     598              :          END IF
     599       133923 :          IF (ASSOCIATED(tau) .AND. uf_grid) THEN
     600          500 :             DO ispin = 1, SIZE(tau)
     601          500 :                CALL xc_pw_pool%give_back_pw(tau(ispin))
     602              :             END DO
     603          250 :             DEALLOCATE (tau)
     604              :          END IF
     605       133923 :          IF (ASSOCIATED(weights_xc)) THEN
     606         1004 :             CALL xc_pw_pool%give_back_pw(weights_xc)
     607         1004 :             DEALLOCATE (weights_xc)
     608              :          END IF
     609       133923 :          IF (ASSOCIATED(rho_nlcc_xc)) THEN
     610           28 :             CALL xc_pw_pool%give_back_pw(rho_nlcc_xc)
     611           28 :             DEALLOCATE (rho_nlcc_xc)
     612              :          END IF
     613       133923 :          IF (ASSOCIATED(rho_nlcc_g_xc)) THEN
     614           28 :             CALL xc_pw_pool%give_back_pw(rho_nlcc_g_xc)
     615           28 :             DEALLOCATE (rho_nlcc_g_xc)
     616              :          END IF
     617              : 
     618              :       END IF
     619              : 
     620       148547 :       CALL timestop(handle)
     621              : 
     622       148547 :    END SUBROUTINE qs_vxc_create
     623              : 
     624              : ! **************************************************************************************************
     625              : !> \brief calculates the XC density: E_xc(r) - V_xc(r)*rho(r)  or  E_xc(r)/rho(r)
     626              : !> \param ks_env to get all the needed things
     627              : !> \param rho_struct density
     628              : !> \param xc_section ...
     629              : !> \param dispersion_env ...
     630              : !> \param xc_ener will contain the xc energy density E_xc(r) - V_xc(r)*rho(r)
     631              : !> \param xc_den will contain the xc energy density E_xc(r)/rho(r)
     632              : !> \param exc will contain the xc energy density E_xc(r)
     633              : !> \param vxc ...
     634              : !> \param vtau ...
     635              : !> \author JGH
     636              : ! **************************************************************************************************
     637          500 :    SUBROUTINE qs_xc_density(ks_env, rho_struct, xc_section, dispersion_env, &
     638          100 :                             xc_ener, xc_den, exc, vxc, vtau)
     639              : 
     640              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     641              :       TYPE(qs_rho_type), POINTER                         :: rho_struct
     642              :       TYPE(section_vals_type), POINTER                   :: xc_section
     643              :       TYPE(qs_dispersion_type), OPTIONAL, POINTER        :: dispersion_env
     644              :       TYPE(pw_r3d_rs_type), INTENT(INOUT), OPTIONAL      :: xc_ener, xc_den
     645              :       TYPE(pw_r3d_rs_type), OPTIONAL                     :: exc
     646              :       TYPE(pw_r3d_rs_type), DIMENSION(:), OPTIONAL       :: vxc, vtau
     647              : 
     648              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_xc_density'
     649              : 
     650              :       INTEGER                                            :: handle, ispin, mspin, myfun, nspins, vdw
     651              :       LOGICAL                                            :: rho_g_valid, tau_g_valid, tau_r_valid, &
     652              :                                                             uf_grid, vdW_nl
     653              :       REAL(KIND=dp)                                      :: edisp, excint, factor, rho_cutoff
     654              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: vdum
     655              :       TYPE(cell_type), POINTER                           :: cell
     656              :       TYPE(dft_control_type), POINTER                    :: dft_control
     657              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     658          100 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g, rho_struct_g, tau_g, tau_struct_g
     659              :       TYPE(pw_c1d_gs_type), POINTER                      :: rho_nlcc_g, rho_nlcc_g_use, rho_nlcc_g_xc
     660              :       TYPE(pw_env_type), POINTER                         :: pw_env
     661              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, vdw_pw_pool, xc_pw_pool
     662              :       TYPE(pw_r3d_rs_type)                               :: exc_r
     663          100 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, rho_struct_r, tau_r, &
     664          100 :                                                             tau_struct_r, vxc_rho, vxc_tau
     665              :       TYPE(pw_r3d_rs_type), POINTER                      :: rho_nlcc, rho_nlcc_use, rho_nlcc_xc, &
     666              :                                                             weights, weights_use, weights_xc
     667              : 
     668          100 :       CALL timeset(routineN, handle)
     669              : 
     670          100 :       NULLIFY (dft_control, pw_env, auxbas_pw_pool, xc_pw_pool, vdw_pw_pool, cell, &
     671          100 :                rho_g, rho_struct_g, tau_g, tau_struct_g, rho_nlcc, rho_nlcc_g, &
     672          100 :                rho_nlcc_g_use, rho_nlcc_g_xc, rho_nlcc_use, rho_nlcc_xc, rho_r, &
     673          100 :                rho_struct_r, tau_r, tau_struct_r, vxc_rho, vxc_tau, weights, &
     674          100 :                weights_use, weights_xc)
     675              : 
     676              :       CALL get_ks_env(ks_env, &
     677              :                       dft_control=dft_control, &
     678              :                       pw_env=pw_env, &
     679              :                       cell=cell, &
     680              :                       xcint_weights=weights, &
     681              :                       rho_nlcc=rho_nlcc, &
     682          100 :                       rho_nlcc_g=rho_nlcc_g)
     683              : 
     684              :       CALL qs_rho_get(rho_struct, &
     685              :                       tau_r_valid=tau_r_valid, &
     686              :                       tau_g_valid=tau_g_valid, &
     687              :                       rho_g_valid=rho_g_valid, &
     688              :                       rho_r=rho_struct_r, &
     689              :                       rho_g=rho_struct_g, &
     690              :                       tau_r=tau_struct_r, &
     691          100 :                       tau_g=tau_struct_g)
     692          100 :       nspins = dft_control%nspins
     693          100 :       mspin = SIZE(rho_struct_r)
     694          100 :       rho_r => rho_struct_r
     695          100 :       rho_g => rho_struct_g
     696          100 :       tau_r => tau_struct_r
     697          100 :       tau_g => tau_struct_g
     698          100 :       rho_nlcc_use => rho_nlcc
     699          100 :       rho_nlcc_g_use => rho_nlcc_g
     700          100 :       weights_use => weights
     701              : 
     702          100 :       CALL section_vals_val_get(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", i_val=myfun)
     703          100 :       CALL section_vals_val_get(xc_section, "VDW_POTENTIAL%POTENTIAL_TYPE", i_val=vdw)
     704          100 :       vdW_nl = (vdw == xc_vdw_fun_nonloc)
     705          100 :       IF (PRESENT(xc_ener)) THEN
     706           34 :          IF (tau_r_valid) THEN
     707            0 :             CALL cp_warn(__LOCATION__, "Tau contribution will not be correctly handled")
     708              :          END IF
     709              :       END IF
     710          100 :       IF (vdW_nl) THEN
     711            0 :          CALL cp_warn(__LOCATION__, "vdW functional contribution will be ignored")
     712              :       END IF
     713              : 
     714          100 :       CALL pw_env_get(pw_env, xc_pw_pool=xc_pw_pool, auxbas_pw_pool=auxbas_pw_pool)
     715          100 :       uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
     716              : 
     717          100 :       IF (PRESENT(xc_ener)) THEN
     718           34 :          CALL pw_zero(xc_ener)
     719              :       END IF
     720          100 :       IF (PRESENT(xc_den)) THEN
     721           66 :          CALL pw_zero(xc_den)
     722              :       END IF
     723          100 :       IF (PRESENT(exc)) THEN
     724            0 :          CALL pw_zero(exc)
     725              :       END IF
     726          100 :       IF (PRESENT(vxc)) THEN
     727          138 :          DO ispin = 1, nspins
     728          138 :             CALL pw_zero(vxc(ispin))
     729              :          END DO
     730              :       END IF
     731          100 :       IF (PRESENT(vtau)) THEN
     732           40 :          DO ispin = 1, nspins
     733           40 :             CALL pw_zero(vtau(ispin))
     734              :          END DO
     735              :       END IF
     736              : 
     737          100 :       IF (myfun /= xc_none) THEN
     738              : 
     739           98 :          CPASSERT(ASSOCIATED(rho_struct))
     740           98 :          CPASSERT(dft_control%sic_method_id == sic_none)
     741              : 
     742           98 :          IF (uf_grid) THEN
     743            2 :             NULLIFY (rho_r, rho_g, tau_r, tau_g)
     744            2 :             IF (rho_g_valid) THEN
     745            2 :                CALL create_density_on_pool(xc_pw_pool, rho_struct_g, rho_r, rho_g)
     746            0 :             ELSEIF (ASSOCIATED(rho_struct_r)) THEN
     747            0 :                CALL create_density_on_pool_from_r(auxbas_pw_pool, xc_pw_pool, rho_struct_r, rho_r, rho_g)
     748              :             ELSE
     749            0 :                CPABORT("Fine Grid in qs_xc_density requires rho_r or rho_g")
     750              :             END IF
     751            2 :             IF (tau_r_valid) THEN
     752            0 :                IF (tau_g_valid) THEN
     753            0 :                   CALL create_density_on_pool(xc_pw_pool, tau_struct_g, tau_r, tau_g)
     754            0 :                ELSEIF (ASSOCIATED(tau_struct_r)) THEN
     755            0 :                   CALL create_density_on_pool_from_r(auxbas_pw_pool, xc_pw_pool, tau_struct_r, tau_r, tau_g)
     756              :                ELSE
     757            0 :                   CPABORT("Fine Grid in qs_xc_density requires tau_r or tau_g")
     758              :                END IF
     759              :             END IF
     760            2 :             IF (ASSOCIATED(weights)) THEN
     761            2 :                ALLOCATE (weights_xc)
     762            2 :                CALL xc_pw_pool%create_pw(weights_xc)
     763            2 :                CALL transfer_rspace_between_pools(auxbas_pw_pool, xc_pw_pool, weights, weights_xc)
     764            2 :                weights_use => weights_xc
     765              :             END IF
     766            2 :             IF (ASSOCIATED(rho_nlcc)) THEN
     767            0 :                CPASSERT(ASSOCIATED(rho_nlcc_g))
     768            0 :                ALLOCATE (rho_nlcc_g_xc, rho_nlcc_xc)
     769            0 :                CALL xc_pw_pool%create_pw(rho_nlcc_g_xc)
     770            0 :                CALL xc_pw_pool%create_pw(rho_nlcc_xc)
     771            0 :                CALL pw_transfer(rho_nlcc_g, rho_nlcc_g_xc)
     772            0 :                CALL pw_transfer(rho_nlcc_g_xc, rho_nlcc_xc)
     773            0 :                rho_nlcc_use => rho_nlcc_xc
     774            0 :                rho_nlcc_g_use => rho_nlcc_g_xc
     775              :             END IF
     776              :          END IF
     777              : 
     778              :          ! add the nlcc densities
     779           98 :          IF (ASSOCIATED(rho_nlcc_use)) THEN
     780            0 :             factor = 1.0_dp
     781            0 :             DO ispin = 1, mspin
     782            0 :                CALL pw_axpy(rho_nlcc_use, rho_r(ispin), factor)
     783            0 :                CALL pw_axpy(rho_nlcc_g_use, rho_g(ispin), factor)
     784              :             END DO
     785              :          END IF
     786           98 :          NULLIFY (vxc_rho, vxc_tau)
     787              :          CALL xc_vxc_pw_create(vxc_rho=vxc_rho, vxc_tau=vxc_tau, rho_r=rho_r, &
     788              :                                rho_g=rho_g, tau=tau_r, exc=excint, &
     789              :                                xc_section=xc_section, &
     790              :                                weights=weights_use, pw_pool=xc_pw_pool, &
     791              :                                compute_virial=.FALSE., &
     792              :                                virial_xc=vdum, &
     793           98 :                                exc_r=exc_r)
     794              :          ! calclulate non-local vdW functional
     795              :          ! only if this XC_SECTION has it
     796              :          ! if yes, we use the dispersion_env from ks_env
     797              :          ! this is dangerous, as it assumes a special connection xc_section -> qs_env
     798           98 :          IF (vdW_nl) THEN
     799            0 :             CALL get_ks_env(ks_env=ks_env, para_env=para_env)
     800              :             ! no SIC functionals allowed
     801            0 :             CPASSERT(dft_control%sic_method_id == sic_none)
     802              :             !
     803            0 :             CALL pw_env_get(pw_env, vdw_pw_pool=vdw_pw_pool)
     804              :             CALL calculate_dispersion_nonloc(vxc_rho, rho_r, rho_g, edisp, dispersion_env, &
     805            0 :                                              .FALSE., vdw_pw_pool, xc_pw_pool, para_env)
     806              :          END IF
     807              : 
     808              :          ! remove the nlcc densities (keep stuff in original state)
     809           98 :          IF (ASSOCIATED(rho_nlcc_use)) THEN
     810            0 :             factor = -1.0_dp
     811            0 :             DO ispin = 1, mspin
     812            0 :                CALL pw_axpy(rho_nlcc_use, rho_r(ispin), factor)
     813            0 :                CALL pw_axpy(rho_nlcc_g_use, rho_g(ispin), factor)
     814              :             END DO
     815              :          END IF
     816              :          !
     817           98 :          IF (PRESENT(xc_den)) THEN
     818           64 :             rho_cutoff = 1.E-14_dp
     819           64 :             IF (uf_grid) THEN
     820              :                BLOCK
     821              :                   TYPE(pw_r3d_rs_type) :: tmp_pw
     822            0 :                   CALL xc_pw_pool%create_pw(tmp_pw)
     823            0 :                   CALL pw_copy(exc_r, tmp_pw)
     824            0 :                   CALL calc_xc_density(tmp_pw, rho_r, rho_cutoff)
     825            0 :                   CALL transfer_rspace_between_pools(xc_pw_pool, auxbas_pw_pool, tmp_pw, xc_den)
     826            0 :                   CALL xc_pw_pool%give_back_pw(tmp_pw)
     827              :                END BLOCK
     828              :             ELSE
     829           64 :                CALL pw_copy(exc_r, xc_den)
     830           64 :                CALL calc_xc_density(xc_den, rho_r, rho_cutoff)
     831              :             END IF
     832              :          END IF
     833           98 :          IF (PRESENT(xc_ener)) THEN
     834           34 :             IF (uf_grid) THEN
     835              :                BLOCK
     836              :                   TYPE(pw_r3d_rs_type) :: tmp_pw
     837            2 :                   CALL xc_pw_pool%create_pw(tmp_pw)
     838            2 :                   CALL pw_copy(exc_r, tmp_pw)
     839            4 :                   DO ispin = 1, nspins
     840            4 :                      CALL pw_multiply(tmp_pw, vxc_rho(ispin), rho_r(ispin), alpha=-1.0_dp)
     841              :                   END DO
     842            2 :                   CALL transfer_rspace_between_pools(xc_pw_pool, auxbas_pw_pool, tmp_pw, xc_ener)
     843            2 :                   CALL xc_pw_pool%give_back_pw(tmp_pw)
     844              :                END BLOCK
     845              :             ELSE
     846           32 :                CALL pw_copy(exc_r, xc_ener)
     847           64 :                DO ispin = 1, nspins
     848           64 :                   CALL pw_multiply(xc_ener, vxc_rho(ispin), rho_r(ispin), alpha=-1.0_dp)
     849              :                END DO
     850              :             END IF
     851              :          END IF
     852           98 :          IF (PRESENT(exc)) THEN
     853            0 :             IF (uf_grid) THEN
     854            0 :                CALL transfer_rspace_between_pools(xc_pw_pool, auxbas_pw_pool, exc_r, exc)
     855              :             ELSE
     856            0 :                CALL pw_copy(exc_r, exc)
     857              :             END IF
     858              :          END IF
     859           98 :          IF (PRESENT(vxc)) THEN
     860          134 :             DO ispin = 1, nspins
     861          134 :                IF (uf_grid) THEN
     862            0 :                   CALL transfer_rspace_between_pools(xc_pw_pool, auxbas_pw_pool, vxc_rho(ispin), vxc(ispin))
     863              :                ELSE
     864           70 :                   CALL pw_copy(vxc_rho(ispin), vxc(ispin))
     865              :                END IF
     866              :             END DO
     867              :          END IF
     868           98 :          IF (PRESENT(vtau) .AND. ASSOCIATED(vxc_tau)) THEN
     869           40 :             DO ispin = 1, nspins
     870           40 :                IF (uf_grid) THEN
     871            0 :                   CALL transfer_rspace_between_pools(xc_pw_pool, auxbas_pw_pool, vxc_tau(ispin), vtau(ispin))
     872              :                ELSE
     873           20 :                   CALL pw_copy(vxc_tau(ispin), vtau(ispin))
     874              :                END IF
     875              :             END DO
     876              :          END IF
     877              :          ! remove arrays
     878           98 :          IF (ASSOCIATED(vxc_rho)) THEN
     879          202 :             DO ispin = 1, nspins
     880          202 :                CALL vxc_rho(ispin)%release()
     881              :             END DO
     882           98 :             DEALLOCATE (vxc_rho)
     883              :          END IF
     884           98 :          IF (ASSOCIATED(vxc_tau)) THEN
     885           40 :             DO ispin = 1, nspins
     886           40 :                CALL vxc_tau(ispin)%release()
     887              :             END DO
     888           20 :             DEALLOCATE (vxc_tau)
     889              :          END IF
     890           98 :          CALL exc_r%release()
     891           98 :          IF (uf_grid) THEN
     892            2 :             CALL give_back_density_on_pool(xc_pw_pool, rho_r, rho_g)
     893            2 :             IF (ASSOCIATED(tau_r)) CALL give_back_density_on_pool(xc_pw_pool, tau_r, tau_g)
     894            2 :             IF (ASSOCIATED(weights_xc)) THEN
     895            2 :                CALL xc_pw_pool%give_back_pw(weights_xc)
     896            2 :                DEALLOCATE (weights_xc)
     897              :             END IF
     898            2 :             IF (ASSOCIATED(rho_nlcc_xc)) THEN
     899            0 :                CALL xc_pw_pool%give_back_pw(rho_nlcc_xc)
     900            0 :                DEALLOCATE (rho_nlcc_xc)
     901              :             END IF
     902            2 :             IF (ASSOCIATED(rho_nlcc_g_xc)) THEN
     903            0 :                CALL xc_pw_pool%give_back_pw(rho_nlcc_g_xc)
     904            0 :                DEALLOCATE (rho_nlcc_g_xc)
     905              :             END IF
     906              :          END IF
     907              :          !
     908              :       END IF
     909              : 
     910          100 :       CALL timestop(handle)
     911              : 
     912          100 :    END SUBROUTINE qs_xc_density
     913              : 
     914              : ! **************************************************************************************************
     915              : !> \brief transfers an r-space PW between two pools and writes into an existing target PW
     916              : !> \param source_pw_pool ...
     917              : !> \param target_pw_pool ...
     918              : !> \param source ...
     919              : !> \param TARGET ...
     920              : ! **************************************************************************************************
     921            4 :    SUBROUTINE transfer_rspace_between_pools(source_pw_pool, target_pw_pool, source, TARGET)
     922              :       TYPE(pw_pool_type), POINTER                        :: source_pw_pool, target_pw_pool
     923              :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                :: source, TARGET
     924              : 
     925              :       TYPE(pw_c1d_gs_type)                               :: source_g, target_g
     926              : 
     927            0 :       CPASSERT(ASSOCIATED(source_pw_pool))
     928            4 :       CPASSERT(ASSOCIATED(target_pw_pool))
     929              : 
     930            4 :       IF (pw_grid_compare(source_pw_pool%pw_grid, target_pw_pool%pw_grid)) THEN
     931            0 :          CALL pw_copy(source, TARGET)
     932              :       ELSE
     933            4 :          CALL source_pw_pool%create_pw(source_g)
     934            4 :          CALL target_pw_pool%create_pw(target_g)
     935            4 :          CALL pw_transfer(source, source_g)
     936            4 :          CALL pw_transfer(source_g, target_g)
     937            4 :          CALL pw_transfer(target_g, TARGET)
     938            4 :          CALL target_pw_pool%give_back_pw(target_g)
     939            4 :          CALL source_pw_pool%give_back_pw(source_g)
     940              :       END IF
     941              : 
     942            4 :    END SUBROUTINE transfer_rspace_between_pools
     943              : 
     944              : ! **************************************************************************************************
     945              : !> \brief transfers a g-space density to a given PW pool and creates its r-space representation
     946              : !> \param pw_pool ...
     947              : !> \param rho_g_in ...
     948              : !> \param rho_r_out ...
     949              : !> \param rho_g_out ...
     950              : ! **************************************************************************************************
     951            2 :    SUBROUTINE create_density_on_pool(pw_pool, rho_g_in, rho_r_out, rho_g_out)
     952              :       TYPE(pw_pool_type), POINTER                        :: pw_pool
     953              :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g_in
     954              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r_out
     955              :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g_out
     956              : 
     957              :       INTEGER                                            :: ispin, nspins
     958              : 
     959            2 :       CPASSERT(ASSOCIATED(pw_pool))
     960            2 :       CPASSERT(ASSOCIATED(rho_g_in))
     961              : 
     962            2 :       nspins = SIZE(rho_g_in)
     963           14 :       ALLOCATE (rho_r_out(nspins), rho_g_out(nspins))
     964            4 :       DO ispin = 1, nspins
     965            2 :          CALL pw_pool%create_pw(rho_g_out(ispin))
     966            2 :          CALL pw_pool%create_pw(rho_r_out(ispin))
     967            2 :          CALL pw_transfer(rho_g_in(ispin), rho_g_out(ispin))
     968            4 :          CALL pw_transfer(rho_g_out(ispin), rho_r_out(ispin))
     969              :       END DO
     970              : 
     971            2 :    END SUBROUTINE create_density_on_pool
     972              : 
     973              : ! **************************************************************************************************
     974              : !> \brief transfers an r-space density to a given PW pool and creates its g-space representation
     975              : !> \param source_pw_pool ...
     976              : !> \param target_pw_pool ...
     977              : !> \param rho_r_in ...
     978              : !> \param rho_r_out ...
     979              : !> \param rho_g_out ...
     980              : ! **************************************************************************************************
     981            0 :    SUBROUTINE create_density_on_pool_from_r(source_pw_pool, target_pw_pool, rho_r_in, rho_r_out, rho_g_out)
     982              :       TYPE(pw_pool_type), POINTER                        :: source_pw_pool, target_pw_pool
     983              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r_in, rho_r_out
     984              :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g_out
     985              : 
     986              :       INTEGER                                            :: ispin, nspins
     987              :       TYPE(pw_c1d_gs_type)                               :: rho_g_in
     988              : 
     989            0 :       CPASSERT(ASSOCIATED(source_pw_pool))
     990            0 :       CPASSERT(ASSOCIATED(target_pw_pool))
     991            0 :       CPASSERT(ASSOCIATED(rho_r_in))
     992              : 
     993            0 :       nspins = SIZE(rho_r_in)
     994            0 :       ALLOCATE (rho_r_out(nspins), rho_g_out(nspins))
     995            0 :       DO ispin = 1, nspins
     996            0 :          CALL source_pw_pool%create_pw(rho_g_in)
     997            0 :          CALL target_pw_pool%create_pw(rho_g_out(ispin))
     998            0 :          CALL target_pw_pool%create_pw(rho_r_out(ispin))
     999            0 :          CALL pw_transfer(rho_r_in(ispin), rho_g_in)
    1000            0 :          CALL pw_transfer(rho_g_in, rho_g_out(ispin))
    1001            0 :          CALL pw_transfer(rho_g_out(ispin), rho_r_out(ispin))
    1002            0 :          CALL source_pw_pool%give_back_pw(rho_g_in)
    1003              :       END DO
    1004              : 
    1005            0 :    END SUBROUTINE create_density_on_pool_from_r
    1006              : 
    1007              : ! **************************************************************************************************
    1008              : !> \brief returns temporary density arrays to the given PW pool
    1009              : !> \param pw_pool ...
    1010              : !> \param rho_r ...
    1011              : !> \param rho_g ...
    1012              : ! **************************************************************************************************
    1013            2 :    SUBROUTINE give_back_density_on_pool(pw_pool, rho_r, rho_g)
    1014              :       TYPE(pw_pool_type), POINTER                        :: pw_pool
    1015              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r
    1016              :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g
    1017              : 
    1018              :       INTEGER                                            :: ispin
    1019              : 
    1020            2 :       CPASSERT(ASSOCIATED(pw_pool))
    1021              : 
    1022            2 :       IF (ASSOCIATED(rho_r)) THEN
    1023            4 :          DO ispin = 1, SIZE(rho_r)
    1024            4 :             CALL pw_pool%give_back_pw(rho_r(ispin))
    1025              :          END DO
    1026            2 :          DEALLOCATE (rho_r)
    1027              :       END IF
    1028            2 :       IF (ASSOCIATED(rho_g)) THEN
    1029            4 :          DO ispin = 1, SIZE(rho_g)
    1030            4 :             CALL pw_pool%give_back_pw(rho_g(ispin))
    1031              :          END DO
    1032            2 :          DEALLOCATE (rho_g)
    1033              :       END IF
    1034              : 
    1035            2 :    END SUBROUTINE give_back_density_on_pool
    1036              : 
    1037              : END MODULE qs_vxc
        

Generated by: LCOV version 2.0-1