LCOV - code coverage report
Current view: top level - src/xc - xc_xbr_pbe_lda_hole_t_c_lr.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:123285f) Lines: 95.0 % 240 228
Test Date: 2026-11-04 00:58:17 Functions: 100.0 % 6 6

            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 This functional is a combination of three different exchange hole
      10              : !>        models. The ingredients are:
      11              : !>
      12              : !>          1. Becke Roussel exchange hole
      13              : !>          2. PBE exchange hole
      14              : !>          3. LDA exchange hole
      15              : !>
      16              : !>        The full functionals is given as follows
      17              : !>
      18              : !>        Fx    = eps_lr_lda/eps_lr_br
      19              : !>        Fcorr = alpha/( exp( (Fx-mu)/N ) + 1)
      20              : !>        rhox  = Fcorr * eps_lr_pbe + (1-Fcorr)*eps_lr_br
      21              : !>        eps   = int_{R}^{\infty} rhox*s*ds
      22              : !>
      23              : !>        with alpha, mu and N fitting parameters
      24              : !> \par History
      25              : !>      01.2009 created [mguidon]
      26              : !> \author mguidon
      27              : ! **************************************************************************************************
      28              : 
      29              : MODULE xc_xbr_pbe_lda_hole_t_c_lr
      30              : 
      31              :    USE input_section_types,             ONLY: section_vals_type,&
      32              :                                               section_vals_val_get
      33              :    USE kinds,                           ONLY: dp
      34              :    USE mathconstants,                   ONLY: pi
      35              :    USE xc_derivative_desc,              ONLY: &
      36              :         deriv_laplace_rho, deriv_laplace_rhoa, deriv_laplace_rhob, deriv_norm_drho, &
      37              :         deriv_norm_drhoa, deriv_norm_drhob, deriv_rho, deriv_rhoa, deriv_rhob, deriv_tau, &
      38              :         deriv_tau_a, deriv_tau_b
      39              :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
      40              :                                               xc_dset_get_derivative
      41              :    USE xc_derivative_types,             ONLY: xc_derivative_get,&
      42              :                                               xc_derivative_type
      43              :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      44              :    USE xc_rho_set_types,                ONLY: xc_rho_set_get,&
      45              :                                               xc_rho_set_type
      46              :    USE xc_xbecke_roussel,               ONLY: x_br_lsd_y_gt_0,&
      47              :                                               x_br_lsd_y_gt_0_cutoff,&
      48              :                                               x_br_lsd_y_lte_0,&
      49              :                                               x_br_lsd_y_lte_0_cutoff
      50              :    USE xc_xlda_hole_t_c_lr,             ONLY: xlda_hole_t_c_lr_lda_calc_0
      51              :    USE xc_xpbe_hole_t_c_lr,             ONLY: xpbe_hole_t_c_lr_lda_calc_1,&
      52              :                                               xpbe_hole_t_c_lr_lda_calc_2
      53              : #include "../base/base_uses.f90"
      54              : 
      55              :    IMPLICIT NONE
      56              :    PRIVATE
      57              : 
      58              :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
      59              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_xbr_pbe_lda_hole_t_c_lr'
      60              : 
      61              :    REAL(dp), PARAMETER, PRIVATE  :: br_a1 = 1.5255251812009530_dp, &
      62              :                                     br_a2 = 0.4576575543602858_dp, &
      63              :                                     br_a3 = 0.4292036732051034_dp, &
      64              :                                     br_c0 = 0.7566445420735584_dp, &
      65              :                                     br_c1 = -2.6363977871370960_dp, &
      66              :                                     br_c2 = 5.4745159964232880_dp, &
      67              :                                     br_c3 = -12.657308127108290_dp, &
      68              :                                     br_c4 = 4.1250584725121360_dp, &
      69              :                                     br_c5 = -30.425133957163840_dp, &
      70              :                                     br_b0 = 0.4771976183772063_dp, &
      71              :                                     br_b1 = -1.7799813494556270_dp, &
      72              :                                     br_b2 = 3.8433841862302150_dp, &
      73              :                                     br_b3 = -9.5912050880518490_dp, &
      74              :                                     br_b4 = 2.1730180285916720_dp, &
      75              :                                     br_b5 = -30.425133851603660_dp, &
      76              :                                     br_d0 = 0.00004435009886795587_dp, &
      77              :                                     br_d1 = 0.58128653604457910_dp, &
      78              :                                     br_d2 = 66.742764515940610_dp, &
      79              :                                     br_d3 = 434.26780897229770_dp, &
      80              :                                     br_d4 = 824.7765766052239000_dp, &
      81              :                                     br_d5 = 1657.9652731582120_dp, &
      82              :                                     br_e0 = 0.00003347285060926091_dp, &
      83              :                                     br_e1 = 0.47917931023971350_dp, &
      84              :                                     br_e2 = 62.392268338574240_dp, &
      85              :                                     br_e3 = 463.14816427938120_dp, &
      86              :                                     br_e4 = 785.2360350104029000_dp, &
      87              :                                     br_e5 = 1657.962968223273000000_dp, &
      88              :                                     br_BB = 2.085749716493756_dp
      89              : 
      90              :    REAL(dp), PARAMETER, PRIVATE  :: smax = 8.572844_dp, &
      91              :                                     scutoff = 8.3_dp, &
      92              :                                     sconst = 18.79622316_dp, &
      93              :                                     gcutoff = 0.08_dp
      94              : 
      95              :    REAL(dp), PARAMETER, PRIVATE  :: alpha = 0.3956891_dp, &
      96              :                                     N = -0.0009800242_dp, &
      97              :                                     mu = 0.00118684_dp
      98              : 
      99              :    PUBLIC :: xbr_pbe_lda_hole_tc_lr_lda_info, &
     100              :              xbr_pbe_lda_hole_tc_lr_lsd_info, &
     101              :              xbr_pbe_lda_hole_tc_lr_lda_eval, &
     102              :              xbr_pbe_lda_hole_tc_lr_lsd_eval
     103              : CONTAINS
     104              : 
     105              : ! **************************************************************************************************
     106              : !> \brief return various information on the functional
     107              : !> \param reference string with the reference of the actual functional
     108              : !> \param shortform string with the shortform of the functional name
     109              : !> \param needs the components needed by this functional are set to
     110              : !>        true (does not set the unneeded components to false)
     111              : !> \param max_deriv ...
     112              : !> \author mguidon (01.2009)
     113              : ! **************************************************************************************************
     114          205 :    SUBROUTINE xbr_pbe_lda_hole_tc_lr_lda_info(reference, shortform, needs, max_deriv)
     115              :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL            :: reference, shortform
     116              :       TYPE(xc_rho_cflags_type), INTENT(inout), OPTIONAL  :: needs
     117              :       INTEGER, INTENT(out), OPTIONAL                     :: max_deriv
     118              : 
     119          205 :       IF (PRESENT(reference)) THEN
     120            1 :          reference = "{LDA version}"
     121              :       END IF
     122          205 :       IF (PRESENT(shortform)) THEN
     123            1 :          shortform = "{LDA}"
     124              :       END IF
     125              : 
     126          205 :       IF (PRESENT(needs)) THEN
     127          204 :          needs%rho = .TRUE.
     128          204 :          needs%norm_drho = .TRUE.
     129          204 :          needs%tau = .TRUE.
     130          204 :          needs%laplace_rho = .TRUE.
     131              :       END IF
     132              : 
     133          205 :       IF (PRESENT(max_deriv)) max_deriv = 1
     134              : 
     135          205 :    END SUBROUTINE xbr_pbe_lda_hole_tc_lr_lda_info
     136              : 
     137              : ! **************************************************************************************************
     138              : !> \brief return various information on the functional
     139              : !> \param reference string with the reference of the actual functional
     140              : !> \param shortform string with the shortform of the functional name
     141              : !> \param needs the components needed by this functional are set to
     142              : !>        true (does not set the unneeded components to false)
     143              : !> \param max_deriv ...
     144              : !> \author mguidon (01.2009)
     145              : ! **************************************************************************************************
     146           63 :    SUBROUTINE xbr_pbe_lda_hole_tc_lr_lsd_info(reference, shortform, needs, max_deriv)
     147              :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL            :: reference, shortform
     148              :       TYPE(xc_rho_cflags_type), INTENT(inout), OPTIONAL  :: needs
     149              :       INTEGER, INTENT(out), OPTIONAL                     :: max_deriv
     150              : 
     151           63 :       IF (PRESENT(reference)) THEN
     152            1 :          reference = "{LDA version}"
     153              :       END IF
     154           63 :       IF (PRESENT(shortform)) THEN
     155            1 :          shortform = "{LDA}"
     156              :       END IF
     157              : 
     158           63 :       IF (PRESENT(needs)) THEN
     159           62 :          needs%rho_spin = .TRUE.
     160           62 :          needs%norm_drho_spin = .TRUE.
     161           62 :          needs%tau_spin = .TRUE.
     162           62 :          needs%laplace_rho_spin = .TRUE.
     163              :       END IF
     164           63 :       IF (PRESENT(max_deriv)) max_deriv = 1
     165              : 
     166           63 :    END SUBROUTINE xbr_pbe_lda_hole_tc_lr_lsd_info
     167              : 
     168              : ! **************************************************************************************************
     169              : !> \brief Intermediate routine that gets grids, derivatives and some params
     170              : !> \param rho_set the density where you want to evaluate the functional
     171              : !> \param deriv_set place where to store the functional derivatives (they are
     172              : !>        added to the derivatives)
     173              : !> \param grad_deriv maximum degree of the derivative that should be evaluated
     174              : !> \param params parameters for functional
     175              : !> \author mguidon (01.2009)
     176              : ! **************************************************************************************************
     177         1000 :    SUBROUTINE xbr_pbe_lda_hole_tc_lr_lda_eval(rho_set, deriv_set, grad_deriv, params)
     178              :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set
     179              :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
     180              :       INTEGER, INTENT(in)                                :: grad_deriv
     181              :       TYPE(section_vals_type), POINTER                   :: params
     182              : 
     183              :       CHARACTER(len=*), PARAMETER :: routineN = 'xbr_pbe_lda_hole_tc_lr_lda_eval'
     184              : 
     185              :       INTEGER                                            :: handle, npoints
     186              :       INTEGER, DIMENSION(2, 3)                           :: bo
     187              :       REAL(dp)                                           :: gamma, R, sx
     188              :       REAL(kind=dp)                                      :: epsilon_rho
     189              :       REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :, :), &
     190          200 :          POINTER                                         :: dummy, e_0, e_laplace_rho, e_ndrho, &
     191          200 :                                                             e_rho, e_tau, laplace_rho, norm_drho, &
     192          200 :                                                             rho, tau
     193              :       TYPE(xc_derivative_type), POINTER                  :: deriv
     194              : 
     195          200 :       CALL timeset(routineN, handle)
     196              : 
     197              :       CALL xc_rho_set_get(rho_set, rho=rho, norm_drho=norm_drho, &
     198              :                           tau=tau, laplace_rho=laplace_rho, local_bounds=bo, &
     199          200 :                           rho_cutoff=epsilon_rho)
     200          200 :       npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
     201              : 
     202          200 :       dummy => rho
     203              : 
     204          200 :       e_0 => dummy
     205          200 :       e_rho => dummy
     206          200 :       e_ndrho => dummy
     207          200 :       e_tau => dummy
     208          200 :       e_laplace_rho => dummy
     209              : 
     210              :       deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
     211          200 :                                       allocate_deriv=.TRUE.)
     212          200 :       CALL xc_derivative_get(deriv, deriv_data=e_0)
     213          200 :       IF (grad_deriv >= 1) THEN
     214              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_rho], &
     215          102 :                                          allocate_deriv=.TRUE.)
     216          102 :          CALL xc_derivative_get(deriv, deriv_data=e_rho)
     217              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
     218          102 :                                          allocate_deriv=.TRUE.)
     219          102 :          CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
     220              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_tau], &
     221          102 :                                          allocate_deriv=.TRUE.)
     222          102 :          CALL xc_derivative_get(deriv, deriv_data=e_tau)
     223              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho], &
     224          102 :                                          allocate_deriv=.TRUE.)
     225          102 :          CALL xc_derivative_get(deriv, deriv_data=e_laplace_rho)
     226              :       END IF
     227          200 :       IF (grad_deriv > 1) THEN
     228            0 :          CPABORT("derivatives bigger than 1 not implemented")
     229              :       END IF
     230              : 
     231          200 :       CALL section_vals_val_get(params, "scale_x", r_val=sx)
     232          200 :       CALL section_vals_val_get(params, "CUTOFF_RADIUS", r_val=R)
     233          200 :       CALL section_vals_val_get(params, "GAMMA", r_val=gamma)
     234              : 
     235          200 :       IF (R == 0.0_dp) THEN
     236            0 :          CPABORT("Cutoff_Radius 0.0 not implemented")
     237              :       END IF
     238              : 
     239              : !$OMP     PARALLEL DEFAULT(NONE) &
     240              : !$OMP              SHARED(rho, norm_drho, laplace_rho, tau, e_0, e_rho) &
     241              : !$OMP              SHARED(e_ndrho, e_tau, e_laplace_rho, grad_deriv) &
     242              : !$OMP              SHARED(npoints, epsilon_rho) &
     243          200 : !$OMP              SHARED(sx, r, gamma)
     244              : 
     245              :       CALL xbr_pbe_lda_hole_tc_lr_lda_calc(rho=rho, norm_drho=norm_drho, &
     246              :                                            laplace_rho=laplace_rho, tau=tau, e_0=e_0, e_rho=e_rho, e_ndrho=e_ndrho, &
     247              :                                            e_tau=e_tau, e_laplace_rho=e_laplace_rho, grad_deriv=grad_deriv, &
     248              :                                            npoints=npoints, epsilon_rho=epsilon_rho, sx=sx, R=R, gamma=gamma)
     249              : 
     250              : !$OMP     END PARALLEL
     251              : 
     252          200 :       CALL timestop(handle)
     253          200 :    END SUBROUTINE xbr_pbe_lda_hole_tc_lr_lda_eval
     254              : 
     255              : ! **************************************************************************************************
     256              : !> \brief Low level routine that calls the three involved holes and puts them
     257              : !>        together
     258              : !> \param rho values on the grid
     259              : !> \param norm_drho values on the grid
     260              : !> \param laplace_rho values on the grid
     261              : !> \param tau values on the grid
     262              : !> \param e_0 derivatives on the grid
     263              : !> \param e_rho derivatives on the grid
     264              : !> \param e_ndrho derivatives on the grid
     265              : !> \param e_tau derivatives on the grid
     266              : !> \param e_laplace_rho derivatives on the grid
     267              : !> \param grad_deriv maximum degree of the derivative that should be evaluated
     268              : !> \param npoints number of gridpoints
     269              : !> \param epsilon_rho cutoffs
     270              : !> \param sx parameters for  functional
     271              : !> \param R parameters for  functional
     272              : !> \param gamma parameters for  functional
     273              : !> \author mguidon (01.2009)
     274              : ! **************************************************************************************************
     275          200 :    SUBROUTINE xbr_pbe_lda_hole_tc_lr_lda_calc(rho, norm_drho, laplace_rho, tau, e_0, e_rho, &
     276          200 :                                               e_ndrho, e_tau, e_laplace_rho, grad_deriv, npoints, &
     277              :                                               epsilon_rho, sx, R, gamma)
     278              : 
     279              :       INTEGER, INTENT(in)                                :: npoints, grad_deriv
     280              :       REAL(kind=dp), DIMENSION(1:npoints), INTENT(inout) :: e_laplace_rho, e_tau, e_ndrho, e_rho, e_0
     281              :       REAL(kind=dp), DIMENSION(1:npoints), INTENT(in)    :: tau, laplace_rho, norm_drho, rho
     282              :       REAL(kind=dp), INTENT(in)                          :: epsilon_rho, sx, R, gamma
     283              : 
     284              :       INTEGER                                            :: ip
     285              :       REAL(dp) :: dFermi_dlaplace_rho, dFermi_dndrho, dFermi_drho, dFermi_dtau, e_0_br, e_0_lda, &
     286              :          e_0_pbe, e_laplace_rho_br, e_ndrho_br, e_ndrho_pbe, e_rho_br, e_rho_lda, e_rho_pbe, &
     287              :          e_tau_br, Fermi, Fx, my_laplace_rho, my_ndrho, my_rho, my_tau, ss, ss2, sscale, t1, t15, &
     288              :          t16, t2, t3, t4, t5, t6, t7, t8, t9, yval
     289              : 
     290              : !$OMP     DO
     291              : 
     292              :       DO ip = 1, npoints
     293      6400000 :          my_rho = 0.5_dp*MAX(rho(ip), 0.0_dp)
     294      6400000 :          IF (my_rho > epsilon_rho) THEN
     295      6400000 :             my_ndrho = 0.5_dp*MAX(norm_drho(ip), EPSILON(0.0_dp)*1.e4_dp)
     296      6400000 :             my_tau = 0.5_dp*MAX(EPSILON(0.0_dp)*1.e4_dp, tau(ip))
     297      6400000 :             my_laplace_rho = 0.5_dp*laplace_rho(ip)
     298              : 
     299              :             ! ** We calculate first the Becke-Roussel part, saving everything in local variables
     300      6400000 :             t1 = pi**(0.1e1_dp/0.3e1_dp)
     301      6400000 :             t2 = t1**2
     302      6400000 :             t3 = my_rho**(0.1e1_dp/0.3e1_dp)
     303      6400000 :             t4 = t3**2
     304      6400000 :             t5 = t4*my_rho
     305      6400000 :             t8 = my_ndrho**2
     306      6400000 :             t9 = 0.1e1_dp/my_rho
     307      6400000 :             t15 = my_laplace_rho/0.6e1_dp - gamma*(2.0_dp*my_tau - t8*t9/0.4e1_dp)/0.3e1_dp
     308      6400000 :             t16 = 0.1e1_dp/t15
     309      6400000 :             yval = 0.2e1_dp/0.3e1_dp*t2*t5*t16
     310              : 
     311      6400000 :             e_0_br = 0.0_dp
     312      6400000 :             e_rho_br = 0.0_dp
     313      6400000 :             e_ndrho_br = 0.0_dp
     314      6400000 :             e_tau_br = 0.0_dp
     315      6400000 :             e_laplace_rho_br = 0.0_dp
     316              : 
     317      6400000 :             IF (R == 0.0_dp) THEN
     318            0 :                IF (yval <= 0.0_dp) THEN
     319              :                   CALL x_br_lsd_y_lte_0(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
     320              :                                         e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
     321            0 :                                         sx, gamma, grad_deriv)
     322              :                   ! VERY UGLY HACK e_0 has to multiplied by the factor 2
     323            0 :                   e_0_br = 2.0_dp*e_0_br
     324              :                ELSE
     325              :                   CALL x_br_lsd_y_gt_0(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
     326              :                                        e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
     327            0 :                                        sx, gamma, grad_deriv)
     328              :                   ! VERY UGLY HACK e_0 has to multiplied by the factor 2
     329            0 :                   e_0_br = 2.0_dp*e_0_br
     330              :                END IF
     331              :             ELSE
     332      6400000 :                IF (yval <= 0.0_dp) THEN
     333              :                   CALL x_br_lsd_y_lte_0_cutoff(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
     334              :                                                e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
     335       143257 :                                                sx, R, gamma, grad_deriv)
     336              :                   ! VERY UGLY HACK e_0 has to multiplied by the factor 2
     337       143257 :                   e_0_br = 2.0_dp*e_0_br
     338              :                ELSE
     339              :                   CALL x_br_lsd_y_gt_0_cutoff(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
     340              :                                               e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
     341      6256743 :                                               sx, R, gamma, grad_deriv)
     342              :                   ! VERY UGLY HACK e_0 has to multiplied by the factor 2
     343      6256743 :                   e_0_br = 2.0_dp*e_0_br
     344              :                END IF
     345              :             END IF
     346              : 
     347              :             ! ** Now we calculate the pbe cutoff part
     348              :             ! ** Attention we need to scale rho, ndrho first
     349      6400000 :             my_rho = my_rho*2.0_dp
     350      6400000 :             my_ndrho = my_ndrho*2.0_dp
     351              : 
     352              :             ! ** Do some precalculation in order to catch the correct branch afterwards
     353      6400000 :             sscale = 1.0_dp
     354      6400000 :             t1 = pi**2
     355      6400000 :             t2 = t1*my_rho
     356      6400000 :             t3 = t2**(0.1e1_dp/0.3e1_dp)
     357      6400000 :             t4 = 0.1e1_dp/t3
     358      6400000 :             t6 = my_ndrho*t4
     359      6400000 :             t7 = 0.1e1_dp/my_rho
     360      6400000 :             t8 = t7*sscale
     361      6400000 :             ss = 0.3466806371753173524216762e0_dp*t6*t8
     362      6400000 :             IF (ss > scutoff) THEN
     363      3573347 :                ss2 = ss*ss
     364      3573347 :                sscale = (smax*ss2 - sconst)/(ss2*ss)
     365              :             END IF
     366      6400000 :             e_0_pbe = 0.0_dp
     367      6400000 :             e_rho_pbe = 0.0_dp
     368      6400000 :             e_ndrho_pbe = 0.0_dp
     369      6400000 :             IF (ss*sscale > gcutoff) THEN
     370              :                CALL xpbe_hole_t_c_lr_lda_calc_1(e_0_pbe, e_rho_pbe, e_ndrho_pbe, &
     371              :                                                 my_rho, &
     372      6399421 :                                                 my_ndrho, sscale, sx, R, grad_deriv)
     373              :             ELSE
     374              :                CALL xpbe_hole_t_c_lr_lda_calc_2(e_0_pbe, e_rho_pbe, e_ndrho_pbe, &
     375              :                                                 my_rho, &
     376          579 :                                                 my_ndrho, sscale, sx, R, grad_deriv)
     377              :             END IF
     378              : 
     379              :             ! ** Finally we get the LDA part
     380              : 
     381      6400000 :             e_0_lda = 0.0_dp
     382      6400000 :             e_rho_lda = 0.0_dp
     383              :             CALL xlda_hole_t_c_lr_lda_calc_0(grad_deriv, my_rho, e_0_lda, e_rho_lda, &
     384      6400000 :                                              sx, R)
     385              : 
     386      6400000 :             Fx = e_0_br/e_0_lda
     387              : 
     388      6400000 :             Fermi = alpha/(EXP((Fx - mu)/N) + 1.0_dp)
     389              : 
     390      6400000 :             e_0(ip) = e_0(ip) + (Fermi*e_0_pbe + (1.0_dp - Fermi)*e_0_br)*sx
     391              : 
     392      6400000 :             IF (grad_deriv >= 1) THEN
     393              : 
     394      3264000 :                dFermi_drho = -Fermi**2/alpha/N*(e_rho_br/e_0_lda - e_0_br*e_rho_lda/e_0_lda**2)*EXP((Fx - mu)/N)
     395      3264000 :                dFermi_dndrho = -Fermi**2/alpha/N*(e_ndrho_br/e_0_lda)*EXP((Fx - mu)/N)
     396      3264000 :                dFermi_dtau = -Fermi**2/alpha/N*(e_tau_br/e_0_lda)*EXP((Fx - mu)/N)
     397      3264000 :                dFermi_dlaplace_rho = -Fermi**2/alpha/N*(e_laplace_rho_br/e_0_lda)*EXP((Fx - mu)/N)
     398              : 
     399              :                e_rho(ip) = e_rho(ip) + (Fermi*e_rho_pbe + dFermi_drho*e_0_pbe + &
     400      3264000 :                                         (1.0_dp - Fermi)*e_rho_br - dFermi_drho*e_0_br)*sx
     401              : 
     402              :                e_ndrho(ip) = e_ndrho(ip) + (Fermi*e_ndrho_pbe + dFermi_dndrho*e_0_pbe + &
     403      3264000 :                                             (1.0_dp - Fermi)*e_ndrho_br - dFermi_dndrho*e_0_br)*sx
     404              : 
     405              :                e_tau(ip) = e_tau(ip) + (dFermi_dtau*e_0_pbe + &
     406      3264000 :                                         (1.0_dp - Fermi)*e_tau_br - dFermi_dtau*e_0_br)*sx
     407              : 
     408              :                e_laplace_rho(ip) = e_laplace_rho(ip) + (dFermi_dlaplace_rho*e_0_pbe + &
     409      3264000 :                                                         (1.0_dp - Fermi)*e_laplace_rho_br - dFermi_dlaplace_rho*e_0_br)*sx
     410              :             END IF
     411              : 
     412              :          END IF
     413              :       END DO
     414              : 
     415              : !$OMP     END DO
     416              : 
     417          200 :    END SUBROUTINE xbr_pbe_lda_hole_tc_lr_lda_calc
     418              : 
     419              : ! **************************************************************************************************
     420              : !> \brief Intermediate routine that gets grids, derivatives and some params
     421              : !> \param rho_set the density where you want to evaluate the functional
     422              : !> \param deriv_set place where to store the functional derivatives (they are
     423              : !>        added to the derivatives)
     424              : !> \param grad_deriv maximum degree of the derivative that should be evaluated
     425              : !> \param params parameters for functional
     426              : !> \author mguidon (01.2009)
     427              : ! **************************************************************************************************
     428          290 :    SUBROUTINE xbr_pbe_lda_hole_tc_lr_lsd_eval(rho_set, deriv_set, grad_deriv, params)
     429              :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set
     430              :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
     431              :       INTEGER, INTENT(in)                                :: grad_deriv
     432              :       TYPE(section_vals_type), POINTER                   :: params
     433              : 
     434              :       CHARACTER(len=*), PARAMETER :: routineN = 'xbr_pbe_lda_hole_tc_lr_lsd_eval'
     435              : 
     436              :       INTEGER                                            :: handle, npoints
     437              :       INTEGER, DIMENSION(2, 3)                           :: bo
     438              :       REAL(dp)                                           :: gamma, R, sx
     439              :       REAL(kind=dp)                                      :: epsilon_rho
     440           58 :       REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: dummy, e_0, e_laplace_rhoa, &
     441           58 :          e_laplace_rhob, e_ndrhoa, e_ndrhob, e_rhoa, e_rhob, e_tau_a, e_tau_b, laplace_rhoa, &
     442           58 :          laplace_rhob, norm_drhoa, norm_drhob, rhoa, rhob, tau_a, tau_b
     443              :       TYPE(xc_derivative_type), POINTER                  :: deriv
     444              : 
     445           58 :       CALL timeset(routineN, handle)
     446              : 
     447              :       CALL xc_rho_set_get(rho_set, rhoa=rhoa, rhob=rhob, norm_drhoa=norm_drhoa, &
     448              :                           norm_drhob=norm_drhob, tau_a=tau_a, tau_b=tau_b, laplace_rhoa=laplace_rhoa, &
     449              :                           laplace_rhob=laplace_rhob, local_bounds=bo, &
     450           58 :                           rho_cutoff=epsilon_rho)
     451           58 :       npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
     452              : 
     453           58 :       dummy => rhoa
     454              : 
     455           58 :       e_0 => dummy
     456           58 :       e_rhoa => dummy
     457           58 :       e_rhob => dummy
     458           58 :       e_ndrhoa => dummy
     459           58 :       e_ndrhob => dummy
     460           58 :       e_tau_a => dummy
     461           58 :       e_tau_b => dummy
     462           58 :       e_laplace_rhoa => dummy
     463           58 :       e_laplace_rhob => dummy
     464              : 
     465              :       deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
     466           58 :                                       allocate_deriv=.TRUE.)
     467           58 :       CALL xc_derivative_get(deriv, deriv_data=e_0)
     468           58 :       IF (grad_deriv >= 1) THEN
     469              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_rhoa], &
     470           30 :                                          allocate_deriv=.TRUE.)
     471           30 :          CALL xc_derivative_get(deriv, deriv_data=e_rhoa)
     472              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_rhob], &
     473           30 :                                          allocate_deriv=.TRUE.)
     474           30 :          CALL xc_derivative_get(deriv, deriv_data=e_rhob)
     475              : 
     476              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa], &
     477           30 :                                          allocate_deriv=.TRUE.)
     478           30 :          CALL xc_derivative_get(deriv, deriv_data=e_ndrhoa)
     479              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob], &
     480           30 :                                          allocate_deriv=.TRUE.)
     481           30 :          CALL xc_derivative_get(deriv, deriv_data=e_ndrhob)
     482              : 
     483              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_a], &
     484           30 :                                          allocate_deriv=.TRUE.)
     485           30 :          CALL xc_derivative_get(deriv, deriv_data=e_tau_a)
     486              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_tau_b], &
     487           30 :                                          allocate_deriv=.TRUE.)
     488           30 :          CALL xc_derivative_get(deriv, deriv_data=e_tau_b)
     489              : 
     490              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa], &
     491           30 :                                          allocate_deriv=.TRUE.)
     492           30 :          CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhoa)
     493              :          deriv => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob], &
     494           30 :                                          allocate_deriv=.TRUE.)
     495           30 :          CALL xc_derivative_get(deriv, deriv_data=e_laplace_rhob)
     496              :       END IF
     497           58 :       IF (grad_deriv > 1) THEN
     498            0 :          CPABORT("derivatives bigger than 1 not implemented")
     499              :       END IF
     500              : 
     501           58 :       CALL section_vals_val_get(params, "scale_x", r_val=sx)
     502           58 :       CALL section_vals_val_get(params, "CUTOFF_RADIUS", r_val=R)
     503           58 :       CALL section_vals_val_get(params, "GAMMA", r_val=gamma)
     504              : 
     505           58 :       IF (R == 0.0_dp) THEN
     506            0 :          CPABORT("Cutoff_Radius 0.0 not implemented")
     507              :       END IF
     508              : 
     509              : !$OMP     PARALLEL DEFAULT(NONE) &
     510              : !$OMP              SHARED(rhoa, norm_drhoa, laplace_rhoa, tau_a, e_0) &
     511              : !$OMP              SHARED(e_rhoa, e_ndrhoa, e_tau_a, e_laplace_rhoa) &
     512              : !$OMP              SHARED(grad_deriv, npoints, epsilon_rho) &
     513              : !$OMP              SHARED(sx, r, gamma) &
     514              : !$OMP              SHARED(rhob, norm_drhob, laplace_rhob, tau_b, e_rhob) &
     515           58 : !$OMP              SHARED(e_ndrhob, e_tau_b, e_laplace_rhob)
     516              : 
     517              :       CALL xbr_pbe_lda_hole_tc_lr_lsd_calc(rho=rhoa, norm_drho=norm_drhoa, &
     518              :                                            laplace_rho=laplace_rhoa, tau=tau_a, e_0=e_0, e_rho=e_rhoa, e_ndrho=e_ndrhoa, &
     519              :                                            e_tau=e_tau_a, e_laplace_rho=e_laplace_rhoa, grad_deriv=grad_deriv, &
     520              :                                            npoints=npoints, epsilon_rho=epsilon_rho, &
     521              :                                            sx=sx, R=R, gamma=gamma)
     522              : 
     523              :       CALL xbr_pbe_lda_hole_tc_lr_lsd_calc(rho=rhob, norm_drho=norm_drhob, &
     524              :                                            laplace_rho=laplace_rhob, tau=tau_b, e_0=e_0, e_rho=e_rhob, e_ndrho=e_ndrhob, &
     525              :                                            e_tau=e_tau_b, e_laplace_rho=e_laplace_rhob, grad_deriv=grad_deriv, &
     526              :                                            npoints=npoints, epsilon_rho=epsilon_rho, &
     527              :                                            sx=sx, R=R, gamma=gamma)
     528              : 
     529              : !$OMP     END PARALLEL
     530              : 
     531           58 :       CALL timestop(handle)
     532           58 :    END SUBROUTINE xbr_pbe_lda_hole_tc_lr_lsd_eval
     533              : ! **************************************************************************************************
     534              : !> \brief Low level routine that calls the three involved holes and puts them
     535              : !>        together
     536              : !> \param rho values on the grid
     537              : !> \param norm_drho values on the grid
     538              : !> \param laplace_rho values on the grid
     539              : !> \param tau values on the grid
     540              : !> \param e_0 derivatives on the grid
     541              : !> \param e_rho derivatives on the grid
     542              : !> \param e_ndrho derivatives on the grid
     543              : !> \param e_tau derivatives on the grid
     544              : !> \param e_laplace_rho derivatives on the grid
     545              : !> \param grad_deriv maximum degree of the derivative that should be evaluated
     546              : !> \param npoints number of gridpoints
     547              : !> \param epsilon_rho cutoffs
     548              : !> \param sx parameters for  functional
     549              : !> \param R parameters for  functional
     550              : !> \param gamma parameters for  functional
     551              : !> \author mguidon (01.2009)
     552              : ! **************************************************************************************************
     553          116 :    SUBROUTINE xbr_pbe_lda_hole_tc_lr_lsd_calc(rho, norm_drho, laplace_rho, tau, e_0, e_rho, &
     554          116 :                                               e_ndrho, e_tau, e_laplace_rho, grad_deriv, npoints, &
     555              :                                               epsilon_rho, sx, R, gamma)
     556              : 
     557              :       INTEGER, INTENT(in)                                :: npoints, grad_deriv
     558              :       REAL(kind=dp), DIMENSION(1:npoints), INTENT(inout) :: e_laplace_rho, e_tau, e_ndrho, e_rho, e_0
     559              :       REAL(kind=dp), DIMENSION(1:npoints), INTENT(in)    :: tau, laplace_rho, norm_drho, rho
     560              :       REAL(kind=dp), INTENT(in)                          :: epsilon_rho, sx, R, gamma
     561              : 
     562              :       INTEGER                                            :: ip
     563              :       REAL(dp) :: dFermi_dlaplace_rho, dFermi_dndrho, dFermi_drho, dFermi_dtau, e_0_br, e_0_lda, &
     564              :          e_0_pbe, e_laplace_rho_br, e_ndrho_br, e_ndrho_pbe, e_rho_br, e_rho_lda, e_rho_pbe, &
     565              :          e_tau_br, Fermi, Fx, my_laplace_rho, my_ndrho, my_rho, my_tau, ss, ss2, sscale, t1, t15, &
     566              :          t16, t2, t3, t4, t5, t6, t7, t8, t9, yval
     567              : 
     568              : !$OMP     DO
     569              : 
     570              :       DO ip = 1, npoints
     571      5285250 :          my_rho = MAX(rho(ip), 0.0_dp)
     572      5285250 :          IF (my_rho > epsilon_rho) THEN
     573      5285248 :             my_ndrho = MAX(norm_drho(ip), EPSILON(0.0_dp)*1.e4_dp)
     574      5285248 :             my_tau = 1.0_dp*MAX(EPSILON(0.0_dp)*1.e4_dp, tau(ip))
     575      5285248 :             my_laplace_rho = 1.0_dp*laplace_rho(ip)
     576              : 
     577      5285248 :             t1 = pi**(0.1e1_dp/0.3e1_dp)
     578      5285248 :             t2 = t1**2
     579      5285248 :             t3 = my_rho**(0.1e1_dp/0.3e1_dp)
     580      5285248 :             t4 = t3**2
     581      5285248 :             t5 = t4*my_rho
     582      5285248 :             t8 = my_ndrho**2
     583      5285248 :             t9 = 0.1e1_dp/my_rho
     584      5285248 :             t15 = my_laplace_rho/0.6e1_dp - gamma*(2.0_dp*my_tau - t8*t9/0.4e1_dp)/0.3e1_dp
     585      5285248 :             t16 = 0.1e1_dp/t15
     586      5285248 :             yval = 0.2e1_dp/0.3e1_dp*t2*t5*t16
     587              : 
     588      5285248 :             e_0_br = 0.0_dp
     589      5285248 :             e_rho_br = 0.0_dp
     590      5285248 :             e_ndrho_br = 0.0_dp
     591      5285248 :             e_tau_br = 0.0_dp
     592      5285248 :             e_laplace_rho_br = 0.0_dp
     593              : 
     594      5285248 :             IF (R == 0.0_dp) THEN
     595            0 :                IF (yval <= 0.0_dp) THEN
     596              :                   CALL x_br_lsd_y_lte_0(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
     597              :                                         e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
     598            0 :                                         sx, gamma, grad_deriv)
     599              :                ELSE
     600              :                   CALL x_br_lsd_y_gt_0(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
     601              :                                        e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
     602            0 :                                        sx, gamma, grad_deriv)
     603              :                END IF
     604              :             ELSE
     605      5285248 :                IF (yval <= 0.0_dp) THEN
     606              :                   CALL x_br_lsd_y_lte_0_cutoff(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
     607              :                                                e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
     608       115013 :                                                sx, R, gamma, grad_deriv)
     609              :                ELSE
     610              :                   CALL x_br_lsd_y_gt_0_cutoff(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
     611              :                                               e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
     612      5170235 :                                               sx, R, gamma, grad_deriv)
     613              :                END IF
     614              :             END IF
     615              : 
     616              :             ! ** Now we calculate the pbe cutoff part
     617              :             ! ** Attention we need to scale rho, ndrho first
     618      5285248 :             my_rho = my_rho*2.0_dp
     619      5285248 :             my_ndrho = my_ndrho*2.0_dp
     620              : 
     621              :             ! ** Do some precalculation in order to catch the correct branch afterwards
     622      5285248 :             sscale = 1.0_dp
     623      5285248 :             t1 = pi**2
     624      5285248 :             t2 = t1*my_rho
     625      5285248 :             t3 = t2**(0.1e1_dp/0.3e1_dp)
     626      5285248 :             t4 = 0.1e1_dp/t3
     627      5285248 :             t6 = my_ndrho*t4
     628      5285248 :             t7 = 0.1e1_dp/my_rho
     629      5285248 :             t8 = t7*sscale
     630      5285248 :             ss = 0.3466806371753173524216762e0_dp*t6*t8
     631      5285248 :             IF (ss > scutoff) THEN
     632      1684625 :                ss2 = ss*ss
     633      1684625 :                sscale = (smax*ss2 - sconst)/(ss2*ss)
     634              :             END IF
     635      5285248 :             e_0_pbe = 0.0_dp
     636      5285248 :             e_rho_pbe = 0.0_dp
     637      5285248 :             e_ndrho_pbe = 0.0_dp
     638      5285248 :             IF (ss*sscale > gcutoff) THEN
     639              :                CALL xpbe_hole_t_c_lr_lda_calc_1(e_0_pbe, e_rho_pbe, e_ndrho_pbe, &
     640              :                                                 my_rho, &
     641      5285085 :                                                 my_ndrho, sscale, sx, R, grad_deriv)
     642              :             ELSE
     643              :                CALL xpbe_hole_t_c_lr_lda_calc_2(e_0_pbe, e_rho_pbe, e_ndrho_pbe, &
     644              :                                                 my_rho, &
     645          163 :                                                 my_ndrho, sscale, sx, R, grad_deriv)
     646              :             END IF
     647              : 
     648      5285248 :             e_0_pbe = 0.5_dp*e_0_pbe
     649              : 
     650              :             ! ** Finally we get the LDA part
     651              : 
     652      5285248 :             e_0_lda = 0.0_dp
     653      5285248 :             e_rho_lda = 0.0_dp
     654              :             CALL xlda_hole_t_c_lr_lda_calc_0(grad_deriv, my_rho, e_0_lda, e_rho_lda, &
     655      5285248 :                                              sx, R)
     656      5285248 :             e_0_lda = 0.5_dp*e_0_lda
     657              : 
     658      5285248 :             Fx = e_0_br/e_0_lda
     659              : 
     660      5285248 :             Fermi = alpha/(EXP((Fx - mu)/N) + 1.0_dp)
     661              : 
     662      5285248 :             e_0(ip) = e_0(ip) + (Fermi*e_0_pbe + (1.0_dp - Fermi)*e_0_br)*sx
     663              : 
     664      5285248 :             IF (grad_deriv >= 1) THEN
     665              : 
     666      2733750 :                dFermi_drho = -Fermi**2/alpha/N*(e_rho_br/e_0_lda - e_0_br*e_rho_lda/e_0_lda**2)*EXP((Fx - mu)/N)
     667      2733750 :                dFermi_dndrho = -Fermi**2/alpha/N*(e_ndrho_br/e_0_lda)*EXP((Fx - mu)/N)
     668      2733750 :                dFermi_dtau = -Fermi**2/alpha/N*(e_tau_br/e_0_lda)*EXP((Fx - mu)/N)
     669      2733750 :                dFermi_dlaplace_rho = -Fermi**2/alpha/N*(e_laplace_rho_br/e_0_lda)*EXP((Fx - mu)/N)
     670              : 
     671              :                e_rho(ip) = e_rho(ip) + (Fermi*e_rho_pbe + dFermi_drho*e_0_pbe + &
     672      2733750 :                                         (1.0_dp - Fermi)*e_rho_br - dFermi_drho*e_0_br)*sx
     673              : 
     674              :                e_ndrho(ip) = e_ndrho(ip) + (Fermi*e_ndrho_pbe + dFermi_dndrho*e_0_pbe + &
     675      2733750 :                                             (1.0_dp - Fermi)*e_ndrho_br - dFermi_dndrho*e_0_br)*sx
     676              : 
     677              :                e_tau(ip) = e_tau(ip) + (dFermi_dtau*e_0_pbe + &
     678      2733750 :                                         (1.0_dp - Fermi)*e_tau_br - dFermi_dtau*e_0_br)*sx
     679              : 
     680              :                e_laplace_rho(ip) = e_laplace_rho(ip) + (dFermi_dlaplace_rho*e_0_pbe + &
     681      2733750 :                                                         (1.0_dp - Fermi)*e_laplace_rho_br - dFermi_dlaplace_rho*e_0_br)*sx
     682              :             END IF
     683              : 
     684              :          END IF
     685              :       END DO
     686              : 
     687              : !$OMP     END DO
     688              : 
     689          116 :    END SUBROUTINE xbr_pbe_lda_hole_tc_lr_lsd_calc
     690              : 
     691              : END MODULE xc_xbr_pbe_lda_hole_t_c_lr
        

Generated by: LCOV version 2.0-1