LCOV - code coverage report
Current view: top level - src - qs_fxc.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 134 238 56.3 %
Date: 2024-11-21 06:45:46 Functions: 4 5 80.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  https://en.wikipedia.org/wiki/Finite_difference_coefficient
      10             : !---------------------------------------------------------------------------------------------------
      11             : !Derivative    Accuracy            4       3       2       1       0       1       2      3       4
      12             : !---------------------------------------------------------------------------------------------------
      13             : !    1             2                                    -1/2       0     1/2
      14             : !                  4                            1/12    -2/3       0     2/3   -1/12
      15             : !                  6                   -1/60    3/20    -3/4       0     3/4   -3/20   1/60
      16             : !                  8           1/280  -4/105     1/5    -4/5       0     4/5    -1/5  4/105  -1/280
      17             : !---------------------------------------------------------------------------------------------------
      18             : !    2             2                                       1      -2       1
      19             : !                  4                           -1/12     4/3    -5/2     4/3   -1/12
      20             : !                  6                    1/90   -3/20     3/2  -49/18     3/2   -3/20   1/90
      21             : !                  8          -1/560   8/315    -1/5     8/5 -205/72     8/5    -1/5  8/315  -1/560
      22             : !---------------------------------------------------------------------------------------------------
      23             : !> \par History
      24             : !>     init 17.03.2020
      25             : !> \author JGH
      26             : ! **************************************************************************************************
      27             : MODULE qs_fxc
      28             : 
      29             :    USE cp_control_types,                ONLY: dft_control_type
      30             :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      31             :                                               section_vals_type
      32             :    USE kinds,                           ONLY: dp
      33             :    USE pw_env_types,                    ONLY: pw_env_get,&
      34             :                                               pw_env_type
      35             :    USE pw_methods,                      ONLY: pw_axpy,&
      36             :                                               pw_scale,&
      37             :                                               pw_zero
      38             :    USE pw_pool_types,                   ONLY: pw_pool_type
      39             :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      40             :                                               pw_r3d_rs_type
      41             :    USE qs_ks_types,                     ONLY: get_ks_env,&
      42             :                                               qs_ks_env_type
      43             :    USE qs_rho_methods,                  ONLY: qs_rho_copy,&
      44             :                                               qs_rho_scale_and_add
      45             :    USE qs_rho_types,                    ONLY: qs_rho_create,&
      46             :                                               qs_rho_get,&
      47             :                                               qs_rho_release,&
      48             :                                               qs_rho_type
      49             :    USE qs_vxc,                          ONLY: qs_vxc_create
      50             :    USE xc,                              ONLY: xc_calc_2nd_deriv,&
      51             :                                               xc_prep_2nd_deriv
      52             :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
      53             :                                               xc_dset_release
      54             :    USE xc_derivatives,                  ONLY: xc_functionals_get_needs
      55             :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      56             :    USE xc_rho_set_types,                ONLY: xc_rho_set_release,&
      57             :                                               xc_rho_set_type
      58             : #include "./base/base_uses.f90"
      59             : 
      60             :    IMPLICIT NONE
      61             : 
      62             :    PRIVATE
      63             : 
      64             :    ! *** Public subroutines ***
      65             :    PUBLIC :: qs_fxc_fdiff, qs_fxc_analytic, qs_fgxc_gdiff, qs_fgxc_create, qs_fgxc_release
      66             : 
      67             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_fxc'
      68             : 
      69             : ! **************************************************************************************************
      70             : 
      71             : CONTAINS
      72             : 
      73             : ! **************************************************************************************************
      74             : !> \brief ...
      75             : !> \param rho0 ...
      76             : !> \param rho1_r ...
      77             : !> \param tau1_r ...
      78             : !> \param xc_section ...
      79             : !> \param auxbas_pw_pool ...
      80             : !> \param is_triplet ...
      81             : !> \param v_xc ...
      82             : !> \param v_xc_tau ...
      83             : ! **************************************************************************************************
      84       16344 :    SUBROUTINE qs_fxc_analytic(rho0, rho1_r, tau1_r, xc_section, auxbas_pw_pool, is_triplet, v_xc, v_xc_tau)
      85             : 
      86             :       TYPE(qs_rho_type), POINTER                         :: rho0
      87             :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho1_r, tau1_r
      88             :       TYPE(section_vals_type), POINTER                   :: xc_section
      89             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
      90             :       LOGICAL, INTENT(IN)                                :: is_triplet
      91             :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_xc, v_xc_tau
      92             : 
      93             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fxc_analytic'
      94             : 
      95             :       INTEGER                                            :: handle, nspins
      96             :       INTEGER, DIMENSION(2, 3)                           :: bo
      97             :       LOGICAL                                            :: lsd
      98             :       REAL(KIND=dp)                                      :: fac
      99       16344 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho0_g, rho1_g
     100       16344 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho0_r, tau0_r
     101             :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     102             :       TYPE(xc_derivative_set_type)                       :: deriv_set
     103             :       TYPE(xc_rho_cflags_type)                           :: needs
     104             :       TYPE(xc_rho_set_type)                              :: rho0_set
     105             : 
     106        8172 :       CALL timeset(routineN, handle)
     107             : 
     108        8172 :       CPASSERT(.NOT. ASSOCIATED(v_xc))
     109        8172 :       CPASSERT(.NOT. ASSOCIATED(v_xc_tau))
     110             : 
     111        8172 :       CALL qs_rho_get(rho0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
     112        8172 :       nspins = SIZE(rho0_r)
     113             : 
     114        8172 :       lsd = (nspins == 2)
     115             :       fac = 0._dp
     116        8172 :       IF (is_triplet .AND. nspins == 1) fac = -1.0_dp
     117             : 
     118        8172 :       NULLIFY (rho1_g)
     119       81720 :       bo = rho1_r(1)%pw_grid%bounds_local
     120        8172 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
     121        8172 :       needs = xc_functionals_get_needs(xc_fun_section, lsd, .TRUE.)
     122             :       ! calculate the arguments needed by the functionals
     123        8172 :       CALL xc_prep_2nd_deriv(deriv_set, rho0_set, rho0_r, auxbas_pw_pool, xc_section=xc_section, tau_r=tau0_r)
     124             :       CALL xc_calc_2nd_deriv(v_xc, v_xc_tau, deriv_set, rho0_set, rho1_r, rho1_g, tau1_r, &
     125        8172 :                              auxbas_pw_pool, xc_section=xc_section, gapw=.FALSE., do_triplet=is_triplet)
     126        8172 :       CALL xc_dset_release(deriv_set)
     127        8172 :       CALL xc_rho_set_release(rho0_set)
     128             : 
     129        8172 :       CALL timestop(handle)
     130             : 
     131      179784 :    END SUBROUTINE qs_fxc_analytic
     132             : 
     133             : ! **************************************************************************************************
     134             : !> \brief ...
     135             : !> \param ks_env ...
     136             : !> \param rho0_struct ...
     137             : !> \param rho1_struct ...
     138             : !> \param xc_section ...
     139             : !> \param accuracy ...
     140             : !> \param is_triplet ...
     141             : !> \param fxc_rho ...
     142             : !> \param fxc_tau ...
     143             : ! **************************************************************************************************
     144        1894 :    SUBROUTINE qs_fxc_fdiff(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, is_triplet, &
     145             :                            fxc_rho, fxc_tau)
     146             : 
     147             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     148             :       TYPE(qs_rho_type), POINTER                         :: rho0_struct, rho1_struct
     149             :       TYPE(section_vals_type), POINTER                   :: xc_section
     150             :       INTEGER, INTENT(IN)                                :: accuracy
     151             :       LOGICAL, INTENT(IN)                                :: is_triplet
     152             :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho, fxc_tau
     153             : 
     154             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fxc_fdiff'
     155             :       REAL(KIND=dp), PARAMETER                           :: epsrho = 5.e-4_dp
     156             : 
     157             :       INTEGER                                            :: handle, ispin, istep, nspins, nstep
     158             :       REAL(KIND=dp)                                      :: alpha, beta, exc, oeps1
     159             :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak
     160             :       TYPE(dft_control_type), POINTER                    :: dft_control
     161             :       TYPE(pw_env_type), POINTER                         :: pw_env
     162             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     163        1894 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_tau_rspace, vxc00
     164             :       TYPE(qs_rho_type), POINTER                         :: rhoin
     165             : 
     166        1894 :       CALL timeset(routineN, handle)
     167             : 
     168        1894 :       CPASSERT(.NOT. ASSOCIATED(fxc_rho))
     169        1894 :       CPASSERT(.NOT. ASSOCIATED(fxc_tau))
     170        1894 :       CPASSERT(ASSOCIATED(rho0_struct))
     171        1894 :       CPASSERT(ASSOCIATED(rho1_struct))
     172             : 
     173        1894 :       ak = 0.0_dp
     174        1894 :       SELECT CASE (accuracy)
     175             :       CASE (:4)
     176           0 :          nstep = 2
     177           0 :          ak(-2:2) = (/1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp/)/12.0_dp
     178             :       CASE (5:7)
     179       15152 :          nstep = 3
     180       15152 :          ak(-3:3) = (/-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp/)/60.0_dp
     181             :       CASE (8:)
     182           0 :          nstep = 4
     183             :          ak(-4:4) = (/1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
     184        1894 :                       224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp/)/280.0_dp
     185             :       END SELECT
     186             : 
     187        1894 :       CALL get_ks_env(ks_env, dft_control=dft_control, pw_env=pw_env)
     188        1894 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     189             : 
     190        1894 :       nspins = dft_control%nspins
     191        1894 :       exc = 0.0_dp
     192             : 
     193       15152 :       DO istep = -nstep, nstep
     194             : 
     195       15152 :          IF (ak(istep) /= 0.0_dp) THEN
     196       11364 :             alpha = 1.0_dp
     197       11364 :             beta = REAL(istep, KIND=dp)*epsrho
     198             :             NULLIFY (rhoin)
     199       11364 :             ALLOCATE (rhoin)
     200       11364 :             CALL qs_rho_create(rhoin)
     201       11364 :             NULLIFY (vxc00, v_tau_rspace)
     202       11364 :             IF (is_triplet) THEN
     203         924 :                CPASSERT(nspins == 1)
     204             :                ! rhoin = (0.5 rho0, 0.5 rho0)
     205         924 :                CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, 2)
     206             :                ! rhoin = (0.5 rho0 + 0.5 rho1, 0.5 rho0)
     207         924 :                CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, 0.5_dp*beta)
     208             :                CALL qs_vxc_create(ks_env=ks_env, rho_struct=rhoin, xc_section=xc_section, &
     209         924 :                                   vxc_rho=vxc00, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE.)
     210         924 :                CALL pw_axpy(vxc00(2), vxc00(1), -1.0_dp)
     211         924 :                IF (ASSOCIATED(v_tau_rspace)) CALL pw_axpy(v_tau_rspace(2), v_tau_rspace(1), -1.0_dp)
     212             :             ELSE
     213       10440 :                CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
     214       10440 :                CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
     215             :                CALL qs_vxc_create(ks_env=ks_env, rho_struct=rhoin, xc_section=xc_section, &
     216       10440 :                                   vxc_rho=vxc00, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE.)
     217             :             END IF
     218       11364 :             CALL qs_rho_release(rhoin)
     219       11364 :             DEALLOCATE (rhoin)
     220       11364 :             IF (.NOT. ASSOCIATED(fxc_rho)) THEN
     221        7876 :                ALLOCATE (fxc_rho(nspins))
     222        4088 :                DO ispin = 1, nspins
     223        2194 :                   CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
     224        4088 :                   CALL pw_zero(fxc_rho(ispin))
     225             :                END DO
     226             :             END IF
     227       24528 :             DO ispin = 1, nspins
     228       24528 :                CALL pw_axpy(vxc00(ispin), fxc_rho(ispin), ak(istep))
     229             :             END DO
     230       25452 :             DO ispin = 1, SIZE(vxc00)
     231       25452 :                CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
     232             :             END DO
     233       11364 :             DEALLOCATE (vxc00)
     234       11364 :             IF (ASSOCIATED(v_tau_rspace)) THEN
     235           0 :                IF (.NOT. ASSOCIATED(fxc_tau)) THEN
     236           0 :                   ALLOCATE (fxc_tau(nspins))
     237           0 :                   DO ispin = 1, nspins
     238           0 :                      CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
     239           0 :                      CALL pw_zero(fxc_tau(ispin))
     240             :                   END DO
     241             :                END IF
     242           0 :                DO ispin = 1, nspins
     243           0 :                   CALL pw_axpy(v_tau_rspace(ispin), fxc_tau(ispin), ak(istep))
     244             :                END DO
     245           0 :                DO ispin = 1, SIZE(v_tau_rspace)
     246           0 :                   CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
     247             :                END DO
     248           0 :                DEALLOCATE (v_tau_rspace)
     249             :             END IF
     250             :          END IF
     251             : 
     252             :       END DO
     253             : 
     254        1894 :       oeps1 = 1.0_dp/epsrho
     255        4088 :       DO ispin = 1, nspins
     256        4088 :          CALL pw_scale(fxc_rho(ispin), oeps1)
     257             :       END DO
     258        1894 :       IF (ASSOCIATED(fxc_tau)) THEN
     259           0 :          DO ispin = 1, nspins
     260           0 :             CALL pw_scale(fxc_tau(ispin), oeps1)
     261             :          END DO
     262             :       END IF
     263             : 
     264        1894 :       CALL timestop(handle)
     265             : 
     266        1894 :    END SUBROUTINE qs_fxc_fdiff
     267             : 
     268             : ! **************************************************************************************************
     269             : !> \brief ...
     270             : !> \param ks_env ...
     271             : !> \param rho0_struct ...
     272             : !> \param rho1_struct ...
     273             : !> \param xc_section ...
     274             : !> \param accuracy ...
     275             : !> \param epsrho ...
     276             : !> \param is_triplet ...
     277             : !> \param fxc_rho ...
     278             : !> \param fxc_tau ...
     279             : !> \param gxc_rho ...
     280             : !> \param gxc_tau ...
     281             : ! **************************************************************************************************
     282         262 :    SUBROUTINE qs_fgxc_gdiff(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, epsrho, &
     283             :                             is_triplet, fxc_rho, fxc_tau, gxc_rho, gxc_tau)
     284             : 
     285             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     286             :       TYPE(qs_rho_type), POINTER                         :: rho0_struct, rho1_struct
     287             :       TYPE(section_vals_type), POINTER                   :: xc_section
     288             :       INTEGER, INTENT(IN)                                :: accuracy
     289             :       REAL(KIND=dp), INTENT(IN)                          :: epsrho
     290             :       LOGICAL, INTENT(IN)                                :: is_triplet
     291             :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho, fxc_tau, gxc_rho, gxc_tau
     292             : 
     293             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fgxc_gdiff'
     294             : 
     295             :       INTEGER                                            :: handle, ispin, istep, nspins, nstep
     296             :       REAL(KIND=dp)                                      :: alpha, beta, exc, oeps1
     297             :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak
     298             :       TYPE(dft_control_type), POINTER                    :: dft_control
     299             :       TYPE(pw_env_type), POINTER                         :: pw_env
     300             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     301         262 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_tau_rspace, vxc00
     302             :       TYPE(qs_rho_type), POINTER                         :: rhoin
     303             : 
     304         262 :       CALL timeset(routineN, handle)
     305             : 
     306         262 :       CPASSERT(.NOT. ASSOCIATED(fxc_rho))
     307         262 :       CPASSERT(.NOT. ASSOCIATED(fxc_tau))
     308         262 :       CPASSERT(.NOT. ASSOCIATED(gxc_rho))
     309         262 :       CPASSERT(.NOT. ASSOCIATED(gxc_tau))
     310         262 :       CPASSERT(ASSOCIATED(rho0_struct))
     311         262 :       CPASSERT(ASSOCIATED(rho1_struct))
     312             : 
     313         262 :       ak = 0.0_dp
     314         262 :       SELECT CASE (accuracy)
     315             :       CASE (:4)
     316           0 :          nstep = 2
     317           0 :          ak(-2:2) = (/1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp/)/12.0_dp
     318             :       CASE (5:7)
     319        2096 :          nstep = 3
     320        2096 :          ak(-3:3) = (/-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp/)/60.0_dp
     321             :       CASE (8:)
     322           0 :          nstep = 4
     323             :          ak(-4:4) = (/1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
     324         262 :                       224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp/)/280.0_dp
     325             :       END SELECT
     326             : 
     327         262 :       CALL get_ks_env(ks_env, dft_control=dft_control, pw_env=pw_env)
     328         262 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     329             : 
     330         262 :       nspins = dft_control%nspins
     331         262 :       exc = 0.0_dp
     332             : 
     333             :       CALL qs_fxc_fdiff(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, is_triplet, &
     334         262 :                         fxc_rho, fxc_tau)
     335             : 
     336        2096 :       DO istep = -nstep, nstep
     337             : 
     338        2096 :          IF (ak(istep) /= 0.0_dp) THEN
     339        1572 :             alpha = 1.0_dp
     340        1572 :             beta = REAL(istep, KIND=dp)*epsrho
     341             :             NULLIFY (rhoin)
     342        1572 :             ALLOCATE (rhoin)
     343        1572 :             CALL qs_rho_create(rhoin)
     344        1572 :             NULLIFY (vxc00, v_tau_rspace)
     345        1572 :             CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
     346        1572 :             CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
     347             :             CALL qs_fxc_fdiff(ks_env=ks_env, rho0_struct=rhoin, rho1_struct=rho1_struct, &
     348             :                               xc_section=xc_section, accuracy=accuracy, is_triplet=is_triplet, &
     349        1572 :                               fxc_rho=vxc00, fxc_tau=v_tau_rspace)
     350        1572 :             CALL qs_rho_release(rhoin)
     351        1572 :             DEALLOCATE (rhoin)
     352        1572 :             IF (.NOT. ASSOCIATED(gxc_rho)) THEN
     353        1084 :                ALLOCATE (gxc_rho(nspins))
     354         560 :                DO ispin = 1, nspins
     355         298 :                   CALL auxbas_pw_pool%create_pw(gxc_rho(ispin))
     356         560 :                   CALL pw_zero(gxc_rho(ispin))
     357             :                END DO
     358             :             END IF
     359        3360 :             DO ispin = 1, nspins
     360        3360 :                CALL pw_axpy(vxc00(ispin), gxc_rho(ispin), ak(istep))
     361             :             END DO
     362        3360 :             DO ispin = 1, SIZE(vxc00)
     363        3360 :                CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
     364             :             END DO
     365        1572 :             DEALLOCATE (vxc00)
     366        1572 :             IF (ASSOCIATED(v_tau_rspace)) THEN
     367           0 :                IF (.NOT. ASSOCIATED(gxc_tau)) THEN
     368           0 :                   ALLOCATE (gxc_tau(nspins))
     369           0 :                   DO ispin = 1, nspins
     370           0 :                      CALL auxbas_pw_pool%create_pw(gxc_tau(ispin))
     371           0 :                      CALL pw_zero(gxc_tau(ispin))
     372             :                   END DO
     373             :                END IF
     374           0 :                DO ispin = 1, nspins
     375           0 :                   CALL pw_axpy(v_tau_rspace(ispin), gxc_tau(ispin), ak(istep))
     376             :                END DO
     377           0 :                DO ispin = 1, SIZE(v_tau_rspace)
     378           0 :                   CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
     379             :                END DO
     380           0 :                DEALLOCATE (v_tau_rspace)
     381             :             END IF
     382             :          END IF
     383             : 
     384             :       END DO
     385             : 
     386         262 :       oeps1 = 1.0_dp/epsrho
     387         560 :       DO ispin = 1, nspins
     388         560 :          CALL pw_scale(gxc_rho(ispin), oeps1)
     389             :       END DO
     390         262 :       IF (ASSOCIATED(gxc_tau)) THEN
     391           0 :          DO ispin = 1, nspins
     392           0 :             CALL pw_scale(gxc_tau(ispin), oeps1)
     393             :          END DO
     394             :       END IF
     395             : 
     396         262 :       CALL timestop(handle)
     397             : 
     398         262 :    END SUBROUTINE qs_fgxc_gdiff
     399             : 
     400             : ! **************************************************************************************************
     401             : !> \brief ...
     402             : !> \param ks_env ...
     403             : !> \param rho0_struct ...
     404             : !> \param rho1_struct ...
     405             : !> \param xc_section ...
     406             : !> \param accuracy ...
     407             : !> \param is_triplet ...
     408             : !> \param fxc_rho ...
     409             : !> \param fxc_tau ...
     410             : !> \param gxc_rho ...
     411             : !> \param gxc_tau ...
     412             : ! **************************************************************************************************
     413           0 :    SUBROUTINE qs_fgxc_create(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, is_triplet, &
     414             :                              fxc_rho, fxc_tau, gxc_rho, gxc_tau)
     415             : 
     416             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     417             :       TYPE(qs_rho_type), POINTER                         :: rho0_struct, rho1_struct
     418             :       TYPE(section_vals_type), POINTER                   :: xc_section
     419             :       INTEGER, INTENT(IN)                                :: accuracy
     420             :       LOGICAL, INTENT(IN)                                :: is_triplet
     421             :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho, fxc_tau, gxc_rho, gxc_tau
     422             : 
     423             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fgxc_create'
     424             :       REAL(KIND=dp), PARAMETER                           :: epsrho = 5.e-4_dp
     425             : 
     426             :       INTEGER                                            :: handle, ispin, istep, nspins, nstep
     427             :       REAL(KIND=dp)                                      :: alpha, beta, exc, oeps1, oeps2
     428             :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak, bl
     429             :       TYPE(dft_control_type), POINTER                    :: dft_control
     430             :       TYPE(pw_env_type), POINTER                         :: pw_env
     431             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     432           0 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_tau_rspace, vxc00
     433             :       TYPE(qs_rho_type), POINTER                         :: rhoin
     434             : 
     435           0 :       CALL timeset(routineN, handle)
     436             : 
     437           0 :       CPASSERT(.NOT. ASSOCIATED(fxc_rho))
     438           0 :       CPASSERT(.NOT. ASSOCIATED(fxc_tau))
     439           0 :       CPASSERT(.NOT. ASSOCIATED(gxc_rho))
     440           0 :       CPASSERT(.NOT. ASSOCIATED(gxc_tau))
     441           0 :       CPASSERT(ASSOCIATED(rho0_struct))
     442           0 :       CPASSERT(ASSOCIATED(rho1_struct))
     443             : 
     444           0 :       ak = 0.0_dp
     445           0 :       bl = 0.0_dp
     446           0 :       SELECT CASE (accuracy)
     447             :       CASE (:4)
     448           0 :          nstep = 2
     449           0 :          ak(-2:2) = (/1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp/)/12.0_dp
     450           0 :          bl(-2:2) = (/-1.0_dp, 16.0_dp, -30.0_dp, 16.0_dp, -1.0_dp/)/12.0_dp
     451             :       CASE (5:7)
     452           0 :          nstep = 3
     453           0 :          ak(-3:3) = (/-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp/)/60.0_dp
     454           0 :          bl(-3:3) = (/2.0_dp, -27.0_dp, 270.0_dp, -490.0_dp, 270.0_dp, -27.0_dp, 2.0_dp/)/180.0_dp
     455             :       CASE (8:)
     456           0 :          nstep = 4
     457             :          ak(-4:4) = (/1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
     458           0 :                       224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp/)/280.0_dp
     459             :          bl(-4:4) = (/-1.0_dp, 128.0_dp/9.0_dp, -112.0_dp, 896.0_dp, -14350.0_dp/9.0_dp, &
     460           0 :                       896.0_dp, -112.0_dp, 128.0_dp/9.0_dp, -1.0_dp/)/560.0_dp
     461             :       END SELECT
     462             : 
     463           0 :       CALL get_ks_env(ks_env, dft_control=dft_control, pw_env=pw_env)
     464           0 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     465             : 
     466           0 :       nspins = dft_control%nspins
     467           0 :       exc = 0.0_dp
     468             : 
     469           0 :       DO istep = -nstep, nstep
     470             : 
     471           0 :          alpha = 1.0_dp
     472           0 :          beta = REAL(istep, KIND=dp)*epsrho
     473             :          NULLIFY (rhoin)
     474           0 :          ALLOCATE (rhoin)
     475           0 :          CALL qs_rho_create(rhoin)
     476           0 :          NULLIFY (vxc00, v_tau_rspace)
     477           0 :          IF (is_triplet) THEN
     478           0 :             CPASSERT(nspins == 1)
     479             :             ! rhoin = (0.5 rho0, 0.5 rho0)
     480           0 :             CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, 2)
     481             :             ! rhoin = (0.5 rho0 + 0.5 rho1, 0.5 rho0)
     482           0 :             CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, 0.5_dp*beta)
     483             :             CALL qs_vxc_create(ks_env=ks_env, rho_struct=rhoin, xc_section=xc_section, &
     484           0 :                                vxc_rho=vxc00, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE.)
     485           0 :             CALL pw_axpy(vxc00(2), vxc00(1), -1.0_dp)
     486             :          ELSE
     487           0 :             CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
     488           0 :             CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
     489             :             CALL qs_vxc_create(ks_env=ks_env, rho_struct=rhoin, xc_section=xc_section, &
     490           0 :                                vxc_rho=vxc00, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE.)
     491             :          END IF
     492           0 :          CALL qs_rho_release(rhoin)
     493           0 :          DEALLOCATE (rhoin)
     494           0 :          IF (.NOT. ASSOCIATED(fxc_rho)) THEN
     495           0 :             ALLOCATE (fxc_rho(nspins))
     496           0 :             DO ispin = 1, nspins
     497           0 :                CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
     498           0 :                CALL pw_zero(fxc_rho(ispin))
     499             :             END DO
     500             :          END IF
     501           0 :          IF (.NOT. ASSOCIATED(gxc_rho)) THEN
     502           0 :             ALLOCATE (gxc_rho(nspins))
     503           0 :             DO ispin = 1, nspins
     504           0 :                CALL auxbas_pw_pool%create_pw(gxc_rho(ispin))
     505           0 :                CALL pw_zero(gxc_rho(ispin))
     506             :             END DO
     507             :          END IF
     508           0 :          CPASSERT(.NOT. ASSOCIATED(v_tau_rspace))
     509           0 :          DO ispin = 1, nspins
     510           0 :             IF (ak(istep) /= 0.0_dp) THEN
     511           0 :                CALL pw_axpy(vxc00(ispin), fxc_rho(ispin), ak(istep))
     512             :             END IF
     513           0 :             IF (bl(istep) /= 0.0_dp) THEN
     514           0 :                CALL pw_axpy(vxc00(ispin), gxc_rho(ispin), bl(istep))
     515             :             END IF
     516             :          END DO
     517           0 :          DO ispin = 1, SIZE(vxc00)
     518           0 :             CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
     519             :          END DO
     520           0 :          DEALLOCATE (vxc00)
     521             : 
     522             :       END DO
     523             : 
     524           0 :       oeps1 = 1.0_dp/epsrho
     525           0 :       oeps2 = 1.0_dp/(epsrho**2)
     526           0 :       DO ispin = 1, nspins
     527           0 :          CALL pw_scale(fxc_rho(ispin), oeps1)
     528           0 :          CALL pw_scale(gxc_rho(ispin), oeps2)
     529             :       END DO
     530             : 
     531           0 :       CALL timestop(handle)
     532             : 
     533           0 :    END SUBROUTINE qs_fgxc_create
     534             : 
     535             : ! **************************************************************************************************
     536             : !> \brief ...
     537             : !> \param ks_env ...
     538             : !> \param fxc_rho ...
     539             : !> \param fxc_tau ...
     540             : !> \param gxc_rho ...
     541             : !> \param gxc_tau ...
     542             : ! **************************************************************************************************
     543         262 :    SUBROUTINE qs_fgxc_release(ks_env, fxc_rho, fxc_tau, gxc_rho, gxc_tau)
     544             : 
     545             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     546             :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho, fxc_tau, gxc_rho, gxc_tau
     547             : 
     548             :       INTEGER                                            :: ispin
     549             :       TYPE(pw_env_type), POINTER                         :: pw_env
     550             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     551             : 
     552         262 :       CALL get_ks_env(ks_env, pw_env=pw_env)
     553         262 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     554             : 
     555         262 :       IF (ASSOCIATED(fxc_rho)) THEN
     556         560 :          DO ispin = 1, SIZE(fxc_rho)
     557         560 :             CALL auxbas_pw_pool%give_back_pw(fxc_rho(ispin))
     558             :          END DO
     559         262 :          DEALLOCATE (fxc_rho)
     560             :       END IF
     561         262 :       IF (ASSOCIATED(fxc_tau)) THEN
     562           0 :          DO ispin = 1, SIZE(fxc_tau)
     563           0 :             CALL auxbas_pw_pool%give_back_pw(fxc_tau(ispin))
     564             :          END DO
     565           0 :          DEALLOCATE (fxc_tau)
     566             :       END IF
     567         262 :       IF (ASSOCIATED(gxc_rho)) THEN
     568         560 :          DO ispin = 1, SIZE(gxc_rho)
     569         560 :             CALL auxbas_pw_pool%give_back_pw(gxc_rho(ispin))
     570             :          END DO
     571         262 :          DEALLOCATE (gxc_rho)
     572             :       END IF
     573         262 :       IF (ASSOCIATED(gxc_tau)) THEN
     574           0 :          DO ispin = 1, SIZE(gxc_tau)
     575           0 :             CALL auxbas_pw_pool%give_back_pw(gxc_tau(ispin))
     576             :          END DO
     577           0 :          DEALLOCATE (gxc_tau)
     578             :       END IF
     579             : 
     580         262 :    END SUBROUTINE qs_fgxc_release
     581             : 
     582             : END MODULE qs_fxc

Generated by: LCOV version 1.15