LCOV - code coverage report
Current view: top level - src - qs_vxc.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 260 293 88.7 %
Date: 2024-12-21 06:28:57 Functions: 2 2 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 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_create1
      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      500820 :    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_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      125205 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g, rho_m_gspace, rho_struct_g
     124             :       TYPE(pw_c1d_gs_type), POINTER                      :: rho_nlcc_g, tmp_g, tmp_g2
     125             :       TYPE(pw_env_type), POINTER                         :: pw_env
     126             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, vdw_pw_pool, xc_pw_pool
     127      125205 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: my_vxc_rho, my_vxc_tau, rho_m_rspace, &
     128      125205 :                                                             rho_r, rho_struct_r, tau, tau_struct_r
     129             :       TYPE(pw_r3d_rs_type), POINTER                      :: rho_nlcc, tmp_pw
     130             :       TYPE(virial_type), POINTER                         :: virial
     131             : 
     132      125205 :       CALL timeset(routineN, handle)
     133             : 
     134      125205 :       CPASSERT(.NOT. ASSOCIATED(vxc_rho))
     135      125205 :       CPASSERT(.NOT. ASSOCIATED(vxc_tau))
     136      125205 :       NULLIFY (dft_control, pw_env, auxbas_pw_pool, xc_pw_pool, vdw_pw_pool, cell, my_vxc_rho, &
     137      125205 :                tmp_pw, tmp_g, tmp_g2, my_vxc_tau, rho_g, rho_r, tau, rho_m_rspace, &
     138      125205 :                rho_m_gspace, rho_nlcc, rho_nlcc_g, rho_struct_r, rho_struct_g, tau_struct_r)
     139             : 
     140      125205 :       exc = 0.0_dp
     141      125205 :       my_just_energy = .FALSE.
     142      125205 :       IF (PRESENT(just_energy)) my_just_energy = just_energy
     143      125205 :       my_adiabatic_rescale_factor = 1.0_dp
     144      125205 :       do_adiabatic_rescaling = .FALSE.
     145      125205 :       IF (PRESENT(adiabatic_rescale_factor)) THEN
     146          48 :          my_adiabatic_rescale_factor = adiabatic_rescale_factor
     147          48 :          do_adiabatic_rescaling = .TRUE.
     148             :       END IF
     149             : 
     150             :       CALL get_ks_env(ks_env, &
     151             :                       dft_control=dft_control, &
     152             :                       pw_env=pw_env, &
     153             :                       cell=cell, &
     154             :                       virial=virial, &
     155             :                       rho_nlcc=rho_nlcc, &
     156      125205 :                       rho_nlcc_g=rho_nlcc_g)
     157             : 
     158             :       CALL qs_rho_get(rho_struct, &
     159             :                       tau_r_valid=tau_r_valid, &
     160             :                       rho_g_valid=rho_g_valid, &
     161             :                       rho_r=rho_struct_r, &
     162             :                       rho_g=rho_struct_g, &
     163      125205 :                       tau_r=tau_struct_r)
     164             : 
     165      125205 :       compute_virial = virial%pv_calculate .AND. (.NOT. virial%pv_numer)
     166      125205 :       IF (compute_virial) THEN
     167       35256 :          virial%pv_xc = 0.0_dp
     168             :       END IF
     169             : 
     170             :       CALL section_vals_val_get(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", &
     171      125205 :                                 i_val=myfun)
     172             :       CALL section_vals_val_get(xc_section, "VDW_POTENTIAL%POTENTIAL_TYPE", &
     173      125205 :                                 i_val=vdw)
     174             : 
     175      125205 :       vdW_nl = (vdw == xc_vdw_fun_nonloc)
     176             :       ! this combination has not been investigated
     177      125205 :       CPASSERT(.NOT. (do_adiabatic_rescaling .AND. vdW_nl))
     178             :       ! are the necessary inputs available
     179      125205 :       IF (.NOT. (PRESENT(dispersion_env) .AND. PRESENT(edisp))) THEN
     180             :          vdW_nl = .FALSE.
     181             :       END IF
     182      125205 :       IF (PRESENT(edisp)) edisp = 0.0_dp
     183             : 
     184      125205 :       IF (myfun /= xc_none .OR. vdW_nl) THEN
     185             : 
     186             :          ! test if the real space density is available
     187      112245 :          CPASSERT(ASSOCIATED(rho_struct))
     188      112245 :          IF (dft_control%nspins /= 1 .AND. dft_control%nspins /= 2) &
     189           0 :             CPABORT("nspins must be 1 or 2")
     190      112245 :          mspin = SIZE(rho_struct_r)
     191      112245 :          IF (dft_control%nspins == 2 .AND. mspin == 1) &
     192           0 :             CPABORT("Spin count mismatch")
     193             : 
     194             :          ! there are some options related to SIC here.
     195             :          ! Normal DFT computes E(rho_alpha,rho_beta) (or its variant E(2*rho_alpha) for non-LSD)
     196             :          ! SIC can             E(rho_alpha,rho_beta)-b*(E(rho_alpha,rho_beta)-E(rho_beta,rho_beta))
     197             :          ! or compute          E(rho_alpha,rho_beta)-b*E(rho_alpha-rho_beta,0)
     198             : 
     199             :          ! my_scaling is the scaling needed of the standard E(rho_alpha,rho_beta) term
     200      112245 :          my_scaling = 1.0_dp
     201      112385 :          SELECT CASE (dft_control%sic_method_id)
     202             :          CASE (sic_none)
     203             :             ! all fine
     204             :          CASE (sic_mauri_spz, sic_ad)
     205             :             ! no idea yet what to do here in that case
     206         140 :             CPASSERT(.NOT. tau_r_valid)
     207             :          CASE (sic_mauri_us)
     208          60 :             my_scaling = 1.0_dp - dft_control%sic_scaling_b
     209             :             ! no idea yet what to do here in that case
     210          60 :             CPASSERT(.NOT. tau_r_valid)
     211             :          CASE (sic_eo)
     212             :             ! NOTHING TO BE DONE
     213             :          CASE DEFAULT
     214             :             ! this case has not yet been treated here
     215      112245 :             CPABORT("NYI")
     216             :          END SELECT
     217             : 
     218      112245 :          IF (dft_control%sic_scaling_b .EQ. 0.0_dp) THEN
     219             :             sic_scaling_b_zero = .TRUE.
     220             :          ELSE
     221      112179 :             sic_scaling_b_zero = .FALSE.
     222             :          END IF
     223             : 
     224      112245 :          IF (PRESENT(pw_env_external)) &
     225           0 :             pw_env => pw_env_external
     226      112245 :          CALL pw_env_get(pw_env, xc_pw_pool=xc_pw_pool, auxbas_pw_pool=auxbas_pw_pool)
     227      112245 :          uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
     228             : 
     229      112245 :          IF (.NOT. uf_grid) THEN
     230      112231 :             rho_r => rho_struct_r
     231             : 
     232      112231 :             IF (tau_r_valid) THEN
     233        2580 :                tau => tau_struct_r
     234             :             END IF
     235             : 
     236             :             ! for gradient corrected functional the density in g space might
     237             :             ! be useful so if we have it, we pass it in
     238      112231 :             IF (rho_g_valid) THEN
     239      112211 :                rho_g => rho_struct_g
     240             :             END IF
     241             :          ELSE
     242          14 :             CPASSERT(rho_g_valid)
     243          56 :             ALLOCATE (rho_r(mspin))
     244          56 :             ALLOCATE (rho_g(mspin))
     245          28 :             DO ispin = 1, mspin
     246          14 :                CALL xc_pw_pool%create_pw(rho_g(ispin))
     247          28 :                CALL pw_transfer(rho_struct_g(ispin), rho_g(ispin))
     248             :             END DO
     249          28 :             DO ispin = 1, mspin
     250          14 :                CALL xc_pw_pool%create_pw(rho_r(ispin))
     251          28 :                CALL pw_transfer(rho_g(ispin), rho_r(ispin))
     252             :             END DO
     253          14 :             IF (tau_r_valid) THEN
     254             :                ! tau with finer grids is not implemented (at least not correctly), which this asserts
     255           0 :                CPABORT("tau with finer grids not implemented")
     256             :             END IF
     257             :          END IF
     258             : 
     259             :          ! add the nlcc densities
     260      112245 :          IF (ASSOCIATED(rho_nlcc)) THEN
     261         320 :             factor = 1.0_dp
     262         640 :             DO ispin = 1, mspin
     263         320 :                CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     264         640 :                CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     265             :             END DO
     266             :          END IF
     267             : 
     268             :          !
     269             :          ! here the rho_r, rho_g, tau is what it should be
     270             :          ! we get back the right my_vxc_rho and my_vxc_tau as required
     271             :          !
     272      112245 :          IF (my_just_energy) THEN
     273             :             exc = xc_exc_calc(rho_r=rho_r, tau=tau, &
     274             :                               rho_g=rho_g, xc_section=xc_section, &
     275        7711 :                               pw_pool=xc_pw_pool)
     276             : 
     277             :          ELSE
     278             :             CALL xc_vxc_pw_create1(vxc_rho=my_vxc_rho, vxc_tau=my_vxc_tau, rho_r=rho_r, &
     279             :                                    rho_g=rho_g, tau=tau, exc=exc, &
     280             :                                    xc_section=xc_section, &
     281             :                                    pw_pool=xc_pw_pool, &
     282             :                                    compute_virial=compute_virial, &
     283      104534 :                                    virial_xc=virial%pv_xc)
     284             :          END IF
     285             : 
     286             :          ! remove the nlcc densities (keep stuff in original state)
     287      112245 :          IF (ASSOCIATED(rho_nlcc)) THEN
     288         320 :             factor = -1.0_dp
     289         640 :             DO ispin = 1, mspin
     290         320 :                CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     291         640 :                CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     292             :             END DO
     293             :          END IF
     294             : 
     295             :          ! calclulate non-local vdW functional
     296             :          ! only if this XC_SECTION has it
     297             :          ! if yes, we use the dispersion_env from ks_env
     298             :          ! this is dangerous, as it assumes a special connection xc_section -> qs_env
     299      112245 :          IF (vdW_nl) THEN
     300         388 :             CALL get_ks_env(ks_env=ks_env, para_env=para_env)
     301             :             ! no SIC functionals allowed
     302         388 :             CPASSERT(dft_control%sic_method_id == sic_none)
     303             :             !
     304         388 :             CALL pw_env_get(pw_env, vdw_pw_pool=vdw_pw_pool)
     305         388 :             IF (my_just_energy) THEN
     306             :                CALL calculate_dispersion_nonloc(my_vxc_rho, rho_r, rho_g, edisp, dispersion_env, &
     307           6 :                                                 my_just_energy, vdw_pw_pool, xc_pw_pool, para_env)
     308             :             ELSE
     309             :                CALL calculate_dispersion_nonloc(my_vxc_rho, rho_r, rho_g, edisp, dispersion_env, &
     310         382 :                                                 my_just_energy, vdw_pw_pool, xc_pw_pool, para_env, virial=virial)
     311             :             END IF
     312             :          END IF
     313             : 
     314             :          !! Apply rescaling to the potential if requested
     315      112245 :          IF (.NOT. my_just_energy) THEN
     316      104534 :             IF (do_adiabatic_rescaling) THEN
     317          26 :                IF (ASSOCIATED(my_vxc_rho)) THEN
     318          68 :                   DO ispin = 1, SIZE(my_vxc_rho)
     319          68 :                      CALL pw_scale(my_vxc_rho(ispin), my_adiabatic_rescale_factor)
     320             :                   END DO
     321             :                END IF
     322             :             END IF
     323             :          END IF
     324             : 
     325      112245 :          IF (my_scaling .NE. 1.0_dp) THEN
     326          60 :             exc = exc*my_scaling
     327          60 :             IF (ASSOCIATED(my_vxc_rho)) THEN
     328         132 :                DO ispin = 1, SIZE(my_vxc_rho)
     329         132 :                   CALL pw_scale(my_vxc_rho(ispin), my_scaling)
     330             :                END DO
     331             :             END IF
     332          60 :             IF (ASSOCIATED(my_vxc_tau)) THEN
     333           0 :                DO ispin = 1, SIZE(my_vxc_tau)
     334           0 :                   CALL pw_scale(my_vxc_tau(ispin), my_scaling)
     335             :                END DO
     336             :             END IF
     337             :          END IF
     338             : 
     339             :          ! we have pw data for the xc, qs_ks requests coeff structure, here we transfer
     340             :          ! pw -> coeff
     341      112245 :          IF (ASSOCIATED(my_vxc_rho)) THEN
     342      104534 :             vxc_rho => my_vxc_rho
     343      104534 :             NULLIFY (my_vxc_rho)
     344             :          END IF
     345      112245 :          IF (ASSOCIATED(my_vxc_tau)) THEN
     346        1930 :             vxc_tau => my_vxc_tau
     347        1930 :             NULLIFY (my_vxc_tau)
     348             :          END IF
     349      112245 :          IF (uf_grid) THEN
     350          28 :             DO ispin = 1, SIZE(rho_r)
     351          28 :                CALL xc_pw_pool%give_back_pw(rho_r(ispin))
     352             :             END DO
     353          14 :             DEALLOCATE (rho_r)
     354          14 :             IF (ASSOCIATED(rho_g)) THEN
     355          28 :                DO ispin = 1, SIZE(rho_g)
     356          28 :                   CALL xc_pw_pool%give_back_pw(rho_g(ispin))
     357             :                END DO
     358          14 :                DEALLOCATE (rho_g)
     359             :             END IF
     360             :          END IF
     361             : 
     362             :          ! compute again the xc but now for Exc(m,o) and the opposite sign
     363      112245 :          IF (dft_control%sic_method_id .EQ. sic_mauri_spz .AND. .NOT. sic_scaling_b_zero) THEN
     364         270 :             ALLOCATE (rho_m_rspace(2), rho_m_gspace(2))
     365          54 :             CALL xc_pw_pool%create_pw(rho_m_gspace(1))
     366          54 :             CALL xc_pw_pool%create_pw(rho_m_rspace(1))
     367          54 :             CALL pw_copy(rho_struct_r(1), rho_m_rspace(1))
     368          54 :             CALL pw_axpy(rho_struct_r(2), rho_m_rspace(1), alpha=-1._dp)
     369          54 :             CALL pw_copy(rho_struct_g(1), rho_m_gspace(1))
     370          54 :             CALL pw_axpy(rho_struct_g(2), rho_m_gspace(1), alpha=-1._dp)
     371             :             ! bit sad, these will be just zero...
     372          54 :             CALL xc_pw_pool%create_pw(rho_m_gspace(2))
     373          54 :             CALL xc_pw_pool%create_pw(rho_m_rspace(2))
     374          54 :             CALL pw_zero(rho_m_rspace(2))
     375          54 :             CALL pw_zero(rho_m_gspace(2))
     376             : 
     377          54 :             IF (my_just_energy) THEN
     378             :                exc_m = xc_exc_calc(rho_r=rho_m_rspace, tau=tau, &
     379             :                                    rho_g=rho_m_gspace, xc_section=xc_section, &
     380          12 :                                    pw_pool=xc_pw_pool)
     381             :             ELSE
     382             :                ! virial untested
     383          42 :                CPASSERT(.NOT. compute_virial)
     384             :                CALL xc_vxc_pw_create1(vxc_rho=my_vxc_rho, vxc_tau=my_vxc_tau, rho_r=rho_m_rspace, &
     385             :                                       rho_g=rho_m_gspace, tau=tau, exc=exc_m, &
     386             :                                       xc_section=xc_section, &
     387             :                                       pw_pool=xc_pw_pool, &
     388             :                                       compute_virial=.FALSE., &
     389          42 :                                       virial_xc=virial_xc_tmp)
     390             :             END IF
     391             : 
     392          54 :             exc = exc - dft_control%sic_scaling_b*exc_m
     393             : 
     394             :             ! and take care of the potential only vxc_rho is taken into account
     395          54 :             IF (.NOT. my_just_energy) THEN
     396          42 :                CALL pw_axpy(my_vxc_rho(1), vxc_rho(1), -dft_control%sic_scaling_b)
     397          42 :                CALL pw_axpy(my_vxc_rho(1), vxc_rho(2), dft_control%sic_scaling_b)
     398          42 :                CALL my_vxc_rho(1)%release()
     399          42 :                CALL my_vxc_rho(2)%release()
     400          42 :                DEALLOCATE (my_vxc_rho)
     401             :             END IF
     402             : 
     403         162 :             DO ispin = 1, 2
     404         108 :                CALL xc_pw_pool%give_back_pw(rho_m_rspace(ispin))
     405         162 :                CALL xc_pw_pool%give_back_pw(rho_m_gspace(ispin))
     406             :             END DO
     407          54 :             DEALLOCATE (rho_m_rspace)
     408          54 :             DEALLOCATE (rho_m_gspace)
     409             : 
     410             :          END IF
     411             : 
     412             :          ! now we have - sum_s N_s * Exc(rho_s/N_s,0)
     413      112245 :          IF (dft_control%sic_method_id .EQ. sic_ad .AND. .NOT. sic_scaling_b_zero) THEN
     414             : 
     415             :             ! find out how many elecs we have
     416          20 :             CALL get_ks_env(ks_env, nelectron_spin=nelec_spin)
     417             : 
     418         100 :             ALLOCATE (rho_m_rspace(2), rho_m_gspace(2))
     419          60 :             DO ispin = 1, 2
     420          40 :                CALL xc_pw_pool%create_pw(rho_m_gspace(ispin))
     421          60 :                CALL xc_pw_pool%create_pw(rho_m_rspace(ispin))
     422             :             END DO
     423             : 
     424          60 :             DO ispin = 1, 2
     425          40 :                IF (nelec_spin(ispin) .GT. 0.0_dp) THEN
     426          40 :                   nelec_s_inv = 1.0_dp/nelec_spin(ispin)
     427             :                ELSE
     428             :                   ! does it matter if there are no electrons with this spin (H) ?
     429           0 :                   nelec_s_inv = 0.0_dp
     430             :                END IF
     431          40 :                CALL pw_copy(rho_struct_r(ispin), rho_m_rspace(1))
     432          40 :                CALL pw_copy(rho_struct_g(ispin), rho_m_gspace(1))
     433          40 :                CALL pw_scale(rho_m_rspace(1), nelec_s_inv)
     434          40 :                CALL pw_scale(rho_m_gspace(1), nelec_s_inv)
     435          40 :                CALL pw_zero(rho_m_rspace(2))
     436          40 :                CALL pw_zero(rho_m_gspace(2))
     437             : 
     438          40 :                IF (my_just_energy) THEN
     439             :                   exc_m = xc_exc_calc(rho_r=rho_m_rspace, tau=tau, &
     440             :                                       rho_g=rho_m_gspace, xc_section=xc_section, &
     441           8 :                                       pw_pool=xc_pw_pool)
     442             :                ELSE
     443             :                   ! virial untested
     444          32 :                   CPASSERT(.NOT. compute_virial)
     445             :                   CALL xc_vxc_pw_create1(vxc_rho=my_vxc_rho, vxc_tau=my_vxc_tau, rho_r=rho_m_rspace, &
     446             :                                          rho_g=rho_m_gspace, tau=tau, exc=exc_m, &
     447             :                                          xc_section=xc_section, &
     448             :                                          pw_pool=xc_pw_pool, &
     449             :                                          compute_virial=.FALSE., &
     450          32 :                                          virial_xc=virial_xc_tmp)
     451             :                END IF
     452             : 
     453          40 :                exc = exc - dft_control%sic_scaling_b*nelec_spin(ispin)*exc_m
     454             : 
     455             :                ! and take care of the potential only vxc_rho is taken into account
     456          60 :                IF (.NOT. my_just_energy) THEN
     457          32 :                   CALL pw_axpy(my_vxc_rho(1), vxc_rho(ispin), -dft_control%sic_scaling_b)
     458          32 :                   CALL my_vxc_rho(1)%release()
     459          32 :                   CALL my_vxc_rho(2)%release()
     460          32 :                   DEALLOCATE (my_vxc_rho)
     461             :                END IF
     462             :             END DO
     463             : 
     464          60 :             DO ispin = 1, 2
     465          40 :                CALL xc_pw_pool%give_back_pw(rho_m_rspace(ispin))
     466          60 :                CALL xc_pw_pool%give_back_pw(rho_m_gspace(ispin))
     467             :             END DO
     468          20 :             DEALLOCATE (rho_m_rspace)
     469          20 :             DEALLOCATE (rho_m_gspace)
     470             : 
     471             :          END IF
     472             : 
     473             :          ! compute again the xc but now for Exc(n_down,n_down)
     474      112245 :          IF (dft_control%sic_method_id .EQ. sic_mauri_us .AND. .NOT. sic_scaling_b_zero) THEN
     475         180 :             ALLOCATE (rho_r(2))
     476          60 :             rho_r(1) = rho_struct_r(2)
     477          60 :             rho_r(2) = rho_struct_r(2)
     478          60 :             IF (rho_g_valid) THEN
     479         180 :                ALLOCATE (rho_g(2))
     480          60 :                rho_g(1) = rho_struct_g(2)
     481          60 :                rho_g(2) = rho_struct_g(2)
     482             :             END IF
     483             : 
     484          60 :             IF (my_just_energy) THEN
     485             :                exc_m = xc_exc_calc(rho_r=rho_r, tau=tau, &
     486             :                                    rho_g=rho_g, xc_section=xc_section, &
     487          16 :                                    pw_pool=xc_pw_pool)
     488             :             ELSE
     489             :                ! virial untested
     490          44 :                CPASSERT(.NOT. compute_virial)
     491             :                CALL xc_vxc_pw_create1(vxc_rho=my_vxc_rho, vxc_tau=my_vxc_tau, rho_r=rho_r, &
     492             :                                       rho_g=rho_g, tau=tau, exc=exc_m, &
     493             :                                       xc_section=xc_section, &
     494             :                                       pw_pool=xc_pw_pool, &
     495             :                                       compute_virial=.FALSE., &
     496          44 :                                       virial_xc=virial_xc_tmp)
     497             :             END IF
     498             : 
     499          60 :             exc = exc + dft_control%sic_scaling_b*exc_m
     500             : 
     501             :             ! and take care of the potential
     502          60 :             IF (.NOT. my_just_energy) THEN
     503             :                ! both go to minority spin
     504          44 :                CALL pw_axpy(my_vxc_rho(1), vxc_rho(2), 2.0_dp*dft_control%sic_scaling_b)
     505          44 :                CALL my_vxc_rho(1)%release()
     506          44 :                CALL my_vxc_rho(2)%release()
     507          44 :                DEALLOCATE (my_vxc_rho)
     508             :             END IF
     509          60 :             DEALLOCATE (rho_r, rho_g)
     510             : 
     511             :          END IF
     512             : 
     513             :          !
     514             :          ! cleanups
     515             :          !
     516      112245 :          IF (uf_grid .AND. (ASSOCIATED(vxc_rho) .OR. ASSOCIATED(vxc_tau))) THEN
     517             :             BLOCK
     518             :                TYPE(pw_r3d_rs_type) :: tmp_pw
     519             :                TYPE(pw_c1d_gs_type) :: tmp_g, tmp_g2
     520          14 :                CALL xc_pw_pool%create_pw(tmp_g)
     521          14 :                CALL auxbas_pw_pool%create_pw(tmp_g2)
     522          14 :                IF (ASSOCIATED(vxc_rho)) THEN
     523          28 :                   DO ispin = 1, SIZE(vxc_rho)
     524          14 :                      CALL auxbas_pw_pool%create_pw(tmp_pw)
     525          14 :                      CALL pw_transfer(vxc_rho(ispin), tmp_g)
     526          14 :                      CALL pw_transfer(tmp_g, tmp_g2)
     527          14 :                      CALL pw_transfer(tmp_g2, tmp_pw)
     528          14 :                      CALL xc_pw_pool%give_back_pw(vxc_rho(ispin))
     529          28 :                      vxc_rho(ispin) = tmp_pw
     530             :                   END DO
     531             :                END IF
     532          14 :                IF (ASSOCIATED(vxc_tau)) THEN
     533           0 :                   DO ispin = 1, SIZE(vxc_tau)
     534           0 :                      CALL auxbas_pw_pool%create_pw(tmp_pw)
     535           0 :                      CALL pw_transfer(vxc_tau(ispin), tmp_g)
     536           0 :                      CALL pw_transfer(tmp_g, tmp_g2)
     537           0 :                      CALL pw_transfer(tmp_g2, tmp_pw)
     538           0 :                      CALL xc_pw_pool%give_back_pw(vxc_tau(ispin))
     539           0 :                      vxc_tau(ispin) = tmp_pw
     540             :                   END DO
     541             :                END IF
     542          14 :                CALL auxbas_pw_pool%give_back_pw(tmp_g2)
     543          28 :                CALL xc_pw_pool%give_back_pw(tmp_g)
     544             :             END BLOCK
     545             :          END IF
     546      112245 :          IF (ASSOCIATED(tau) .AND. uf_grid) THEN
     547           0 :             DO ispin = 1, SIZE(tau)
     548           0 :                CALL xc_pw_pool%give_back_pw(tau(ispin))
     549             :             END DO
     550           0 :             DEALLOCATE (tau)
     551             :          END IF
     552             : 
     553             :       END IF
     554             : 
     555      125205 :       CALL timestop(handle)
     556             : 
     557      125205 :    END SUBROUTINE qs_vxc_create
     558             : 
     559             : ! **************************************************************************************************
     560             : !> \brief calculates the XC density: E_xc(r) - V_xc(r)*rho(r)  or  E_xc(r)/rho(r)
     561             : !> \param ks_env to get all the needed things
     562             : !> \param rho_struct density
     563             : !> \param xc_section ...
     564             : !> \param dispersion_env ...
     565             : !> \param xc_ener will contain the xc energy density E_xc(r) - V_xc(r)*rho(r)
     566             : !> \param xc_den will contain the xc energy density E_xc(r)/rho(r)
     567             : !> \param vxc ...
     568             : !> \param vtau ...
     569             : !> \author JGH
     570             : ! **************************************************************************************************
     571         490 :    SUBROUTINE qs_xc_density(ks_env, rho_struct, xc_section, dispersion_env, &
     572          98 :                             xc_ener, xc_den, vxc, vtau)
     573             : 
     574             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     575             :       TYPE(qs_rho_type), POINTER                         :: rho_struct
     576             :       TYPE(section_vals_type), POINTER                   :: xc_section
     577             :       TYPE(qs_dispersion_type), OPTIONAL, POINTER        :: dispersion_env
     578             :       TYPE(pw_r3d_rs_type), INTENT(INOUT), OPTIONAL      :: xc_ener, xc_den
     579             :       TYPE(pw_r3d_rs_type), DIMENSION(:), OPTIONAL       :: vxc, vtau
     580             : 
     581             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_xc_density'
     582             : 
     583             :       INTEGER                                            :: handle, ispin, myfun, nspins, vdw
     584             :       LOGICAL                                            :: rho_g_valid, tau_r_valid, uf_grid, vdW_nl
     585             :       REAL(KIND=dp)                                      :: edisp, exc, factor, rho_cutoff
     586             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: vdum
     587             :       TYPE(cell_type), POINTER                           :: cell
     588             :       TYPE(dft_control_type), POINTER                    :: dft_control
     589             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     590          98 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g
     591             :       TYPE(pw_c1d_gs_type), POINTER                      :: rho_nlcc_g
     592             :       TYPE(pw_env_type), POINTER                         :: pw_env
     593             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, vdw_pw_pool, xc_pw_pool
     594             :       TYPE(pw_r3d_rs_type)                               :: exc_r
     595          98 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, tau_r, vxc_rho, vxc_tau
     596             :       TYPE(pw_r3d_rs_type), POINTER                      :: rho_nlcc
     597             : 
     598          98 :       CALL timeset(routineN, handle)
     599             : 
     600             :       CALL get_ks_env(ks_env, &
     601             :                       dft_control=dft_control, &
     602             :                       pw_env=pw_env, &
     603             :                       cell=cell, &
     604             :                       rho_nlcc=rho_nlcc, &
     605          98 :                       rho_nlcc_g=rho_nlcc_g)
     606             : 
     607             :       CALL qs_rho_get(rho_struct, &
     608             :                       tau_r_valid=tau_r_valid, &
     609             :                       rho_g_valid=rho_g_valid, &
     610             :                       rho_r=rho_r, &
     611             :                       rho_g=rho_g, &
     612          98 :                       tau_r=tau_r)
     613          98 :       nspins = dft_control%nspins
     614             : 
     615          98 :       CALL section_vals_val_get(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", i_val=myfun)
     616          98 :       CALL section_vals_val_get(xc_section, "VDW_POTENTIAL%POTENTIAL_TYPE", i_val=vdw)
     617          98 :       vdW_nl = (vdw == xc_vdw_fun_nonloc)
     618          98 :       IF (PRESENT(xc_ener)) THEN
     619          32 :          IF (tau_r_valid) THEN
     620           0 :             CALL cp_warn(__LOCATION__, "Tau contribution will not be correctly handled")
     621             :          END IF
     622             :       END IF
     623          98 :       IF (vdW_nl) THEN
     624           0 :          CALL cp_warn(__LOCATION__, "vdW functional contribution will be ignored")
     625             :       END IF
     626             : 
     627          98 :       CALL pw_env_get(pw_env, xc_pw_pool=xc_pw_pool, auxbas_pw_pool=auxbas_pw_pool)
     628          98 :       uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
     629          98 :       IF (uf_grid) THEN
     630           0 :          CALL cp_warn(__LOCATION__, "Fine grid option not possible with local energy")
     631           0 :          CPABORT("Fine Grid in Local Energy")
     632             :       END IF
     633             : 
     634          98 :       IF (PRESENT(xc_ener)) THEN
     635          32 :          CALL pw_zero(xc_ener)
     636             :       END IF
     637          98 :       IF (PRESENT(xc_den)) THEN
     638          66 :          CALL pw_zero(xc_den)
     639             :       END IF
     640          98 :       IF (PRESENT(vxc)) THEN
     641         138 :          DO ispin = 1, nspins
     642         138 :             CALL pw_zero(vxc(ispin))
     643             :          END DO
     644             :       END IF
     645          98 :       IF (PRESENT(vtau)) THEN
     646          40 :          DO ispin = 1, nspins
     647          40 :             CALL pw_zero(vtau(ispin))
     648             :          END DO
     649             :       END IF
     650             : 
     651          98 :       IF (myfun /= xc_none) THEN
     652             : 
     653          96 :          CPASSERT(ASSOCIATED(rho_struct))
     654          96 :          CPASSERT(dft_control%sic_method_id == sic_none)
     655             : 
     656             :          ! add the nlcc densities
     657          96 :          IF (ASSOCIATED(rho_nlcc)) THEN
     658           0 :             factor = 1.0_dp
     659           0 :             DO ispin = 1, nspins
     660           0 :                CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     661           0 :                CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     662             :             END DO
     663             :          END IF
     664          96 :          NULLIFY (vxc_rho, vxc_tau)
     665             :          CALL xc_vxc_pw_create1(vxc_rho=vxc_rho, vxc_tau=vxc_tau, rho_r=rho_r, &
     666             :                                 rho_g=rho_g, tau=tau_r, exc=exc, &
     667             :                                 xc_section=xc_section, &
     668             :                                 pw_pool=xc_pw_pool, &
     669             :                                 compute_virial=.FALSE., &
     670             :                                 virial_xc=vdum, &
     671          96 :                                 exc_r=exc_r)
     672             :          ! calclulate non-local vdW functional
     673             :          ! only if this XC_SECTION has it
     674             :          ! if yes, we use the dispersion_env from ks_env
     675             :          ! this is dangerous, as it assumes a special connection xc_section -> qs_env
     676          96 :          IF (vdW_nl) THEN
     677           0 :             CALL get_ks_env(ks_env=ks_env, para_env=para_env)
     678             :             ! no SIC functionals allowed
     679           0 :             CPASSERT(dft_control%sic_method_id == sic_none)
     680             :             !
     681           0 :             CALL pw_env_get(pw_env, vdw_pw_pool=vdw_pw_pool)
     682             :             CALL calculate_dispersion_nonloc(vxc_rho, rho_r, rho_g, edisp, dispersion_env, &
     683           0 :                                              .FALSE., vdw_pw_pool, xc_pw_pool, para_env)
     684             :          END IF
     685             : 
     686             :          ! remove the nlcc densities (keep stuff in original state)
     687          96 :          IF (ASSOCIATED(rho_nlcc)) THEN
     688           0 :             factor = -1.0_dp
     689           0 :             DO ispin = 1, dft_control%nspins
     690           0 :                CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     691           0 :                CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     692             :             END DO
     693             :          END IF
     694             :          !
     695          96 :          IF (PRESENT(xc_den)) THEN
     696          64 :             CALL pw_copy(exc_r, xc_den)
     697          64 :             rho_cutoff = 1.E-14_dp
     698          64 :             CALL calc_xc_density(xc_den, rho_r, rho_cutoff)
     699             :          END IF
     700          96 :          IF (PRESENT(xc_ener)) THEN
     701          32 :             CALL pw_copy(exc_r, xc_ener)
     702          64 :             DO ispin = 1, nspins
     703          64 :                CALL pw_multiply(xc_ener, vxc_rho(ispin), rho_r(ispin), alpha=-1.0_dp)
     704             :             END DO
     705             :          END IF
     706          96 :          IF (PRESENT(vxc)) THEN
     707         134 :             DO ispin = 1, nspins
     708         134 :                CALL pw_copy(vxc_rho(ispin), vxc(ispin))
     709             :             END DO
     710             :          END IF
     711          96 :          IF (PRESENT(vtau)) THEN
     712          40 :             DO ispin = 1, nspins
     713          40 :                CALL pw_copy(vxc_tau(ispin), vtau(ispin))
     714             :             END DO
     715             :          END IF
     716             :          ! remove arrays
     717          96 :          IF (ASSOCIATED(vxc_rho)) THEN
     718         198 :             DO ispin = 1, nspins
     719         198 :                CALL vxc_rho(ispin)%release()
     720             :             END DO
     721          96 :             DEALLOCATE (vxc_rho)
     722             :          END IF
     723          96 :          IF (ASSOCIATED(vxc_tau)) THEN
     724          40 :             DO ispin = 1, nspins
     725          40 :                CALL vxc_tau(ispin)%release()
     726             :             END DO
     727          20 :             DEALLOCATE (vxc_tau)
     728             :          END IF
     729          96 :          CALL exc_r%release()
     730             :          !
     731             :       END IF
     732             : 
     733          98 :       CALL timestop(handle)
     734             : 
     735          98 :    END SUBROUTINE qs_xc_density
     736             : 
     737             : END MODULE qs_vxc

Generated by: LCOV version 1.15